Value-Parameterized Tests, documentation and code suggestions

3,602 views
Skip to first unread message

bakerhillpins

unread,
Sep 24, 2013, 3:00:02 PM9/24/13
to googletes...@googlegroups.com
So I have just started really using Google Test, specifically using Value-Parameterized Tests. After several hours of frustration where my test instantiations were never executed/run I finally realized that the generator provided in the definition was evaluated before the Test Fixture class was ever evaluated.

# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)

IIRC it is evaluated in the ::testing::InitGoogleTest(&argc, argv); call. Anyhow, I happened to assume that the test fixture class would be the natural place for my initialization of test vectors. Seems simple but it might be worth a note in the Wiki or even a change in the code such that a test with an empty generator set would publish a run-time error or note mentioning that it was skipped and why! Would have saved me a LOT of effort.


Second, After using it a bit I have found that there are several ways for me to combat this and still feel like I have encapsulated the Test Fixture.

Simply including the test vectors as static elements of the Test Fixture Class:

static const int positiveDelays[] = {0, 100, 200, 300, 400, 500, 600};
static const int delays[] = {-300, -200, -100, 0, 100, 200, 300};

class FooTestFixture :
    public ::testing::Test,
    public ::testing::WithParamInterface<std::tuple<bool, int, int>>
{
public:
    static std::vector<int> PositiveDelays;
    static std::vector<int> Delays;
....
}

std::vector<int> FooTestFixture::PositiveDelays( positiveDelays, end(positiveDelays) );
std::vector<int> FooTestFixture::Delays( delays, end(delays) );

And then using them

TEST_P(FooTestFixture, BarTest)
{..}

INSTANTIATE_TEST_CASE_P(ParameterizedBarTest, FooTestFixture
                        ::testing::Combine(
                        ::testing::Bool(),
                        ::testing::ValuesIn(FooTestFixture::PositiveDelays),
                        ::testing::ValuesIn(FooTestFixture::Delays)));



Or I can go so far as including a/set of static initialization methods inside the Test Fixture class that can be called as the generator when needed. So the change to the above would be:

class FooTestFixture :
    public ::testing::Test,
    public ::testing::WithParamInterface<std::tuple<bool, int, int>>
{
public:
....

    static testing::internal::CartesianProductHolder3<
        testing::internal::ParamGenerator<bool>,
        testing::internal::ParamGenerator<int>,
        testing::internal::ParamGenerator<int>> Generate()
    {
        return ::testing::Combine(
            ::testing::Bool(),
            ::testing::ValuesIn(FooTestFixture::PositiveDelays),
            ::testing::ValuesIn(FooTestFixture::Delays));
    }
....
}
...
INSTANTIATE_TEST_CASE_P(ParameterizedBarTest, FooTestFixture, FooTestFixture ::Generate());


I noticed there were a few questions posted to the group in the past concerning linking SetUp()/TearDown() methods and getting that feature added to Value-Parameterized Tests in the Test Fixture Class, for example: https://groups.google.com/forum/#!searchin/googletestframework/parameterized/googletestframework/yUKCppkDock/TczWLHQfursJ This may be a good way for folks to combat this as they could create multiple static methods which are called individually when needed to create the specialized test vectors for each test.


Hope you find this useful.
Bryan

bakerhillpins

unread,
Sep 24, 2013, 3:34:38 PM9/24/13
to googletes...@googlegroups.com
So with regard to the Static methods to do initialization..  this post says that this is the expected implementation method:

https://groups.google.com/d/msg/googletestframework/lkrX7DoOcnM/chlCQGwjJPMJ

However, I didn't find that very clear after reading the documentation several times trying to diagnose the tests not executing, so maybe the above will help some others.

Cheers!
Bryan




Reply all
Reply to author
Forward
0 new messages