I see in the Value-Parameterized Test documentation that using the same test case (fixture class) results in executing all the test vectors from every
INSTANTIATE_TEST_CASE_P statement.
Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests in the given test case, whether their definitions come before or after the INSTANTIATE_TEST_CASE_P statement. I also see that some sort of notification of this behavior is listed as an enhancement:
http://code.google.com/p/googletest/issues/detail?id=65I found this behavior non intuitive as the above enhancement suggests. I guess I don't have enough experience with Google Test to know why this behavior is useful. I know that I can combat this by putting all my common code into a base class and then make lots of subclasses, one for each test, thus making my vectors unique for each test but providing the same SetUp/TearDown via inheritance. e.g. This is useful if your interface constantly changes however, since the templates don't work with multiple inheritance (Why? - templates hurt my brain =P).
class FooTestFixture: public ::testing::Test
{
public:
static void SetUpTestCase() ...
static void TearDownTestCase() ...
protected:
virtual void SetUp() ...
virtual void TearDown() ...
....
};
...
class FooTest1 :
public FooTestFixture,
public ::testing::WithParamInterface<std::tuple<bool, int, int>>
{};
TEST_P(FooTest1, Test1)
INSTANTIATE_TEST_CASE_P(ParameterizedTest1, FooTest1,
::testing::Combine(
::testing::Bool(),
::testing::Range(1,10)));
Lather, rinse, repeat..
That seems like a lot of clerical text to do something that seems to be the way most would think it was going to behave anyhow. Playing around in the debugger I noted that a simple change can make it a one to one or one to many relationship by simply having the RegisterTests() method in
gtest-param-util.h search for
test_name == prefix. If equal then it's a one to one for this test.
# define TEST_P(test_case_name, test_name)
# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
To orchestrate the specific test with the instantiation as such. (excuse the code, it could be cleaner but it was just a proof of concept and hastily tested).
// UnitTest class invokes this method to register tests in this test case
// test cases right before running tests in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more then once.
virtual void RegisterTests() {
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it)
{
linked_ptr<TestInfo> test_info = *test_it;
typename InstantiationContainer::iterator gen_it = instantiations_.begin();
for ( ; gen_it != instantiations_.end(); ++gen_it)
{
if(gen_it->first == test_info->test_base_name)
{
break;
}
}
if(gen_it != instantiations_.end())
{
RegisterNow(test_it, gen_it);
}
else
{
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end();
++gen_it) {
RegisterNow(test_it, gen_it);
}
}
}
}
void RegisterNow(typename TestInfoContainer::iterator test_it,
typename InstantiationContainer::iterator gen_it) {
linked_ptr<TestInfo> test_info = *test_it;
const string& instantiation_name = gen_it->first;
ParamGenerator<ParamType> generator((*gen_it->second)());
string test_case_name;
if ( !instantiation_name.empty() )
test_case_name = instantiation_name + "/";
test_case_name += test_info->test_case_base_name;
int i = 0;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
Message test_name_stream;
test_name_stream << test_info->test_base_name << "/" << i;
MakeAndRegisterTestInfo(
test_case_name.c_str(),
test_name_stream.GetString().c_str(),
NULL, // No type parameter.
PrintToString(*param_it).c_str(),
GetTestCaseTypeId(),
TestCase::SetUpTestCase,
TestCase::TearDownTestCase,
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
I also noted that I don't see any tests for the Value-Parameterized Tests included in the code base??
Cheers,
Bryan