指定Google测试夹具的构造函数参数

Gre*_*gor 10 c++ constructor unit-testing googletest

通过Google测试,我想指定一个测试夹具,用于不同的测试用例.fixture必须分配和释放类TheClass及其数据管理类的对象TheClassData,其中数据管理类需要数据文件的名称.
对于不同的测试,文件名应该有所不同.

我定义了以下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;
};
Run Code Online (Sandbox Code Playgroud)

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

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

我发现喜欢的东西::testing::TestWithParam<T>TEST_P,这没有帮助,因为我不希望运行具有不同值的一个测试,但不同的测试用一个夹具.

Mar*_*vic 7

正如另一个用户所建议的那样,通过使用非默认构造函数实例化fixture,无法实现所需.但是,还有其他方法.只需重载该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;
};
Run Code Online (Sandbox Code Playgroud)

现在在测试中只需使用此重载来设置文件名:

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

TearDown测试完成后,无参数将自动清理.

  • 对不起,我错了。由于您的“设置”带有参数,因此gtest不会调用它。我会将SetUp重命名为其他名称,因为它可以与gtest调用的SetUp()混淆。 (3认同)

Pio*_*ycz 7

使用当前类作为您的装置的基类:

class TheClassTestBase : public ::testing::Test {
 protected:
  TheClassTestBase(std::string filename) : datafile(filename) {}
  ...
 };
Run Code Online (Sandbox Code Playgroud)

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

class TheClassTestForFooTxt : public TheClassTestBase {
protected:
    TheClassTestForFooTxt() : TheClassTestBase ("foo.txt") {}
};
Run Code Online (Sandbox Code Playgroud)

然而,这是每组参数都需要的额外步骤 - 因此您可以尝试使用模板或宏来轻松完成。喜欢:

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

template<typename  ClassTestTag>
class TheClassTest : public TheClassTestBase {
protected:
    TheClassTest() : TheClassTestBase (ClassTestParams<ClassTestTag>::filename) {}
};
Run Code Online (Sandbox Code Playgroud)

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

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

但是 - 在您的特定情况下 - 我也会尝试GoogleTest:type-parameterized-tests


mik*_*vis 5

处理这个问题的另一种好方法是扩展您的固定装置,并在扩展类中提供一个新的默认构造函数,该构造函数使用您需要的参数调用旧的构造函数。例如:

struct MySpecializedTestFixture : public GenericTestFixture
{
  MySpecializedTestFixture() : GenericTestFixture("a thing", "another thing") {}
};

TEST_F(MySpecializedTestFixture, FancyTest)
{
  // Use the thing environment and make some assertions.
}
Run Code Online (Sandbox Code Playgroud)