26

I have a test fixture class which is currently used by many tests.

#include <gtest/gtest.h>
class MyFixtureTest : public ::testing::Test {
  void SetUp() { ... }
};

I would like to create a parameterized test which also uses all that MyFixtureTest has to offer, without needing to change all my existing tests.

How do I do that?

I have found similar discussions on the web, but have not fully understood their answers.

des4maisons
  • 1,791
  • 4
  • 20
  • 23

3 Answers3

54

This question is now answered in the Google Test documentation (the answer from VladLosev is technically correct, but perhaps slightly more work)

Specifically, when you want to add parameters to a pre-existing fixture class, you can do

class MyFixtureTest : public ::testing::Test {
  ...
};
class MyParamFixtureTest : public MyFixtureTest,
                           public ::testing::WithParamInterface<MyParameterType> {
  ...
};

TEST_P(MyParamFixtureTest, MyTestName) { ... }
mabraham
  • 2,806
  • 3
  • 28
  • 25
  • 5
    This definitely seems cleaner and less work compared to what VladLosev proposed (which is technically correct and perhaps from a time when the ParamInterface was not available) – sanchitarora Jan 09 '15 at 20:41
  • Don't forget that if you define `SetUp()` in `MyParamFixtureTest` it should call `MyFixtureTest::SetUp()`, otherwise that setup of the base class will never run. – DBedrenko Jan 02 '18 at 15:45
  • How do I instantiate `MyParamFixtureTest` with the right parameter of type `MyParameterType` ? – liv2hak Sep 13 '19 at 03:41
25

The problem is that for regular tests your fixture has to be derived from testing::Test and for parameterized tests, it has to be derived from testing::TestWithParam<>.

In order to accommodate that, you'll have to modify your fixture class in order to work with your parameter type

template <class T> class MyFixtureBase : public T {
  void SetUp() { ... };
  // Put the rest of your original MyFixtureTest here.
};

// This will work with your non-parameterized tests.
class MyFixtureTest : public MyFixtureBase<testing::Test> {};

// This will be the fixture for all your parameterized tests.
// Just substitute the actual type of your parameters for MyParameterType.
class MyParamFixtureTest : public MyFixtureBase<
    testing::TestWithParam<MyParameterType> > {};

This way you can keep all your existing tests intact while creating parameterized tests using

TEST_P(MyParamFixtureTest, MyTestName) { ... }
VladLosev
  • 7,296
  • 2
  • 35
  • 46
0

If you create a new fixture that is derived from this common one and than create your parameterized tests on that derived class - would that help you and solve your problem?

From Google Test wiki page:

In Google Test, you share a fixture among test cases by putting the shared logic in a base test fixture, then deriving from that base a separate fixture for each test case that wants to use this common logic.

user4581301
  • 33,082
  • 7
  • 33
  • 54
ratkok
  • 739
  • 9
  • 15
  • Thanks for the answer. My issue is that a parameterized test fixture needs to inherit from ::testing::TestWithParam, whereas my current fixture only inherits from ::testing::Test. Also, tests which use parameterized tests are declared with TEST_P instead of TEST_F. Any ideas how to resolve the differences? – des4maisons Jul 14 '10 at 19:34