简体   繁体   中英

How can i decorate Google Test fixture

I have some test:

class Somefixture: ::testing::Test{};
class Somefixture2: ::testing::Test{};

TEST_F(SomeFixture, SomeName)
{
// ...
}

How can i automatically link test to both fixtures (decorate)?

TEST_F2(SomeFixture, SomeFixture2, SomeName){}

While the required result will be as if I wrote:

TEST_F(SomeFixture, SomeName)
{
// ...
}
TEST_F(SomeFixture2, SomeName)
{
// ...
}

Without the unnecessary code duplication

With one little exception (two tests can't have the same name), this should go in the right derection:

#define TEST_F2(F1, F2, Name)                                  \
template <struct Fixture> struct MyTester##Name : Fixture {    \
  void test##Name();                                           \
};                                                             \
                                                               \
TEST_F(MyTester##Name<F1>, Name##1){ test##Name(); }           \
TEST_F(MyTester##Name<F2>, Name##2){ test##Name(); }           \
                                                               \
template <struct Fixture> void MyTester##Name::test##Name()

This will call two tests, each using MyTester as fixture that inherits from one of the two fixtures. Since do_test is a member of MyTester, it has access to all inherited members from the fixtures. The test framework will create an MyTester object for each test and the corresponding actual fixture will get created as base class object. To avoid naming conflicts with other tests or bewteen different calls of TEST_F2, I appended the Name to the template name and test method name. The TEST_F macro calls are supplied with a name and an index. I did not test it, since I don't have Google Test, but the mechanisms in many of those testing frameworks work similar.

How can i automatically link test to both fixtures (decorate)?

By adding a common base class :

class CommonFixture
{
  public:
    // add member variables and initialize them in the constructor
};
class Somefixture1 : ::testing::Test, protected CommonFixture{}
class Somefixture2 : ::testing::Test, protected CommonFixture{}

Tests stay the same :

TEST_F(SomeFixture1, SomeName)
{
// ...
}
TEST_F(SomeFixture2, SomeName)
{
// ...
}

Now you got a common fixture for Somefixture1 and Somefixture2. You can access these common objects from within your tests.

You can go with BЈовић approach which seems good.
Or anther approach which required a small change to the test itself can be having a "super" class which will have both instances as members.

class superFuxture
{
public:
    Somefixture1 f1;
    Somefixture2 f2;
}

Then you test will be like that:

TEST_F(superFuxture, SomeName)
{
    //when you were accessing a member of Somefixture1 you'll now need to do:
    //f1.SomeFixture1Member
}

Google Test has two ways of executing the same test body in different contexts: value-parameterized tests or typed/type-parameterized tests . Not precisely what you want but it's the closest thing it offers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM