这篇博文的重点:

  1、单元测试的目的是什么;

  2、单元测试测试什么;

  3、在敏捷开发中,如何进行单元测试;

  4、测试的分配与配合;

  5、如何设计好的单元测试案例;

  因为我的打字不快,外加国内对知识产权的轻视,我不准备花大篇幅写详细文章,内容只是点到为止。你想学到更高深的知识,请在参加我开设的培训(我没有组织任何培训,也没有自己的培训机构,所以上一句话是说了白说)。

  有人认为大多数程序员知道单元测试的重要性。事实上只有少数人知道单元测试的重要性,大多数程序员都懒得写单元测试,大多数公司都在使用流水性工程管理。XP,敏捷开发,或是精简敏捷开发都没有想像的那样广泛应用,甚至在很多地方XP,敏捷开发的应用都不正确。甚至在我现在的公司里,很多人都不知道如何运用JUnit/NUnit来进行单元测试。他们对JUnit/NUnit会有各种错误假设,然后设计出来的单元测试根本解决不了实际问题。更多的公司根本不懂自动化测试或单元测试,所以他们所有的测试多半是半自动半人为的测试。有一部分可能还只是人为测试,效率低下。

  单元测试的目的

  我也不重复很多地方已经重复过的什么是单元测试,单元测试的目的,我只想说说我的看法。单元测试的目的是在早的开发阶段进行测试。这么做的好处,大的好处是,每次开发对一个个单元(也是类)进行更改,再运行一下单元测试知道自己有没有破坏单元希望达到的功能。TDD的目的是用测试来推动开发的进行。在单元没有成形之前,单元测试案例被设计出来模拟假想中的单元是如何被利用的,这时单元测试案例的运行肯定是不及格的,然后开发开始设计单元来让单元测试案例的运行达到及格。以后的修改中,所有的单元测试要运行来保证单元的修改没有造成运行的错误。

  当然,并不是所有的开发团队都进行TDD,单元测试还是可以帮助这些小组,单元测试可以间接地测量一个单元的可测试性,要是一个单元要依靠很多其他单元才能完成一个操作,那么这个单元对其他部件的依赖性过大,那么可测性很低。单元与单元的依赖可以依靠Mock对象来测试,但是过于复杂的依赖特别是实类和实类的依赖,在单元测试中可以马上检测出程序的可测性。

  单元测试的目的,好处,并不是显而易见的。了解这些细节只能从详细阅读理解书籍和网上的资料,或者从我这样的人交流获得。现在很少人能够一字一句地将书或文章读透。所以好的学习方法还是通过面对面的交流。

  单元测试测试什么

  单元测试的是一个源码中小单元的代码是否正确处理它该处理的任务。源码中小单元的代码可以是一个类中的类函数。也可以是类的本身(几个类函数一起合作处理类所应该进行的操作)。这里为什么有两种不同,因为单元测试设计者的风格不同,导致设计的不同,但是任何测试结合几个已开发的实单元,不算单元测试。使用Mock单元来协助现有单元的测试是单元测试,因为Mock单元不是已开发的实单元,它是一个假的,辅助性的单元。所以使用Mock单元终测试的也只是现有开发的单元。

  任何测试,如业务功能,或是接口型测试都不算是单元测试。严格地说单元测试在面向对象程序设计里,是对类为单元的测试。业务功能,接口测试已经是QA测试负责的业务。在XP,敏捷,精简敏捷开发里,业务功能,接口测试是接受性测试中的部分。QA在开发者开发的同时,必须对业务功能定义并设计接受性测试。只有通过了接受性测试,代码的初级接受性才能认可。单元测试是开发者自己的接受性测试,目的是保证自己开发的单元合乎自己的期望。QA的接受性测试往往是以业务功能定义和接口为目标的局部结合性测试,甚至有时是复杂的头到尾测试。单元测试和QA接受性测试都不能忘记边界情况,边界数据的处理等等案例。

  单元测试的目标是,在快的速度内让任何人能够设计一个测试案例,然后能够马上执行,案例与案例间不能有任何序列的依赖,每个单元测试都有自己的测试前设置,和测试後清除步骤(所以两个测试案例不用相互依赖)。

  在敏捷开发中,如何进行单元测试

  在敏捷开发中,自动化,经常性的单元测试是一个项目成功的关键。所有的自动化测试在每一次的构建後都要运行,任何错误都会造成构建失败,这样才能督促开发者或测试修改出错的地方。构建可以是每日构建(Daily Build),甚至是随时只要有变化进行构建(Constant Continuous Build)。

  敏捷开发的目标是,在开发中出现任何变化,整个团队都能敏捷地转换自己的开发方向来顺应变化的要求。TDD所要达到的目的是用需求来引导单元的业务功能,用测试先模拟业务功能的实现,在引导开发者实现单元的的业务功能。开发者必须对单元进行分割和重组,利用OO佳设计结构和设计模式(Design Pattern)来实现OCP(Open for extension, Close for modification Principle)。利用OCP达到的目的是让整个系统变得更易延伸,更易维护。TDD也会驱使开发者对程序系统的构架进行层次分化,将系统分割成用户界面,商业逻辑,和后台存储的三层结构。三层结构是具有测试性的,用户界面是用手动测试,和专业自动化测试工具进行的。商业逻辑和后台存储这两层都能用单元测试来实施自动话和单元化测试。具体如何做到这些,必须通过实际案例的剖析来理解。