第一章 为什么使用单元测试
1.1 程序员的工作——修改软件
修改既有代码是程序员谋生的手段。但是为什么我们需要去修改软件呢?修改软件有以下4个主要起因:
● 修正bug
● 添加新特性(feature)
● 改善设计
● 优化资源使用
这4项都与软件的“行为”密切相关,见下表。
软件的既有行为 | 软件的新行为 | |
修正bug | 改变软件的既有行为 | 增加新行为 |
添加新特性 | 保持软件的既有行为,完全不修改既有代码 | 无 |
改善设计 | 保持软件的既有行为,但软件的可维护性得到提升 | 无 |
优化资源使用 | 保持软件的既有行为,但软件的性能得到提升 | 无 |
通过这张表格我们看出:只有在修正bug时,我们才需要改变软件的既有行为,而在其他情况下,我们都需要保持住软件的既有行为。如果我们在改善设计,优化,或添加新特性时改变了软件的既有行为,那我们实际上是给软件引入了bug。
可是程序员的工作就是修改软件,所以我们有很多的“机会”给软件引入bug。有什么办法能让我们的生活轻松一点,而不用因为修改代码引入bug而担惊受怕吗?
1.2 软件夹钳——测试
我们已经看到:在大多数情况下,我们希望对软件所做的改动不会改变系统的既有行为。即使是对于修正bug这种情况,我们也希望一旦bug被修正,那么修正后的正确行为能够得到保持,而不会被再之后的代码修改所改变。怎样做到这一点呢?
让我们这样想想:如果我们能在对代码进行改动之前,用一种“软件夹钳”(software vise)来固定住软件的既有行为,那么我们就可以放心大胆地去修改代码了。那么,又是什么可以来充当“软件夹钳”呢?答案是:测试。我们可以这样想一下:当一段代码被一组良好的测试所覆盖时,我们就可以放手去修改这段代码,并在修改完成之后立即运行这组测试,来验证我们的修改并没有改变既有行为而引入bug。如果确实改变了既有行为,那么测试就会明确无误地发出警报。由此可见,测试就是程序员所需要的“软件夹钳”。
1.3 单元测试与集成测试之争
我们已经知道了“测试”就是程序员所需要的“软件夹钳”。但是测试分为单元测试和集成测试,程序员需要哪种测试呢?让我们来分析一下程序员需要什么样的测试,这样或许我们就能知道程序员应该更偏向于哪种测试了。
● 程序员需要的测试应该是能帮助程序员定位错误的,这样程序员才会真正地从测试中得到“实惠”。
● 程序员需要的测试应该是很容易执行的,最好是只需点击一个按钮或键入一条命令,这些测试就能运行,而无需费时费力地去搭建测试环境及准备测试数据或仪器。
● 程序员需要的测试应该是运行速度很快的,最好能在几分钟内完成,这样程序员才能快速地得到反馈,采取下一步动作。
● 程序员需要的测试应该是易于写就的,而不愿意对代码基大动干戈,这样程序员才会愿意去写这些测试。
● 程序员需要的测试应该是自动化的,可重复的。这样程序员才会愿意重复多次地去运行这种测试。