有一点需要注意的是,一些开发人员认为TDD与基于实例的测试有关,可能缺少每一个有效的输入处理。
让我们举一个简单的例子,开发人员可以争辩说:
鲍勃,开发人员开始编写第一个测试:制作一个添加两个数字的程序。
现在进行第二次测试:
给定2 + 2,结果为4 。
实现仍然相同: def add(x:Int,y:Int)= 4
所以其他开发者会来告诉他:
“现在你看到鲍勃,基于实例的测试对你的可怜的2个例子是不够的! 您没有测试每个输出并查看您的实际实现,对于其结果与4不同的其他输入,它将失败! 现在,听取我们的意见,开始编写一些基于属性的测试,以涵盖所有有效的输入 因此,让我们从交换性测试,关联性等开始,这些是特定于添加的属性!“
但是但是......鲍勃的TDD练习真的很糟糕! 实际上,他想要应用三角测量,但他写了一个已经成功的测试,因为实现不得改变!
要导致三角测量,应该编写一个失败的测试。 三角测量是TDD实践的关键之一 它允许主要步骤:重构,因为您应该管理两条导致2个不同结果的路径!
=>只要测试具体化,由于重构,代码变得更加通用。
所以我的问题是:
如果我们通过良好的三角测量实践严格的TDD,使用基于属性的测试的真正好处是什么,断言99%的情况下已经由良好TDD覆盖的不变量?
实际上,假设开发人员具有良好的智商并构建有意义的实现;)
我的例子取自those slides。
答案 0 :(得分:4)
基于属性的测试非常有用,当边缘情况很难找到,或者有很多这样的程序员很容易错过。我使用它时,例如当我实施hirschberg的算法时。没有明显的方法可以将算法划分为更小,更简单,易于TDD测试的部分。并且很难手工制作涵盖所有可能的算法路径的输入。最好的方法是生成大量不同的输入以覆盖所有路径。当自动检查发现错误时,将该特定输入添加到回归测试
答案 1 :(得分:1)
如果您练习 TDD ,您知道这是一种思考和设计的方式而不是测试。
TDD起源于增量,主要是基于状态的单元测试。然后 交互式(即, mockist-style 或伦敦风格的)TDD改变了我们对代码设计代码的思考方式。基于属性的 TDD也有机会改变我们设计代码的方式。我们使用属性而不是生成示例来推动我们的设计。这导致更少的测试更易于维护,并具有更好的测试覆盖率。
另一方面,它比基于TDD的示例更难,需要更多思考。