其实TDD很简单,只要你不把它当测试。没错,就这么简单。把TDD当测试来写,你想着的就是如何找出已有代码的错误。想象着的是一副从迷宫中拯救出受困公主的图景。这个时候你就会受困于该如何去测与测什么的问题。假若你不把TDD当测试来写,顿时就会豁然开朗,拨云见日。
我认为TDD的本质在于,通过写测试来写代码。也就是在每一行产品代码落笔之前,先写一个测试来给这行代码找一个存在的理由。在参加TWU期间,一位名叫Garret Smith的培训师(Coach)反复和我们强调任何一行代码都要有测试。而且给我们举了一个实际例子:公司的英国办公室的一位同事编写一个软件专门用来对付无测试的代码。方式就是一行行地删除产品代码,如果测试仍然能够通过,这行代码就被删除了。这个例子给我的印象很深刻,因为我觉得它一语道破了天机。TDD其实就这么简单,让你的产品代码不能随便被别人“删除”。
当用这个视角去实践TDD的时候。测试的名字就会很细节化。具体到描述什么条件时以什么参数调用什么方法时会有什么返回值。回头一想,这些测试对应着是什么呢?其实就是javadoc文档!那么TDD又是什么一个过程呢?就是先写文档再写代码的过程。这么一说来,TDD就很自然了。你先想到一个很简单的功能要实现,有很多的代码要写。从一堆要写的代码中选择出最简单的部分(比如边界的情况)来写。把这部分代码的外部行为想好,写出对应的测试来,并给测试取一个能够当文档使的名字。
知道了TDD的本质与单元测试的本质之后,再来看一下我认为唯一关键的一个实践,那就是Mock。没有Mock的单元测试就很可能不是单元测试,也许是集成测试,也许是功能测试,总之不是TDD中所需要的那种能够驱动你开发的测试。任何牵涉到两个有行为的类之间交互的测试,都要Mock一个测另外一个,不然就会对象之间的互相影响就会使得测试测不准,无法确知问题所在,也无法让你的测试能够清晰地表达意图。
也许以前有一些书籍或者人讲过TDD只适合测算法,单元测试要做到黑盒,写Mock要适度之类的话。我目前的认识是这些见解容易让人把单元测试真当测试来看了。其实矫枉过正也无妨,就把TDD测试不当测试吧。总结一下就是TDD是确保你的代码不被别人意外“删掉”的开发方式,单元测试是你产品代码的文档,Mock是编写单元测试时最重要的技术,用于隔离测试对象行为。
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/