15 September 2013

测试对于提高软件的质量来说意义重大,修改bug并不难,但是寻找bug却是非常难的。正因为此,测试的重要性不言而喻。对于初学者来说,测试往往被忽略或被轻视,而事实上,能写出好的测试也是一种能力,需要不停的修炼。

按照理解,测试似乎是在代码完成之后再实现的部分,毕竟测试的是代码,但是测试却可以先行,而且还会收到良好的效果,事实上,测试驱动开发(TDD)就是这种测试先行的方法。

具体来说,TDD即先写测试,再写代码。也许你会好奇,这种方法与测试后行的方法有什么区别?根据《代码大全》中的描述:

  • 在开始写代码之前先写测试用例,并不比之后再写要花多少功夫,只是调整了一下测试用例编写活动的工作顺序而已。
  • 假如你首先编写测试用例,那么你将可以更早发现缺陷,同时也更容易修正它们。
  • 首先编写测试用例,将迫使你在开始写代码之前至少思考一下需求和设计,而这往往会催生更高质量的代码。
  • 在编写代码之前先编写测试用例,能更早地把需求上的问题暴露出来。

我觉得《高效程序员的45个习惯》一书中对其好处做了更简洁的评价:

  • 先写测试,你就会站在代码用户的角度来思考,而不仅仅是一个单纯的实现者,因为你自己要使用它们,所以能设计一个更有用,更一致的接口。
  • 有助于消除过度复杂的设计,让你可以专注于真正需要完成的工作。

总结来说,测试先行与后行所花费的成本并不大,而测试先行却可以使程序员站在更高的角度上来审视代码,编写代码。不仅可以更早的发现问题的所在,还能以用户的角度发现更多的需求和设计。

实际上,《代码整洁之道》还给出了TDD三定律:

  • 定律一:在编写不能通过的单元测试前,不可编写生产代码。
  • 定律二:只可编写刚好无法通过的单元测试,不能编译也算不通过。
  • 定律三:只可编写刚好足以通过当前失败测试的生产代码。

我们编写测试刚好不通过时,说明我们需要编写生产代码来实现某些功能,这时我们就要着手去编写代码。通过TDD的三定律,我们基本要做到测试与代码同行(测试要稍早一些),通过不停的实现这一过程,我们可以编写更多的测试,覆盖更多的生产代码。

《代码大全》最后做了总结:

总而言之,我认为测试先行的编程是过去十年中所形成的最有用的软件开发实践之一,同时也是一个非常好的通用方法。

在这篇《测试驱动开发(TDD)跟敏捷开发有冲突》中,我很认同作者的观点。无论是测试先行还是后行,重要的是我们既要测试又要写出良好的测试,条条大路通罗马,只要能达到目的就是最好的方法。



blog comments powered by Disqus