“质量是免费的,但只有那些愿意付出沉重代价的人才能拥有。” -- 《人件》
为什么 TDD 测试驱动开发如此重要
软件的质量和开发效率都需要程序员快速频繁地收到反馈,测试驱动可以缩短反馈循环。
编写类和函数--(单元测试)->集成新模块--(集成测试)->生成新系统--(系统测试)->构建软件--(QA测试)->发布软件
如上,在编程与测试交织的软件开发流程中,反馈循环越短它的优势越明显。
- 代码修改的迭代速度越快,我们对代码也就越有信心。
- 越早发现问题,修复就越简单,成本也就越低。
测试的种类
成熟的软件项目应该包含以下 3 种测试。
- 单元测试(unit test):独立地测试最小的功能单元(一个类或函数),不涉及任何外部访问(没有数据库、网络或文件系统操作)。
- 集成测试(integration test):检查独立的单元如何集成在一起,并互相聚合、互相操作,以实现更大的功能。
- 系统测试(system test):端到端测试,覆盖系统规格说明书中要求的所有功能,可以用作项目的验收标准。
什么时候测试
- 早测试、勤测试:在编写代码的同时编写测试。不要推迟,否则测试的效率将非常低。
- 先测试、再修复 bug:先编写单元测试来模拟 bug 出现的原因,然后修复错误,并使测试通过,添加测试代码到版本库中。
- 先测试、再构建软件:将测试放入构建/编译/运行过程中,如果测试失败了,代码编译就会失败,软件就不能运行。
- 重视 QA 测试:自动化测试主要针对容易修复和预防的错误,无法模拟和考虑不周的 bug 还得靠 QA 周密的测试。
测试什么
测试软件中任何重要的内容,一切从需求出发。
- 既要考虑“正常”的输入和常见的“异常情况”,也要考虑边界情况,包括空和零状态。
- 测试必须检查每个代码单元的行为是否符合要求,并返回准确的结果。
- 如果性能对软件来说是一个重要的需求,那么应该有测试用例来测试代码的性能。
- 相比测试的覆盖率,更重要的是关注核心的行为和系统特性。
维护测试代码
- 因为测试代码和生产代码同样重要,所以要维护测试代码,并把它加入版本库。
- 为生产代码添加新功能后,要重构测试代码,回归测试,并听取它的意见。
- 测试框架 xUnit 不是必须的,一个 main 函数和一系列 assert 就可以实现测试代码。
- 构建易于测试的代码有利于产生好的设计。