译者序

测试驱动开发(Test-Driven Development, TDD)这种编程手法或许很早就出现了,它后来能够重新得到关注的其中一个原因在于,有一群开发者很乐意通过各种实例向我们介绍该手法的好处。我刚学编程的那几年,依然在用老办法写程序,虽然也做过一些测试,但都是实现完功能之后补写的,直到2007年看了Kent Beck的《测试驱动开发》(Test-Driven Development: By Example),才发现原来程序可以这样写。

从最基本的流程上说,TDD可以概括成三个环节:首先,写一项测试,以描述有待实现的某个功能,并在其中做出断言,以表示产品的执行效果必定与期望的效果相符,由于我们还没有编写相关的产品代码,因此这样的测试几乎总是无法通过;其次,用极其简单的方式(甚至可以是硬代码)来编写产品,让这项测试能够通过;最后,重构产品与测试代码,让两者都变得更加准确、清晰。

测试代码明确地描述了需求,促使开发者必须写出满足该需求的产品代码,这确保我们不会走错方向。测试越写越多,这些测试所覆盖的范围也逐渐扩大,这促使我们把代码写得越来越通用,但是,由于我们在每一轮迭代时都力求用最简单的写法让测试通过,因此不会像以前那样总是想一下子就写出极为通用的代码,从而导致过度设计。另外,有这套测试做保障,就不用害怕新编的代码会破坏已经写好的功能了,因为假如出现那样的情况,就会有测试无法通过,从而提醒我们注意该问题。

现在距离《测试驱动开发》一书面世已经20多年了,但仍有一些朋友尚未尝试过TDD,还有一些虽然尝试过,但尚未完全了解它的理念并体会到它的好处。如果说Kent Beck重新发现了TDD,那么Saleem Siddiqui的这本书则有可能让TDD变得更加流行。

本书采用一个完整的项目贯穿各章,作者全程示范了如何把项目拆解成多个小功能,并依次采用测试驱动的方式实现这些功能。每实现一个功能,作者都会演示如何通过重构,把这个功能的代码乃至项目的结构调整得更好。作者采用三种编程语言讲解,这不仅能吸引更多的人来阅读,而且让我们能够观察各种编程语言在设计思路与实现细节方面的异同,进而养成一种超越编程语言的设计思维。大家在书中会看到如何结合具体语言的优势,以清晰的代码将这种思维表达出来。此外,作者还指引我们把这个项目提交到本地的git代码库中,以便做版本管理,并且告诉我们如何将本地仓库与远程的GitHub库同步,以及如何通过脚本制作CI(持续集成)管道,让项目代码每次推送到远程库之后都能够自动接受测试。

总之,这是一本流畅而连贯的教程,能让大家很快喜欢上TDD。当然,TDD本身仍有一些地方尚待思考,例如怎样测试图形界面以及多线程的代码等,希望大家结合自己的实际工作来探索这些问题。

为便于阅读,译者根据汉语习惯及原文语境补充了部分词句,以六角括号〔〕标出,原书中某些不便翻译的术语酌情保留原样,让大家能够直接用这些英文词来沟通,以避免误解。

翻译过程中,我得到了家人和朋友的帮助,在此深表谢意。

由于译者水平有限,错误与疏漏在所难免,请大家访问github.com/jeffreybaoshenlee/ltdd-errata/issues留言,或发邮件至eastarstormlee@gmail.com,给予批评和指正。

爱飞翔

2022年7月21日