在编写测试时,如何避免重新实现正在测试的代码?

时间:2011-11-27 18:17:48

标签: unit-testing rspec

(我在RoR中使用rspec,但我相信这个问题与任何测试系统都有关。)

我经常发现自己在我的测试套件中做了这种事情:

actual_value = object_being_tested.tested_method(args)
expected_value = compute_expected_value(args)
assert(actual_value == expected_value, ...)

问题在于我compute_expected_value()的实现通常最终会模仿object_being_tested.tested_method(),所以它确实不是一个好的测试,因为它们可能有相同的错误。

这是一个相当开放的问题,但人们使用什么技术来避免这个陷阱? (关于该主题的优秀论文指针获得的分数......)

3 个答案:

答案 0 :(得分:3)

通常(对于手动编写的单元测试),您不会计算预期值。相反,您只是断言您希望从给定args的测试方法得到的结果。也就是说,你会有这样的事情:

actual_value = object_being_tested.tested_method(args)
expected_value = what_you_expect_to_be_the_result
assert(actual_value == expected_value, ...)

在自动生成参数(甚至正在执行的测试方法)的其他测试场景中,您需要设计一个简单的oracle,它将为您提供预期的结果(或者应该保留预期结果的不变量)。 PexRandoopASTGenUDITA等工具可以进行此类测试。

答案 1 :(得分:1)

这是我的两分钱

a)如果预期值的计算很简单,并且除了它产生预期结果的测试用例之外不包含任何业务规则/条件那么它应该足够好了......记住你的实际值代码将尽可能通用。 好吧,有些情况下你会遇到预期方法中的问题,但你可以很容易地指出失败的原因并修复它。

b)有些情况下,在这种情况下无法轻易计算预期值,可能包含带有结果的平面文件或者可能是某种常量预期值,这自然是您想要的。

此外还有测试,你只想验证一个特定的方法是否被调用,你完成了对该单元的测试..记得在测试时使用所有这些不同的范例,并始终记住 KEEP IT SIMPLE

答案 2 :(得分:-1)

你不会这样做。

你没有计算预期值,你已经知道了。它应该是您的测试中定义的常量值。 (或者是从已经过测试的其他功能构建的。)