使用模拟测试迭代代码 - 这是否有意义,如何?
我想使用模拟来测试算法。该算法 - 在当前的实现中 - 多次迭代容器类并从中设置()和获取()值。测试的目的是验证存储在容器中的最终结果。最终值取决于两次传递之间读取和写入的值。例如,任何元素的值可能会多次更改,直到算法完成,并且最有可能的是,其作为迭代 n 的结果的值将取决于其在迭代 n-1 后的值。
我喜欢模拟的想法,并且我很乐意在上述场景中使用它们,因为它允许我在算法发生错误行为时验证它,而不仅仅是在计算完成时。但是,我不确定这实际上是否是一个好主意,因为我必须将对模拟真实的期望与当前实现联系起来(例如,“期望 get(element n) 并返回 x,然后 set(元素 n,值 x+1),另一个 get(n) 并返回 x+1,然后期望 set(n, x+2) 等”)。
虽然允许我验证中间值是否符合预期,但我认为这种期望会与测试的目的相矛盾(验证算法计算出正确的最终值),并且如果实现发生变化,无论测试的正确性如何,测试都可能失败最终值。
现在我的问题是:我错过了什么吗?在这种情况下有没有一种使用模拟的好方法?或者在这里使用它们根本没有意义?其他人如何处理这个问题?
最后评论:我正在谈论测试 C++ 代码并使用 googlemock,如果这对您的答案有任何影响。
ps:我检查了谷歌和这里的文章(特别是模拟迭代行为 - 仅解决增加回报的问题值),但是,我没有找到任何接近我的问题的东西。
I want to test an algorithm using mocks. The algorithm - in the current implementation - iterates over a container class in multiple passes and set()s and get()s values from it. The test's purpose is to verify the final result, stored in the container. The final value depends on values read and written in between the passes. e.g. the value of any element may change multiple times until the algorithm is finished and, most-likely, its value as result of iteration n will depend on its value after iteration n-1.
I like the idea of mocks and I would love to use them in the scenario described above since it would allow me to verify erroneous behavior of the algorithm once it occurs, not only when the computation is finished. However, I'm not sure whether this would actually be a good idea because I would then have to tie the expectations for the mock real close to the current implementation (e.g, "expect get(element n) and return x, then set(element n, value x+1), another get(n) and return x+1, then expect set(n, x+2) etc.").
Although allowing me to verify that intermediate values are as expected, I think such expectations would contradict the purpose of the test (verify that the algorithm computes the correct final value) and likely the test would fail if the implementation changes, regardless of the correctness of the final value.
Now my question: am I missing something? Is there nevertheless a good way to use mocks in this scenario? or does it simply make no sense to use them here? How do others deal with this problem?
Final remark: I'm talking about testing c++ code and using googlemock, if that makes any difference to your answer.
p.s.: I checked google and articles here (especially Mocking iterative behaviour - only tackles the problem of increasing a return value), however, I didn't find anything close to my problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为算法的最终输出创建单元测试。您希望自动化测试能够验证预期结果,因为这是程序的其他部分将使用的结果。
就测试算法代码中的各个步骤而言,这更多的是使用调试器逐步执行的工作,而不是自动化测试。了解算法的内部工作原理应该是一次性的事情,一旦你掌握了正确的方法,就没有必要继续测试其中的各个步骤。
Create your unit test for the final output of the algorithm. You want your automated testing to verify the expected result because that is what other parts of the program will utilize.
As far as testing the individual steps within the algorithm code, this is more a job for stepping through with a debugger -- not for automated tests. Going through the internal workings of the algorithm should be a one-time thing, and once you have it right there's no need to keep testing individual steps within it.
我想说,如果容器在某种程度上很慢或者它有副作用,这意味着你无法在不干扰它的情况下读取它的值,那么你应该使用模拟。
否则,使用模拟就是浪费时间。您会使用
std::vector
的模拟版本吗?我不会;这太愚蠢了。在单元测试中,如果您无法通过各种公共参数测试算法的所有内部状态,那么这些状态实际上并不重要。它们永远无法实际使用。因此,只要您从算法中为每组输入参数获得正确的最终答案,我就会说事情进展顺利。
I would say that if the container is slow in some way or it has side-effects that mean you cannot read its values without disturbing it, then you should use a mock.
Otherwise, using a mock is a waste of time. Would you use a mocked version of
std::vector
? I wouldn't; it would be silly.With your unit testing, if you cannot test all of the internal state of your algorithm through various public parameters, then those states don't actually matter. They can never come up in real use. So as long as you get the correct final answer from your algorithm for each set of input parameters, I would say things are working well.
单元测试更适用于组成算法的较小部分。
话虽这么说,单元测试工具对于以这种方式开发算法非常有帮助。它们用起来一点也不差,只是如果它们不再有效就不要保留它们。通常,您不会在集成测试中测试每个迭代,而只需测试结果。如果以这种方式开发算法有帮助,那就去做吧。
你对模拟的看法是对的,你并没有真正进行很多测试。如果您想控制某些输入,它们可能会很有用。很多时候,当我有无法控制的黑匣子时,我会以详尽的方式排列我的输入。不过,此类测试运行时间太长。当它们进入源代码管理时,我通常会将它们全部或部分注释掉。
Unit tests would be more applicable on the smaller parts that compose the algorithm.
That being said, unit test tools are very helpful for developing algorithms that way. They aren't bad at all to use, just don't hold on to them if they aren't valid anymore. Usually you wouldn't test each iteration in an integration test, you'd just test the results. If it is helpful to develop the algorithm that way though, go for it.
You are right about the mocks, you aren't really testing a lot. They can be useful if you want to control some of the inputs though. Many times I will permute my inputs in exhaustive ways when I have black boxes that I cannot control. These sorts of tests run too long, though. I will generally comment them out entirely or partially when they go into source control.