22、不要关联到预定义的外部资源
编写测试文件的时候应该不能利用将要执行环境的上下文信息以使得他们可以在任何时间任何地方运行。为了给测试提供所需的资源,这些资源应该通过测试自身提供。
现在考虑解析某种类型文件的类的情况。应该将文件的内容放在测试内,在测试开始前将其写入一个临时文件并在测试完成后删除掉文件,而不是从预定义的路径选择一个示例文件。
23、了解测试成本
不写单体测试代价很高,写单体测试代价也很高。这是两者之间的平衡,从执行覆盖率考虑一般的行业标准是大约是80%。
通常比较困难达到完全覆盖的区域是处理外部资源的错误或异常。在一个交易中模拟数据库崩溃是完全有可能的,但较之作为替代方法的深度代码检查通常代价过高。
24、测试优先级排序
单体测试通常是一个至底而上的流程,如果没有测试系统所有部分所需的足够资源就应该优先考虑最底层。
25、考虑到测试代码失败
考虑下这个简单的实例:
Handle handle = manager.getHandle(); String handleName = handle.getName(); |
如果第一个断言是假的,接下来的语句就会崩溃,余下的测试也就不会被执行了。所以应该考虑单个测试代码失效不会使得这个测试套件无法执行。通常可以改写成这样:
Handle handle = manager.getHandle(); String handleName = handle.getName(); |
26、编写测试来重现缺陷
如果报告了一个缺陷,就应该写一个测试来重现该缺陷(比如一个失败的测试)并使用该测试作为是否成功修复代码的标准。
27、认识局限性
单体测试永远不能证明代码的正确性!
一个失败的测试意味着代码含有错误,而一个成功的测试不能证明任何东西。
单体测试的最普遍的应用就是验证和记录底层的需求以及回归测试:验证代码在变迁和重构的过程中一直保持稳定。
因此,单体测试永远无法替代前期设计和健全的开发流程。单体测试可以作为既有开发方法的一个宝贵补充。
后记:
对于第9点”测试类和被测试类尽量近”和第14点”微不足道的类也要测试”,我不是很赞同,实践的时候也没有完全遵守。但为了忠实于原文没有做擅自修改。大家在学习和实践的时候可能也会接触一些相悖的观点和理论,不要担心,选择最适合你尝试下就知道了。同时,欢迎说出你的故事!