Skip to main content

第09章 回归测试

第09章 回归测试

一、回归测试概念(白盒)

1)概念

在软件⽣命周期中的任何⼀个阶段,只要软件发⽣了修改和改变,就可能给该软件带来问题。修改可能是

  • 对问题的修改被遗漏;
  • 所做的修改只修正了错误的外在表现;
  • 导致软件未被修改的部分产⽣出新的问题

因此,每当软件发⽣变化时,我们就必须重新测试现有的功能,以便确定软件修改是否达到了预期的目的, 检查修改是否损害了原有的正常功能。同时,还需要补 充新的测试用例来测试新的或被修改了的功能。为了验 证修改的正确性及其影响,就需要进⾏回归测试。

回归测试的目的:

  • 比如说 V0. 1 版本的一个软件,到 V0. 2 版本一个新的版本的话,它发生了很大变化。但是这样的话我们测试需要把整个测试用例都要跑一遍吗?一个大的软件,可能比如有几万个测试用例,软件变化了以后它就要重新跑一遍,这样的话实际上来讲的话它有很大的一些这种资源的开销。所以说我们在想就是说如何能够以最小的代价去适应软件的变化
  • 我们对软件这种改变的一些问题的话,有一个针对性的测试,提高软件测试的这个质量

所以回归测试产生。回归测试解决的是原来很多功能都测过了,然后我是不是测过的一些功能,一些测试用例,我就没有必要把所有的测试用例都跑一遍。这么做,我们要保证,新的功能增加之后,原来测过的,就不需要再测了。这样减少了测试的代价。

回归测试是白盒测试,因为需要源代码。

2)传统方法

传统的测试方法有:

  • 把原来所有的测试用例跑一遍,把新的测试用例也要跑一遍。缺点是代价太高了,优点是方法简单。
  • 比如说原来的话有一个测试用例集大t,我们考虑是不是只是拿一部分。比如我新功能只用到了一部分函数,我就单独考虑只用测这一部分函数就可以了
  • 所以回归测试很特殊,他不是设计测试用例,而是选择测试用例

3)名词

  • 测试用例库: 对于⼀个软件开发项目来说,项目的测试 组在实施测试的过程中,会将所开发的测试用例保存到 “测试用例库”中,并对其进⾏维护和管理 。
  • 基线测试用例库 :当得到⼀个软件的基线版本时,用于 基线版本测试的所有测试用例就形成了基线测试用例库
  • 回归测试本质就是对于测试用例的管理和维护。回归测试删除一些过时的,然后改进一些不受控制的测试用例、删除冗余的测试用例,增添新的测试用例。所以回归测试核心兼顾效率和有效性。

4)回归测试包的选择

选择回归测试策略应该兼顾效率和有效性两个 ⽅面。常用的选择回归测试的⽅式包括:

  • 再测试全部测试用例:再测试全部用例具有最低的遗漏回归错误的风险,但是测试成本最⾼。
  • 基于风险选择测试:首先运⾏最重要的、关键的和可疑的测试,逐步降低风 险值,直⾄满⾜回归测试要求。
  • 基于操作剖面选择测试:测试用例是基于软件操作剖面开发的,优先选择那些针 对最重要或最频繁使用功能的测试用例。
  • 再测试修改的部分:当测试者对修改的局部有⾜够的信⼼时,可以通过等价 性分析,识别软件的修改情况并分析修改的影响,将回归测 试局限于被改变的模块和它的接⼝上。

二、回归测试策略

1)回归测试的步骤

回归测试可遵循下述基本过程进⾏:

  • 识别出软件中被修改的部分。
  • 从原基线测试用例库T中,排除所有不再适用的测试用例, 确定那些对新的软件版本依然有效的测试用例,其结果是建立⼀个新的基线测试用例库T0。
  • 依据⼀定的策略从T0中选择测试用例测试被修改的软件。
  • 如果必要,⽣成新的测试用例集T1,用于测试T0⽆法充分测试的软件部分。
  • 用T1执⾏修改后的软件。
  • 第(2)和第(3)步测试,验证修改是否破坏了现有的功能, 第(4)和第(5)步测试验证修改⼯作本身。

回归测试的话虽然有两部分工作,但是核心是2和3两步。是要验证修改的部分功能是不是损坏。

2)方法一

基于执行的轨迹和程序的这种执行的切片去分析:它这个方法本身它是一个基于程序的一个分析的方法:

  • 第一步:我们有一个原有的程序p,还有一个基线的测试用例集t,程序 p 是一个版本。然后我们原来有一个那个测试用例集,这个测试集原来对 p 进行了相应的测试,首先要找到程序p,对于每一个测试用例的执行轨迹(在程序里面)
  • 第二步:这样就可以构造一个测试的向量(向量是经过node的路径,比如经过了程序片1->程序片2->程序片3)
  • 第三步:构建一个语法树,每一个 node 对应着一个程序的一个程序片。我要比较看 p 和 p 撇的话,在语法树里面语义上是不是有修改
  • 第四步:遍历整个程序流图

具体举例子:

  • 首先要把程序的图画出来,下面的是代码

  • 画图出来之后:

  • 一般会给一些测试用例,我根据每个测试用例,画出对应测试用例在程序里面经过的路径
  • 然后可以得到一些向量。下图里面,main函数的节点1里面,有t1、t2、t3测试用例经过,g2函数里面的节点1,只有t2测试用例经过

  • 然后分析程序的改变。程序的改变的话,我们不能只看语序的改变,是吧?我们还要看这个,他的这个语法,是要辨别里面这种语义的改变的模块。
  • 对照上面的表格,如果发现修改了main.2,那么,我只需要跑一遍t1、t3的测试用例,就好了

3)方法二

基于测试的最小化。刚才那个是针对于我们的执行轨迹的分析来做的,假设原有的程序包含两个func,有main函数和f函数,p程序已经通过了t1、t2的测试用例

  • 在这个测试里面 T1 会执行什么?main函数,不执行f
  • T2的里面会执行f函数、main函数
  • p1如果只修改了f函数,那么我们测试的时候,T1就不需要执行了,只需要测试T2
  • 所以可以看出是按照函数作为单位,来测试的。

test 最小化的话,它是有一个覆盖率的概念,就是说可测实体的覆盖率概念。当然我还可以其他的实体,比如判断的语句,可以当为实体(一段代码,一段定义使用路径等等都可以)

总结方法:

  • 选择可以测的实体(函数,等等)
  • 把可测的实体转化为单位
  • 用上面的方法一然后来测试(只需辨别每个测试用例经过了那些可测实体)

4)方法三

基于优先级测试。类似于我们前面所讲的按照风险抛面。比如说优先级高的是不是操作频繁的。把测试变成优先级,按照优先级进行测试。

  • 首先也有一些测试的实体
  • 如果说,你测试实体就是function,把这些测试实体做过优先级排序,然后这个排序的话就说他还是有一些依据的
  • 排序之后就选择,选择取决于项目组自己测试

三、回归测试的总结

  • 第一个回归测试一定是放在软件整个生活周期去做的,
  • 回归测试的话,它的核心不是设计新的测试用例,它是选择测试用例。就是说我有测试用例了以后,我回归测试里面我选哪些去做,是吧?当然选最少的