在 googletest 中使用任意 类 作为参数化测试的参数

Use arbitrary classes as parameter for parametrized tests in googletest

我有一些重复测试,其中测试的输入需要以非重复的方式唯一地创建。想象一下这样的 2 个测试:

struct ComplexInput{};

ComplexInput CreateA();
ComplexInput CreateB();

bool FunctionUnderTest(ComplexInput& input);

TEST(TestCase, TestWithA)
{
    auto input = CreateA();
    auto ret = FunctionUnderTest(input);
    EXPECT_TRUE(ret);
}

TEST(TestCase, TestWithB)
{
    auto input = CreateB();
    auto ret = FunctionUnderTest(input);
    EXPECT_TRUE(ret);
}

有什么方法可以参数化测试以指定应该调用的函数,例如与模板?我能想到的唯一解决方案是使用 enum 来指定数据并使用 returns 基于 enum 类型的正确数据的函数,但这感觉像是 hack:

struct ComplexInput{};

ComplexInput CreateA();
ComplexInput CreateB();

bool FunctionUnderTest(ComplexInput& input);

class enum InputChoice
{
    A, 
    B
};

ComplexInput GetComplexInput(InputChoice c)
{
    switch(c)
    {
        case A:
        return CreateA();
        case B:
        return CreateB();
    }
}

class ParamTest : public ::testing::TestWithParam<InputChoice>{};

TEST_P(ParamTest, Test)
{
    InputChoice c = GetParam();
    auto input = GetComplexInput(c);
    auto ret = FunctionUnderTest(input);
    EXPECT_TRUE(ret);
}

INSTANTIATE_TEST_CASE_P
(
    Tests,
    ParamTest,
    ::testing::Values
    (
        InputChoice::A,
        InputChoice::B
        // maybe this could also be automated?
    )
);

请记住,此代码仅用于演示场景,可能无法编译。

您可以存储函数指针并将它们传递给参数化测试,只要它们具有相同的类型(即相同的参数和 return 类型)

See it online

struct ComplexInput{};

ComplexInput CreateA();
ComplexInput CreateB();

bool FunctionUnderTest(ComplexInput& input);

class ParamTest : public ::testing::TestWithParam<ComplexInput(*)()>{};

TEST_P(TestCase, TestWithA)
{
    auto uutCreator = GetParam();
    auto input = uutCreator();
    auto ret = FunctionUnderTest(input);
    EXPECT_TRUE(ret);
}

INSTANTIATE_TEST_SUITE_P(MyParamTest, ParamTest, 
                         ::testing::Values(CreateA, CreateB));

如果这些函数在现实中没有相同的签名,您需要考虑是否可以使用一些包装器使它们具有相同的签名,或者最好只使用单独的签名 (non-parameterized)测试。

重要说明:这适用于具有空捕获列表、自由函数或 static 成员函数的 lambda。
对于具有 non-empty 捕获列表的 lambda,您必须使用 std::function<ComplexInput()> 而不是 ComplexInput(*)().
static 成员函数将有更多涉及的语法。