第四章 高质量的测试代码
4.1 测试代码同样要有高质量
有的开发人员认为,测试代码不是交付给最终用户的产品代码,只是内部测试使用的,因此其质量比产品代码低一点也无可厚非。我们认为这是一个错误的观点。
首先,虽然测试代码不会被交付给最终用户,但它同样是交付代码,它将被交付给下一代维护程序员,而这些维护程序员,很有可能就是我们自己。因此,为了让我们自己和其他程序员今后的生活轻松一点,我们应该在书写测试代码的时候,就以能达到的最高标准来要求。
另一方面,测试代码也必须是优质的代码。低劣的测试代码所带来的麻烦,远超过没有测试代码所带来的麻烦。因此,要么我们不写测试代码,要么就必须写出“好的”测试代码。
所以,我们希望树立起这样的观念:测试代码绝不是二等公民,必须以产品代码的标准来要求测试代码,因为测试代码也是要交付的代码。
如果有了这样的观念,那么下一个问题便是:我们怎样才能写出高质量的测试代码来?实际上,任何促使我们写出高质量的产品代码的方法和原则,也同样适用于促使我们写出高质量的测试代码。因此,只要我们遵循这些原则和方法,我们就能写了高质量的测试代码。这些方法和原则包括:
● 不留破窗原则
● DRY原则
● 单一职责原则
● 最小耦合原则
● 提高代码可读性
我们将在接下来的几节中分别来看看怎样具体贯彻这些原则和方法。
另一方面,同产品代码(production code)一样,测试代码(test code)应该有自己独立的源代码树,从而方便管理,因此在本章的最后一节中,我们将介绍如何管理测试代码的源代码树。
4.2 不留破窗原则
软件中的“破窗”指的就是bug。对于测试代码而言,不留破窗原则显得尤其重要。这是因为如果在测试代码中出现了bug,这种bug是很难被检测到的。当单元测试无法通过时,程序员往往会先从被测的产品代码中去寻找bug,直到无法在产品代码中找到bug,才会想到去测试代码中碰碰运气,这是很浪费时间也破坏士气的。因此,在书写测试代码时,一定要保证第一次写就把测试代码写正确。而当发现测试代码中出现了bug时,马上修正,不留破窗!
4.3 DRY原则
DRY原则要求在软件中的每一项信息都只有单一、无歧义、权威的表示。当我们的测试代码中出现了违背DRY原则的情况时,不要犹豫,要立刻重构,去除对同一信息的重复表示。DRY原则在测试代码中还体现为代码复用。测试代码中的代码复用主要是下面的三种形式。
4.3.1 使用helper method
这是一种常见的形式,把共同代码抽取到一个helper method中,让其他测试代码调用该helper method。实际上, Test Fixture中的SetUp()和TearDown()方法就是这种形式的典型应用。
4.3.2 使用参数化测试
参数化测试常常用于对一个被测方法进行黑箱测试,即给被测方法各种不同的输入,然后检测被测方法能否对这些输入产生正确的结果。我们分别看看C++,C#和Java中怎样来进行参数化测试。
4.3.2.1 Google UTF对参数化测试的支持
gTest框架(1.5版)的参数化测试如下表所示。