Charles O’Farrell 在 LambdaJam 2015 关于 How I learned to stop unit testing and love property-based testing 的演讲中,涵盖了一些基于属性测试应使用的标准模式:
- Round-tripping/Symmetry/There and back again:基本前提是将某值转换为另一值,然后再转换回原始值,如序列化和解析文本为对象再写回文本等,但转换不能有信息丢失,否则会导致测试不通过,可通过始终将输入转换为在转换回时不会丢失信息的形式来避免,不过这可能会导致一些错误假设。
- Commutativity/Different paths, same destination:基本前提是改变某些操作的顺序不应改变最终结果,如对列表的每个元素添加相同值后再排序与先排序再添加值结果相同。
- Invariants/Some things never change:基本前提是进行某种操作不应改变测试对象的给定属性,常见的不变量包括列表大小在映射操作后不应改变、列表内容在排序操作后不应改变等。
- Idempotence/The more things change, the more they stay the same:基本上一次执行操作应与两次执行操作相同,如对列表多次排序结果应与一次排序相同。
- Induction/Solve a smaller problem first:基于“结构归纳”,如果一个大的东西可以分解为较小的部分,且某些属性对这些较小的部分成立,那么通常可以证明该属性对大的东西也成立,常用于递归结构如列表和树。
- Blackbox Testing/Hard to prove, easy to verify:是难以计算但容易验证的属性,如计算第 n 个质数,已知第 n 个质数时验证答案容易。
- Comparison with another implementation/Test Oracle:通过对算法的另一个实现运行相同的测试来验证属性,如比较并行或并发算法与线性单线程版本的结果,或验证新的 json 解析器与现有解析器的结果。
此外,选择的属性在代码有错误时应实际失败,如给定一个列表排序实现返回原始列表不变的情况,一些属性通过但一些正确的属性会失败,基于属性的测试需要更多地思考代码,识别属性的真假,能比单元测试更有信心。
一些额外资源:Practical Property-Based Testing - Charles O’Farrell、I Dream of Genning ScalaCheck Beyond the Basics - Kelsey Gilmore-Innis、An Introduction to Property-Based Testing - FFP、Choosing properties for Property-Based Testing - FFP、Testing patterns、Testing the Hard Stuff and Staying Sane - John Hughes。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。