Mik*_*378 5 testing tdd unit-testing property-based-testing
一些开发人员在基于示例的测试中争论 TDD 的一个警告是,可能缺乏所有有效的输入处理。
让我们举一个简单的例子,这些开发人员可能会争论:
编写一个将两个数字相加的程序。
Bob,开发人员开始编写第一个测试:
给定 1 + 3,那么结果是 4。
实现:def add(x: Int, y: Int) = 4
很好,通过了。
Now second test:
Given 2 + 2, then result is 4.
Implementation still the same: def add(x: Int, y: Int) = 4
So other developers would come and tell him:
"Now you see Bob that Example-based testing is not enough with your poor 2 examples !
You didn't test every output and looking at your actual implementation, it will fail for other inputs whose result is distinct from 4!
Now, listen to us and start writing some property-based tests to cover all valid inputs.
So let's start with commutativity test, associativity etc.. that are specific to the addition: properties of the addition !"
But but but.... Bob's TDD practice is really bad!
Indeed, he wanted to apply triangulation but he wrote a test that already succeeded, since the implementation hadn't to be altered!
To lead to Triangulation, one should write a test that fails.
And triangulation is one of the master key of the practice of TDD.
It allows the main step: refactoring since you should manage two paths that lead to 2 distinct results!
=> As long as the tests get specific, the code gets more generic thanks to refactoring.
So my question is:
If we practice strict TDD with good practice of triangulation, what is the real benefit of using Property-based testing, asserting invariants that are in 99% of cases already cover by a good TDD?
Indeed, supposing that developers have a good IQ and build implementation that makes sense ;)
My example is taken from those slides.
当边缘情况很难找到或者边缘情况太多以至于程序员很容易错过一个时,基于属性的测试非常有用。例如,我在实施 hirschberg 算法时使用了它。没有明显的方法可以将算法划分为更小、琐碎、易于 TDD 测试的部分。并且很难手工制作涵盖所有可能算法路径的输入。最好的方法是生成大量不同的输入来覆盖所有路径。当自动检查发现错误时,将该特定输入添加到您的回归测试中