2016-07-05 117 views
5

使用Google测试,我想指定一个Test fixture以用于不同的测试用例。 夹具应分配和取消分配类TheClass及其数据管理类TheClassData的对象,其中数据管理类需要数据文件的名称。
对于不同的测试,文件名应该有所不同。指定Google测试的构造函数参数Fixture

我定义了如下夹具:

class TheClassTest : public ::testing::Test { 
protected: 
    TheClassTest(std::string filename) : datafile(filename) {} 
    virtual ~TheClassTest() {} 
    virtual void SetUp() { 
    data = new TheClassData(datafile); 
    tc = new TheClass(data); 
    } 
    virtual void TearDown() { 
    delete tc; 
    delete data; 
    } 

    std::string datafile; 
    TheClassData* data; 
    TheClass* tc; 
}; 

现在,不同的测试应该使用不同的文件名的夹具。 想象一下,设置一个测试环境。

问题:如何从测试中指定文件名,即如何调用夹具的非默认构造函数?

我发现像::testing::TestWithParam<T>TEST_P这样的东西,这没有帮助,因为我不想运行一个测试不同的值,但使用一个灯具进行不同的测试。

+0

所以你想自己运行该夹具?谷歌测试默认测试运行器不能实例化具有参数的灯具。 –

+0

我想使用灯具运行测试(可能是'TEST_F')。所以答案是,这是不可能的?谢谢。 – Gregor

+0

我认为'TestWithParam '和'TEST_P'正是你所需要的。查找[高级文档](https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md)如何在实践中使用它们。您可以随时在测试用例中实例化待测试的实例(我假设它是TheClass)。 –

回答

3

正如其他用户所建议的那样,通过使用非默认构造函数实例化灯具,您无法实现想要的效果。但是, 还有其他方法。只需在测试中明确重载SetUp功能和 调用该版本:

class TheClassTest : public ::testing::Test { 
protected: 
    TheClassTest() {} 
    virtual ~TheClassTest() {} 
    void SetUp(const std::string &filename) { 
     data = new TheClassData(filename); 
     tc = new TheClass(data); 
    } 
    virtual void TearDown() { 
     delete tc; 
     delete data; 
    } 

    TheClassData* data; 
    TheClass* tc; 
}; 

现在在测试纯粹使用此重载设置文件名:

TEST_F(TheClassTest, MyTestCaseName) 
{ 
    SetUp("my_filename_for_this_test_case"); 

    ... 
} 

的参TearDown会自动清理时 测试完成。

+0

太好了。非常感谢! – Gregor

+0

SetUp方法仍将由gtest调用,导致两次调用SetUp ...因此在这种情况下存在内存泄漏,因为TearDown只会删除最后的分配。我会将SetUp重命名为其他名称,以便gtest不会调用它。 – Andreas

+0

对不起,我错了。由于你的'Setup'带有一个参数,它不会被gtest调用。我会重命名'SetUp',因为它可能会被gtest调用的'SetUp()'混淆。 – Andreas

0

使用当前类的基类的灯具:

class TheClassTestBase : public ::testing::Test { 
protected: 
    TheClassTestBase(std::string filename) : datafile(filename) {} 
    ... 
}; 

对于每一个特定的文件名 - 可使用衍生夹具:

class TheClassTestForFooTxt : public TheClassTestBase { 
protected: 
    TheClassTestForFooTxt() : TheClassTestBase ("foo.txt") {} 
}; 

然而,这是额外的步骤需要为每个组参数 - 所以你可以尝试使用模板或宏来以较少的努力完成它。像:

template <typename ClassTestTag> 
struct ClassTestParams 
{ 
    static std::string filename; 
}; 

template<typename ClassTestTag> 
class TheClassTest : public TheClassTestBase { 
protected: 
    TheClassTest() : TheClassTestBase (ClassTestParams<ClassTestTag>::filename) {} 
}; 

然后 - 对于每个组参数 - 这样做:

class FooTxtTag {}; 
template <> std::string ClassTestParams<FooTxtTag>::value = "foo.txt"; 
using TheClassTestForFooTxt = TheClassTest<FooTxtTag>; 
TEST_F(TheClassTestForFooTxt, xxxx) {} 

但是 - 在您的具体情况 - 我也想尝试GoogleTest:type-parameterized-tests

+0

谢谢。我认为这对我的问题的规模来说过于费力。 – Gregor