I\'d like to write C++ Google tests which can use value-parameterized tests with multiple parameters of different data types, ideally matching the complexity of the followin
An alternative to using a custom structure as the parameter is to use the parameter generator ::testing::Combine(g1, g2, ..., gn)
. This generator allows you to combine the other parameter generators into a set of parameters with a type std::tuple
that has a template type that matches the types of the values provided.
Note that this generator produces the Cartesian product of the values provided. That means that every possible ordered tuple will be created. I believe the original question is asking for a strict array of parameters with the provided values, which this does not support. If you need to have an array of strict parameters, you could use a tuple with the parameter generator ::testing::Values(v1, v2, ..., vN)
where each value is a separate tuple.
Example:
#include <string>
#include <tuple>
class MyTestSuite :
public testing::TestWithParam<std::tuple<std::string, std::string, int>>
{
};
TEST_P(MyTestSuite, TestThatThing)
{
functionUnderTest(std::get<0>(GetParam()),
std::get<1>(GetParam()),
std::get<2>(GetParam()));
. . .
}
INSTANTIATE_TEST_SUITE_P(
MyTestGroup,
MyTestSuite,
::testing::Combine(
::testing::Values("FirstString1", "FirstString2"),
::testing::Values("SecondString1", "SecondString2"),
::testing::Range(10, 13)));
INSTANTIATE_TEST_SUITE_P(
MyOtherTestGroupThatUsesStrictParameters,
MyTestSuite,
::testing::Values(
{"FirstString1", "SecondString1", 10},
{"FirstString2", "SecondString2", 32},
{"FirstString3", "SecondString3", 75}));
In the above example, the parameters created for MyTestGroup
would look like the following:
[
{"FirstString1", "SecondString1", 10},
{"FirstString1", "SecondString1", 11},
{"FirstString1", "SecondString1", 12},
{"FirstString1", "SecondString2", 10},
{"FirstString1", "SecondString2", 11},
{"FirstString1", "SecondString2", 12},
{"FirstString2", "SecondString1", 10},
{"FirstString2", "SecondString1", 11},
{"FirstString2", "SecondString1", 12},
{"FirstString2", "SecondString2", 10},
{"FirstString2", "SecondString2", 11},
{"FirstString2", "SecondString2", 12}
]
Refer to the GoogleTest documentation for further details. (Accessed on 12/17/2019)
Yes, there's a single parameter. You can make that parameter be arbitrarily complex, though. You could adapting the code from the documentation to use you Row
type, for example:
class AndyTest : public ::testing::TestWithParam<Row> {
// You can implement all the usual fixture class members here.
// To access the test parameter, call GetParam() from class
// TestWithParam<T>.
};
Then define your parameterized test:
TEST_P(AndyTest, CountViaDirectSQLCommand)
{
// Call GetParam() here to get the Row values
Row const& p = GetParam();
std::string dbFilePath = testDBFullPath(p.dbname);
{
StAnsi fpath(dbFilePath);
StGdbConnection db(p.fpath);
db.Connect(p.fpath);
int result = db.ExecuteSQLReturningScalar(StAnsi(p.command));
EXPECT_EQ(p.numRecs, result);
}
}
Finally, instantiate it:
INSTANTIATE_TEST_CASE_P(InstantiationName, AndyTest, ::testing::Values(
Row("Empty.mdb", "select count(*) from collar", 0),
Row("SomeCollars.mdb", "select count(*) from collar", 17),
Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4)
));