比对程序员的需求,我们可以发现集成测试往往不能满足程序员的这些需求:

  ● 集成测试由于涉及多个模块,因此往往不能提供准确的错误定位信息。

  ● 集成测试的执行时间一般较长(小时级),这不能给程序员带来快速反馈。

  ● 集成测试可以自动化执行,但前提是把测试环境和测试数据等事先准备好。

  ● 集成测试由于不太容易写,通常不是由程序员写,而由专门的测试人员写。

  相反,单元测试,尤其是良好的单元测试,恰恰正是程序员所需要的那种测试:

  单元测试针对单个类或单个方法,能很有成效地帮助程序员准确定位问题所在。

  单元测试应该是执行时间很短的,全部执行也只需5到10分钟,程序员正好可以去喝喝咖啡。

  单元测试是一种“虚拟”测试,重在测试代码逻辑,因此一般不需要真实测试环境和测试数据的支持。

  单元测试是很容易写的,尤其是有单元测试框架的帮助时。

  由此可见,对于程序员而言,需要的是单元测试。程序员使用单元测试来充当软件夹钳,并在修改代码时获得快速反馈,从而更有信心地投入到修改软件的工作中。

  1.4 进行单元测试的其他好处

  我们已经知道了单元测试带来的一个好处:它可以充当程序员的“软件夹钳”,在程序员修改软件的过程中给予程序员快速的反馈,帮助程序员定位问题,避免引入bug。单元测试只有这一个好处吗?不是的。下面我们来看看引入单元测试带来的其他好处。

  1.4.1 单元测试是代码的“活文档”

  让文档及时反映软件设计和代码的新情况,这是一个颇有挑战性的问题。一种较好的思路是:使用“内部”文档,即把文档同代码“拴”在一起。这样当代码发生改变的时候,文档也能相应更新。注释是一种内部文档,良好的注释应该反映代码的新状况。

  类比来看,单元测试同样也是内部文档,因为单元测试本质上也是描述了被测类或被测方法的行为。对软件行为不了解的程序员,可以通过阅读单元测试代码来理解软件的行为。同注释相比,单元测试还具有一个更好的特性:它是一种“可执行”文档。如果单元测试在被执行时无法通过,那么说明要么单元测试没有反映当前代码的真实状况,要么说明代码中有bug。无论哪种情况,程序员都需要修改某一方,以保持两者的一致。

  1.4.2 具有可测试性的软件具有更高的质量

  近年来流行的极限编程方法论推崇“测试驱动开发”。我们认为,“测试驱动开发”并不一定要求必须先有测试后有代码,而关键在于要求在设计软件和实现编码时,一定要预先把软件的可测试性考虑周全。这种可测试性的重要体现是能够方便地将单个类或方法纳入单元测试之中。具有可测试性的软件的质量往往高于不具有可测试性的软件,为什么这样说呢?

  ● 一个类能够被方便地纳入单元测试,往往说明这个类职责单一,也是说它满足“单一职责原则”。

  ● 一个类能够被方便地纳入单元测试,往往说明它与其他类之间的耦合程度较低,相互依赖性较小,而且很可能满足“依赖抽象原则”和“开放-封闭原则”。

  因此, 具有可测试性的软件,也更有可能是满足良好设计原则的软件,所以往往质量更高。