因为两种类型的测试都是必要的,你会需要编写它们的指南。
如何编写单元测试
在你开始编写单元测试很容易被激动的情绪感染。最简单的起步方式就是为新的代码创建单元测试。为已经存在的代码创建单元测试是一种比较有难度的开始方式,但是也是可行的。)从新的代码开始,习惯了这样的步骤后,还要坚持重新阅读现有代码,并为它们创建一套测试程序。
就像前面提到过的一样,你应该在你编写要测试的代码之前编写单元测试。如何做到为还不存在的事物编写测试呢?好问题!掌握这个能力需要90%的智力和10%技巧。我的意思是你只需假装是在为已有的类编写测试。接下来,进行编写的工作。最初,你将出现很多语法错误,但是let it be,不要理会它。紧接着进行单元测试,修改语法错误(即是说,只用你自己定义的测试接口来实现类),再一次进行测试。重复这个过程,每一次都写下充足的代码去修改错误,进行测试直到它们通过为止。当所有的单元测试都通过时,代码才算真正地完成了。
一般地说,你的类应具有开放的单元测试方式。然而,带有直截了当的功能性的方法比如说,Java 语言里的Getting 和Setting 读写方法,就不需要单元测试,除非它们是以“特殊”的方式进行的。接下来的指导就是,当你感到需要对代码中的某些特性添加注释时,同时要编写出单元测试。如果你同很多的程序员一样,厌恶为代码写注释,单元测试就是将你的代码的特性文档化的一种好方法。
将单元测试同被测试的相关的类打包在一起。(这种组织的方式允许每一个单元测试都能够直接访问类中被打包和保护的方法和参数)。要避免在单元测试中用到域对象(domain object)。域对象就是对于一个应用程序特定的对象。
例如,电子表格应用程序有个工作簿对象,它就是一个域对象。如果你的一个类已经知道了域对象,在你的测试中用到这些对象是很好的。但是如果你的类没有涉及到这些对象,就不要在测试里让它们同类纠缠不清了。不这样做的话,就会产生打包的代码被重用。经常是为一个项目创建的类也可以应用于其他的项目,这样可能会出现直接重用这些类的情况。但是如果针对这些类的测试也用于另外的项目对象,让测试生效会很费时,通常测试不是被抛弃掉就是被重新编写。
以上的一些技巧会让你从中受益,但最重要的是如果你不实际地去做,就永远不会对单元测试有全面、深入的理解。更早地运行测试,并且在整个过程中都在代码中给出全面的依据。当项目进展时,你会随时添加更多的特性。运行测试就会提醒你,实现刚添加的特性会不会破坏已有的东西。
在你已经掌握编写单元测试的技巧之后,你需要重新阅读已存在的代码。的确,为它们编写代码可能会是一场挑战。但是千万不要为了测试的目的而测试。可以说,编写测试是一件紧跟时效的事情,尤其是当你发现要修改一个没有好的测试程序的类时,那就是添加测试的恰当时机。和平常一样,单元测试应该具备类每个方法的特性。实现测试的一个最简单的方法就是,测试的同时一定要注意代码的注释。在单元测试中,不能放过任何一个注释,在描述测试方法的开始就要为单元测试添加大量的注释中。
如何编写功能测试
尽管功能测试是如此重要,它也有个开发过程里丑陋的继生子的坏名声。在大多数的项目里,是由一个独立的工作组来完成功能测试的工作。通常需要一群人在系统中的相互协助才能保证工序的正确运行。这种通常的看法和队伍的组建的做法,都是非常愚蠢的。
功能测试同单元测试相类似。一旦要编写有用户涉入的产品的代码(例如,对话框)时,就要编写测试,但是一定要在实际编写代码之前做。一旦你开始了一项新任务,就要在功能测试的框架里清楚地描述这个任务的内容。你加入的新代码的同时进行单元测试,开发工作就向前持续进行。
当所有的单元测试都进行通过后,再进行最初的功能测试来判断项目是否可以通过,或是需要修改。理想的状况下,功能测试小组的概念应该不存在的。开发者应该同用户一同编写功能测试。系统通过了一系列的单元测试后,负责进行功能测试的小组成员就要改变初试测试的参数,再进行系统的功能测试。
单元测试和功能测试之间的界线
一般情况下,很难划清在单元测试和功能测试之间的界限。说实话,一直以来,我就不知道这个界线应该定在哪里。当编写单元测试时,我用以下几个方法来判定单元测试是不是已经变成了功能测试:
如果单元测试超越了类之间的界限,它可能变成了功能测试
如果单元测试变得非常的复杂,它可能变成了功能测试
如果单元测试变得很脆弱(即是说,它已经成为一个测试,但是却因为要迎合不同用户需求的改变而被动地变化),它可能变成了功能测试
如果单元测试比需要测试的代码还要难于编写,它可能变成了功能测试
注意“它可能变成了功能测试”的说法,在这里没有严格的标准。在单元测试和功能测试之间是有界线的,但是你必须自己判定它在哪里。单元测试进行地顺利,特定的测试逾越两者界线的过渡就越明显。
结论
单元测试以开发者的角度来编写,并注重被测试类的特性。当编写单元测试时,利用以下几条指导:
在类代码进行测试之前编写单元测试
在单元测试里掌握代码的注释
测试所有执行特定功能的公用程序(即是说,和Java 语言中的Getting 和Setting 读写方法不同的方法。除非它们是通过一种特殊的方式来完成Getting 和Setting 功能的。)
将所有的测试项目同被测试的类打包在一起,并且分配它们对在模块包内的和被保护成员
的访问权限
在单元测试中避免使用某些特定的对象
功能测试也需要从用户的角度出发来编写,并且注重用户所感兴趣的系统功能。选择一个适当的功能测试框架,或是开发出一种,并利用这些功能测试来制定用户们想要的东西。通过这种方式,功能测试的人员可以获得一个自动的工具,并且对使用工具的习惯有了一个好的起点。
将单元测试和功能测试作为开发进程的核心内容。这样做,你就会确定系统在正常运转。如果没有,你恐怕不能保证系统是正常工作的。测试可能不是一件好玩的事情,但是从事单元测试和功能测试会使开发过程里含有更多的乐趣。