使用模拟测试迭代代码 - 它是否有意义,如何?

时间:2011-09-12 14:02:44

标签: c++ algorithm unit-testing mocking googlemock

我想使用模拟测试算法。该算法 - 在当前实现中 - 在多个传递中迭代容器类,并从中迭代set()和get()s。测试的目的是验证存储在容器中的最终结果。最终值取决于在通道之间读取和写入的值。例如任何元素的值可能会多次更改,直到算法结束,并且最有可能的是,它作为迭代结果n的值将取决于迭代n-1后的值。

我喜欢模拟的想法,我很乐意在上述场景中使用它们,因为它可以让我在算法出现时验证算法的错误行为,而不仅仅是在计算完成时。但是,我不确定这是否真的是一个好主意,因为我必须将模拟实际的期望与当前实现联系起来(例如,“期望得到(元素n)并返回x,然后设置(元素n,值x + 1),另一个get(n)并返回x + 1,然后期望set(n,x + 2)等。“)。

虽然允许我验证中间值是否符合预期,但我认为这样的期望会与测试的目的相矛盾(验证算法计算正确的最终值),如果实现更改,测试可能会失败,无论最终价值的正确性。

现在我的问题是:我错过了什么吗?在这种情况下,是否有一种使用模拟的好方法?或者在这里使用它们毫无意义?其他人如何处理这个问题?

最后评论:我正在谈论测试c ++代码并使用googlemock,如果这对你的答案有任何影响。

p.s。:我在这里检查了谷歌和文章(特别是Mocking iterative behaviour - 只解决了增加返回值的问题),但是,我没有发现任何接近我问题的内容。

3 个答案:

答案 0 :(得分:3)

为算法的最终输出创建单元测试。您希望自动化测试验证预期结果,因为这是程序的其他部分将使用的。

就测试算法代码中的各个步骤而言,这更像是一个使用调试器的工作 - 而不是自动化测试。通过算法的内部工作应该是一次性的事情,一旦你做对了就没有必要继续测试其中的各个步骤。

答案 1 :(得分:1)

单元测试更适用于构成算法的较小部分。

话虽这么说,单元测试工具对于以这种方式开发算法非常有帮助。它们使用起来并不坏,如果它们不再有效,就不要抓住它们。通常,您不会在集成测试中测试每个迭代,您只需测试结果。如果以这种方式开发算法是有帮助的,那就去吧。

你对嘲笑是正确的,你并没有真正测试过很多。如果你想控制一些输入,它们会很有用。很多时候,当我有无法控制的黑匣子时,我会以详尽的方式置换我的输入。但是,这些类型的测试运行时间太长。我会在进入源代码控制时全部或部分地对它们进行评论。

答案 2 :(得分:1)

我会说,如果容器在某种程度上是缓慢的,或者它有副作用,这意味着你不能在不打扰它的情况下读取它的值,那么你应该使用模拟。

否则,使用模拟是浪费时间。你会使用std::vector的模拟版本吗?我不会;这将是愚蠢的。

通过单元测试,如果无法通过各种公共参数测试算法的所有内部状态,那么这些状态实际上并不重要。他们永远不会真正使用它们。因此,只要您从算法中为每组输入参数得到正确的最终答案,我就会说事情进展顺利。