作为极限编程的核心实践之一,测试驱动开发的大名我已仰慕许久。但将测试阶段放置在开发过程的最前端,对于很多像我一样学习、应用传统重量级开发流程的程序员而言,这样的做法似乎实在是太不可思议。所以,我在开发中,还是保留着先实现,后写测试用例的做法。
但最近因为工作流程的一些变化,让我不得不重新审视自己的一些做法,即使是找寻不到“银弹”,期望好歹也能找到些有用的“铜弹”、“铁弹”。于是又捡起了在书架中染尘已久的大作《测试驱动开发》。这本书虽是大作,却体态小巧轻盈,如 K&R 的那本经典之著《C程序设计语言》一般。
Kent Beck 向我们说明了测试前置有诸多好处,结合自己的应用实践,略略谈谈我对测试驱动开发的印象和感受。
但最近因为工作流程的一些变化,让我不得不重新审视自己的一些做法,即使是找寻不到“银弹”,期望好歹也能找到些有用的“铜弹”、“铁弹”。于是又捡起了在书架中染尘已久的大作《测试驱动开发》。这本书虽是大作,却体态小巧轻盈,如 K&R 的那本经典之著《C程序设计语言》一般。
Kent Beck 向我们说明了测试前置有诸多好处,结合自己的应用实践,略略谈谈我对测试驱动开发的印象和感受。
- 测试前置能帮助开发者忽略内部细节,明确将要实现的模块的 API。因为满足单元测试需要的 API 必然是需要实现的 API,而不需要通过测试的 API 也必然是无用的 API,所以在书写单元测试用例的同时,也就逐步设计出模块的 API 来。从而避免在被模糊不清的高层需求和错综复杂的底层实现弄得晕头转向的情况下,或者过度设计或者设计不足(往往是兼而有之)。
- 持续测试、每日构建能够增强开发者对程序代码的信心,对于程序的质量也是益处多多。避免了到项目临近结束时才发现大量模块内部实现的问题。
- 单元测试有助于重构。在重构时,只要保证重构后的代码能够通过单元测试,便可以(满有信心地)认为重构后的代码依旧满足原有 API 的要求。
- 书中有一个细节令我印象深刻。在针对 plus 操作的测试,Kent 首先只是在实现类中简单地返回一个常量,快速地通过测试。通过对测试用例的完善,和对实现类的不断重构,逐渐完全实现 plus 操作的功能。这样做的目的是在开始阶段只花费较少的时间实现,尽快地从单元测试中得到反馈,缩短每一次微小迭代(micro iteration)的周期,让每一次迭代都站在稳固的基石之上(这块基石就是所有测试用例皆通过之后 xUnit 显示出来的绿条条
)。