GoogleTest:尝试获取带有测试的抽象基类,然后使用派生类定义多个测试方案

Lee*_*eeC 5 googletest

为了对某些代码进行BDD样式测试,我有一组要在多种情况下执行的测试。我已经在C#中使用NUnit&NSubstitute完成了很多次,但是我正在努力通过GoogleTest实现C ++代码的预期结果。

我想做什么的概念-但由于BaseTest中的纯虚方法,甚至无法编译为:

class BaseTest : public ::testing::Test {
protected:
    int expected = 0;
    int actual = 0;

    virtual void SetUp() {  printf("BaseTest SetUp()\r\n"); }
    virtual void TearDown() {  printf("BaseTest TearDown()\r\n"); }
    virtual void PureVirtual() = 0;
};

TEST_F(BaseTest, BaseTest1)
{
    printf("BaseTest BaseTest1\r\n");
    ASSERT_EQ(expected, actual);
}

class ScenarioOne: public BaseTest {
public:
    virtual void SetUp()
    {
        BaseTest::SetUp();
        printf("ScenarioOne SetUp()\r\n"); 
        actual = 20;
        expected = 20;
    }

    virtual void PureVirtual() {}
};

class ScenarioTwo: public BaseTest {
public:
    virtual void SetUp()
    {
        BaseTest::SetUp();
        printf("ScenarioTwo SetUp()\r\n"); 
        actual = 98;
        expected = 98;
    }

    virtual void PureVirtual() {}
};
Run Code Online (Sandbox Code Playgroud)

上面的代码已大大简化,BaseTest类将定义30多个测试,而Scenario类将具有广泛而复杂的输入数据以执行正在测试的代码,并且预期结果将是相当可观的并且是不重要的-因此in派生类SetUp()方法,定义输入数据和预期结果,并使用输入数据刺激被测代码。然后,基类中的测试将针对预期结果测试各种实际结果,并在适当情况下通过/失败。

我已经考虑过尝试使用参数化测试,但是由于输入数据和预期结果的复杂性,这看起来很困难,此外,对于每个新的测试场景,我认为这意味着要修改每个测试以提供输入数据和预期结果,一个附加参数。

就像我之前说的,我可以在C#中轻松完成这种事情,但是不幸的是,目前我正在从事C ++项目。我想用GoogleTest做些什么吗?

Lee*_*eeC 4

好的 - 我刚刚想到了一个可能的解决方案。

将所有测试放在一个头文件中,如下所示:

// Tests.h - Tests to be performed for all test scenarios
TEST_F(SCENARIO_NAME, test1)
{
    ASSERT_EQ(expected, actual);
}
Run Code Online (Sandbox Code Playgroud)

BaseTest 类只具有基本的 SetUp()/TearDown() 方法、用于保存预期结果和实际结果的成员变量以及派生场景类的任何辅助函数 - 但没有测试,因此如果需要,可以是抽象的。

然后对于每个场景:

class ScenarioOne: public BaseTest 
{
public:
    virtual void SetUp()
    {
        BaseTest::SetUp();
        printf("ScenarioOne SetUp()\r\n"); 
        actual = 20;
        expected = 20;
    }
};

#define SCENARIO_NAME ScenarioOne
#include "Tests.h"
Run Code Online (Sandbox Code Playgroud)

最终效果是一组定义一次的测试,然后可以应用于多个测试场景。

这看起来确实有点作弊,所以我很感兴趣是否有人有更好的方法。