在 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 类型)
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
成员函数将有更多涉及的语法。
我有一些重复测试,其中测试的输入需要以非重复的方式唯一地创建。想象一下这样的 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 类型)
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
成员函数将有更多涉及的语法。