如何使用 Google Test 测试大量数据结构的方法?

How to test methods of heavy data structures using Google Test?

假设我们有以下 class:

class Graph {
 public:

  Graph(int num_vertices, int num_edges, const EdgeList& edge_list)
    : num_vertices_(num_vertices), num_edges_(num_edges), edge_list_(edge_list) { }

  int GetNumberOfComponents() { ... }

 private:
  int num_vertices_;
  int num_edges_;
  EdgeList edge_list;
}

在文件gtest.cpp中我有这样的东西:

#include "gtest/gtest.h"

TEST(Test, NumberOfComponentsTest) {
  Graph graph(4, 3, {{1, 2}, {2, 3}, {1, 3}});
  EXPECT_EQ(2, graph.GetNumberOfComponents());
}

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

目标是使用 Google 测试框架检查 GetNumberOfComponents() 是否正常工作。

但是让我们考虑大型测试用例,例如 num_vertices = 1000number_edges = 100000。如果我不想硬编码所有边,在这种情况下如何编写这样的测试? ;)

如果您不想对大图进行硬编码,那么您需要一种确定性的方法来在 运行 时生成它。从文件读取会产生文件系统依赖性并减慢测试速度。

这个问题其实隐藏了两个问题:

  1. 真正在测试什么?
  2. 假设我决定我真的需要来测试 100K 条边,最好的方法是什么?

从我的观点和经验来看,最重要的问题是1:

  • 我在测试性能吗?那么是的,我需要测试 100K 边缘情况(并测量时间或其他资源使用情况)。
  • 我是否在测试边界条件并且我知道该实现具有大约 100K 个边的条件代码?那么是的,我需要测试这个案例。
  • 我是否正在测试稳健性或安全性并且我有理由认为我可能能够用 100K 边缘破坏被测系统?那么是的,我需要测试这个案例。
  • 另一方面,如果我 "just" 测试正确性,为什么我觉得测试 10 条边不足以说服自己该实现也适用于 100K 条边?在继续之前我需要回答这个问题。

做个比较:假设我正在测试一个 returns 数字列表总和的函数。假设我要测试 0,1 和 5 元素的列表。为什么我认为 5 个元素不足以代表一般情况?

我想说的是首先一个人必须真正理解什么一个人在测试为什么,在进入测试编码之前。

对于问题2,我觉得robert的回答是对的,我只能转述一下。您需要编写一个 尽可能简单的 辅助函数来在 运行 时生成图形。

但是从代码来看,Graph class 的设计问题似乎应该在之前解决:

  • 既然构造函数需要边列表,为什么在参数num_edges中还需要边列表的大小?该实现可以轻松地从列表本身获取列表的大小。
  • 此外,要求顶点数量的事实也是有问题的,总是出于与接收边列表相同的原因。顶点数应该是从边列表计算出来的,否则如果num_vertices和从边列表计算出的顶点数不一致怎么办?

您正在编写测试这一事实非常好,因为测试迫使您质疑 Graph 的设计。考虑一下并考虑重新设计,使用其他更简单的测试来指导您的设计。