单元测试和回归测试(3)

发表于:2015-03-27来源:uml.org.cn作者:SoftwareTeacher点击数: 标签:单元测试
单元测试应该产生可重复、一致的结果。 如果单元测试的结果是错的,那一定是程序出了问题,而且这个错误一定是可以重复的。 问:如果用随机数以增

  单元测试应该产生可重复、一致的结果。

  如果单元测试的结果是错的,那一定是程序出了问题,而且这个错误一定是可以重复的。

  问:如果用随机数以增加测试的真实性,好么?

  答:一般情况下不好,如果某个随机数导致程序出错,但是下一次运行又不能重复这一错误,于事无补。要注意我们还是要用随机数等办法“增加测试的真实性”,但是不是在单元测试中。单元测试不能解决所有问题,所以也不必期望它会发现所有的缺陷

  独立性,单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性。

  程序中的各个模块都是互相依赖的,否则它们就不会出现在一个程序中。一般情况下,单元测试中的模块可以直接引用其他的模块,并期待其他的模块能返回正确的结果。

  如果其他的模块很不稳定,或者其他模块运行比较费时(如进行网络操作),而且对于本模块的正确性并不起关键的作用,这时可以人为地构造数据以保证这个单元测试的独立性。

  单元测试应该覆盖所有代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,单元测试必须测试公开的和私有的函数/方法。

  单元测试必须覆盖所测单元的所有代码路径。

  问:啊!这样岂不是要写很多啰里啰唆的测试方法?

  答:对,因为程序中很多缺陷都是从这些啰里啰唆的错误处理中产生的。如果你的模块中某个错误处理路径很难到达,那你也许要想想是否可以把这个错误处理拿掉。

  大栓:这对于那些爱写复杂代码的人是一个很好的惩罚,不对,是一个很好的锻炼。

  阿超:对,把单元测试的责任和代码作者绑定在一起后,代码作者就能更真切地体会到复杂代码的副作用,因为验证复杂代码的正确性要困难得多。要注意的一点是:100%的代码覆盖率并不等同于100%的正确性。

  单元测试应该集成到自动测试的框架中。

  另一个重要的措施是要把单元测试自动化,这样每个人都能很容易地运行它,并且可以使单元测试每天都运行。每个人都可以随时在自己的机器上运行。团队一般是在每日构建中运行单元测试的,这样每个单元测试的错误就能及时被发现并得到修改。

  单元测试必须和产品代码一起保存和维护。

  单元测试必须和代码一起进行版本维护。如果不是这样,过了一阵,代码和单元测试就会出现不一致,而且所有代码的作者要花时间来确认哪些是程序出现的错误,哪些是由于单元测试更新滞后造成的错误。这样就失去了单元测试的意义,同时又给大家增加了负担。如此折腾多次以后,大家就会觉得维护单元测试是一件很费时费力的事。

  3、回归测试

  在单元测试的基础上, 我们就能够建立关于这一模块的回归测试 (Regression Test).

  Regress 的英语定义是: return to a worse or less developed state。是倒退、退化、退步的意思。

  在软件项目中,如果一个模块或功能以前是正常工作的,但是在一个新的构建中出了问题,那这个模块就出现了一个“退步”(Regression),从正常工作的稳定状态退化到不正常工作的不稳定状态。

  在一个模块的功能逐步完成的同时,与此功能有关的测试用例也同样在完善中。一旦有关的测试用例通过,我们就得到了此模块的功能基准 (Baseline) , 一个模块的所有单元测试就是这个模块最初的Baseline。

  假如,在3.1.5版本,模块A的测试用例125是通过的,但是测试人员发现在新的版本3.1.6,这个测试用例却失败了,这就是一个“倒退”。在新版本上运行所有已通过的测试用例以验证有没有“退化”情况发生,这个过程就是一个“Regression Test”。如果这样的“倒退”是由于模块的功能发生了正常变化(由于设计变更的原因)引起的,那么测试用例的基准就要修改,以便和新的功能保持一致。

  针对一个Bug Fix, 我们也要作Regression Test。

  (1)验证新的代码的确把缺陷改正了。

  (2)同时要验证新的代码没有把模块的现有功能破坏,没有Regression。

  所以对于“回归测试”中的“回归”,我们可以理解为“回归到以前不正常的状态”。

  回归测试最好要自动化,因为这样就可以对于每一个构建快速运行所有回归测试,以保证尽早发现问题。单元测试是回归测试的基础.

原文转自:http://www.ltesting.net