This week I'm going to learn GoogleTest for c++. Goals for day 4: test code with several data sets. In this case, I'm asking a GPS parser object (object under test) to parse sets of valid and invalid GPS payloads. The object should be able to report if the payload is valid or not (test condition).
The GTest WithParamInterface test fixture class allows that. I can write a single test case, and run that multiple times.
// generic template for NMEA parser unit tests
// base class for all test fixtures, parameterized or not.
template <class T>
class nmeaTest : public testing::Test {
protected:
nmeaTest() {}
T o;
};
// ==================================================================================
// template for parameterised parser tests
// generic fixture that allows to test any nmea parser class' parser function
// with multiple data inputs
template <class T>
class nmeaParsersTest : public nmeaTest<T>, public testing::WithParamInterface<std::tuple<std::string, bool>> {
protected:
nmeaParsersTest() {}
};
The class accepts two parameters each time it's executed:
- a string. In my tests, that will be GPS payload data. Both valid and invalid data.
- a bool: what is the expected result of this test. I'm expecting a true result only for valid payloads. My class under test should report false if the payload is not compliant
note: this test fixture also uses a template. You can ignore that for now. I'll review that in a next post.
Next, we declare the tests that we will do on the object under test:
TEST_P(gllParserTest, gllparsetest) { bool expected = std::get<1>(GetParam()); std::string s = std::get<0>(GetParam()); ASSERT_EQ(expected, o.from_data(s, o)); }
We retrieve the expected outcome and the test payload from the parameters. Then we ask the object under test to execute a parse test with that string, and compare its return value with the expected outcome.
Here is how to call this test with multiple data sets and expectations:
INSTANTIATE_TEST_SUITE_P( parsetest, gllParserTest, ::testing::Values( std::make_tuple("$XXXXXXXX", false), // invalid payload std::make_tuple("", false), // empty payload std::make_tuple("$GPGLL,5051.83778,N,00422.55809,S,185427.150,A,N*4F", true), std::make_tuple("$GPGLL,5051.83778,N,00422.55809,S,185427.150,V,N*4F", true)) );
Test 1 and 2 should check for a false return value, because the payload isn't compliant with the GPS payload definition. Test 3 and 4 have valid payload, and the object under test should return true.
Outcome:
link to all posts.