如何使用Google Test来运行C++的数据组合

17

我有一个单元测试,需要运行200个可能的数据组合。(生产实现将要测试的数据存储在配置文件中。我知道如何模拟这些值)。我更喜欢不为每个组合编写单独的测试用例,而是通过某种方式循环遍历数据。是否有一种直接的方法可以在 C++ 中使用 Google test 来实现?


为什么不使用结构体数组来保存测试数据,并循环遍历每个条目?您可以只有一个测试用例来测试所有组合。 - Emile Cormier
嗨Emile,谢谢你的建议。当我尝试它时,如果一个组合失败,它会阻止测试用例继续进行并且无法正确报告成功率。最终,对我来说这些是不同的测试用例。 - Karthick S
2个回答

30

您可以使用gtest的参数化测试来实现此功能。

Combine(g1, g2, ..., gN)生成器一起使用似乎是您最好的选择。

下面的示例会填充两个vector,一个包含int,另一个包含string。然后,仅使用单个测试夹具就可以为2个vector中可用值的每个组合创建测试:

#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include "gtest/gtest.h"

std::vector<int> ints;
std::vector<std::string> strings;

class CombinationsTest :
    public ::testing::TestWithParam<std::tuple<int, std::string>> {};

TEST_P(CombinationsTest, Basic) {
  std::cout << "int: "        << std::get<0>(GetParam())
            << "  string: \"" << std::get<1>(GetParam())
            << "\"\n";
}

INSTANTIATE_TEST_CASE_P(AllCombinations,
                        CombinationsTest,
                        ::testing::Combine(::testing::ValuesIn(ints),
                                           ::testing::ValuesIn(strings)));

int main(int argc, char **argv) {
  for (int i = 0; i < 10; ++i) {
    ints.push_back(i * 100);
    strings.push_back(std::string("String ") + static_cast<char>(i + 65));
  }
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

让我试一下,然后回复你。 - Karthick S
5
"INSTANTIATE_TEST_CASE_P已被弃用,请使用"INSTANTIATE_TEST_SUITE_P""。这是从 https://github.com/google/googletest/blob/f16d43cd38e9f2e41357dba8445f9d3a32d4e83d/googletest/include/gtest/internal/gtest-internal.h#L1295 获取的信息。 - hojin

4
使用一个结构体数组(称为Combination),来保存你的测试数据,并循环遍历单个测试中的每个条目。使用EXPECT_EQ而不是ASSERT_EQ来检查每个组合,这样测试不会被中止,你可以继续检查其他组合。
Combination重载运算符<<,以便你可以将它输出到ostream中:
ostream& operator<<(ostream& os, const Combination& combo)
{
    os << "(" << combo.field1 << ", " << combo.field2 << ")";
    return os;
}

为了方便比较两个组合是否相等,重载Combinationoperator==

bool operator==(const Combination& c1, const Combination& c2)
{
    return (c1.field1 == c2.field1) && (c1.field2 == c2.field2);
}

单元测试可能看起来像这样:

TEST(myTestCase, myTestName)
{
    int failureCount = 0;
    for (each index i in expectedComboTable)
    {
        Combination expected = expectedComboTable[i];
        Combination actual = generateCombination(i);
        EXPECT_EQ(expected, actual);
        failureCount += (expected == actual) ? 0 : 1;
    }
    ASSERT_EQ(0, failureCount) << "some combinations failed";
}

让我试一下,然后回复你。 - Karthick S
嗨Emile,虽然听起来很简单,但是我正在获取测试用例执行次数时,即使在expectedComboTable中有数百个组合,也只得到1。由于这个原因,我需要重新制作报告仪表板等内容,以提供对于已经存在组合的情况下失败组合的准确计数。这太麻烦了。因此,我将无法使用它。感谢您的想法。 - Karthick S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接