C++ 如何装饰Google测试夹具

C++ 如何装饰Google测试夹具,c++,unit-testing,googletest,C++,Unit Testing,Googletest,我有一些测试: class Somefixture: ::testing::Test{}; class Somefixture2: ::testing::Test{}; TEST_F(SomeFixture, SomeName) { // ... } 如何将测试自动链接到两个装置(装饰) 而要求的结果就好像我写了: TEST_F(SomeFixture, SomeName) { // ... } TEST_F(SomeFixture2, SomeName) { // ... } 没有不必要

我有一些测试:

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

TEST_F(SomeFixture, SomeName)
{
// ...
}
如何将测试自动链接到两个装置(装饰)

而要求的结果就好像我写了:

TEST_F(SomeFixture, SomeName)
{
// ...
}
TEST_F(SomeFixture2, SomeName)
{
// ...
}
没有不必要的代码重复

如何将测试自动链接到两个装置(装饰)

通过添加公共基类:

class CommonFixture
{
  public:
    // add member variables and initialize them in the constructor
};
class Somefixture1 : ::testing::Test, protected CommonFixture{}
class Somefixture2 : ::testing::Test, protected CommonFixture{}
测试保持不变:

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

现在您有了一个适用于Somefixture1和Somefixture2的通用夹具。您可以从测试中访问这些公共对象。

您可以使用
Bццћ
方法,这似乎很好。
或者,另一种需要对测试本身进行微小更改的方法可以是使用一个“超级”类,该类将两个实例都作为成员

class superFuxture
{
public:
    Somefixture1 f1;
    Somefixture2 f2;
}
那么您的测试将是这样的:

TEST_F(superFuxture, SomeName)
{
    //when you were accessing a member of Somefixture1 you'll now need to do:
    //f1.SomeFixture1Member
}
除了一个小例外(两个测试不能有相同的名称),这应该是正确的方向:

#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()
定义测试(F1,F2,名称)\ 模板结构MyTester##名称:Fixture{\ 无效测试##Name()\ }; \ \ TEST#F(MyTester#Name,Name#1){TEST##Name()}\ TEST#F(MyTester#Name,Name#2){TEST##Name()}\ \ 模板无效MyTester##Name::test##Name()
这将调用两个测试,每个测试都使用MyTester作为从两个装置之一继承的装置。因为do_test是MyTester的成员,所以它可以访问fixture中所有继承的成员。测试框架将为每个测试创建一个MyTester对象,相应的实际夹具将被创建为基类对象。为了避免与其他测试发生命名冲突,或者避免在不同的测试调用之间发生冲突,我在模板名称和测试方法名称后面附加了这个名称。TEST_F宏调用提供了名称和索引。我没有测试它,因为我没有Google test,但是许多测试框架中的机制工作原理相似。

Google test有两种方法在不同的上下文中执行相同的测试体:或。不完全是您想要的,但它是它提供的最接近的东西。

我应该如何调用我的测试,使其在单个实例中成为主体,但使用1个和2个fixture调用?我有20个测试。我想用1号和2号的固定装置通过他们。我不想复制粘贴测试代码。@Deeptowncitizen:我不确定我是否得到了你想要的。您是否希望测试使用
someFuxture
运行一次,然后再使用
someFixture2
运行一次?在这种情况下,我之前的答案与此无关,我已对问题进行了编辑,使其更具针对性。我会想办法做到这一点…谢谢,但这是一个有点丑陋的变体(必须是框架)。在单元测试中使用decorator是一种正常的做法。定义“正常做法”-我不知道Google测试中有任何decorator。NUnit中有这样的“decorator”。我认为在java、Python、Ruby中也必须是这样的,但是这是谷歌测试和C++,所以你不能仅仅从其他语言和框架中假设。但是,你可能想看看CppUnit,它是C++的NUnk端口。FWW,谷歌。测试后的宏在测试时看起来和我上面做的非常相似(而且很难看),并且由于缺乏反射和静态类型和其他类型的存在,这是C++单元测试框架中非常正常的做法。
#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()