什么是变异测试?

变异测试 是一种基于错误注入的测试方式,具体来讲就是人为在代码中注入错误,然后来观察现有的测试用例是否能够发现这些错误,如果能够发现说明测试用例是有效的,如果不能发现说明测试用例需要进一步完善和补充。

变异测试起源

变异测试在1970年被一个学生DickLipton提出,首次发现和公之于众,之后在1980年就已经出现了第一个变异测试的工具。

在学术界变异测试的研究已经持续了很长时间,研究的焦点主要集中在变异算法优化以及等价变异体分析上。

但是在工业界对变异测试的关注度一直很低,甚至很多测试技术人员压根不知道什么是变异测试,这背后的原因主要是因为 变异测试需要在单元测试已经做得比较完备的基础上才有其价值

实施变异测试的步骤

什么是变异测试?

首选我们有被测源代码(P),以及对应的测试用例代码,随后在被测源代码P上,用变异算子(S)生成变异体源代码(P'),这个过程称为变异体生成。用人话来讲其实就是对被测源代码进行“合乎语法的微小改动”,这种微小改动就是所谓的变异算子,比如原本是“加法”运算现在改成“乘法”运算,或者原本是“逻辑与”运算现在改成“逻辑或”运算,之后分别使用相同的测试用例T对被测源代码P和变异体源代码P'执行测试,最后比较测试执行结果。

  • 如果两次测试结果都是通过的,说明变异注入的错误并不能被测试用例T感知,这种情况称为变异体能够“存活”,说明测试用例T的有效性存在问题,需要对测试用例进行补充和修正。
  • 如果两次测试结果不同,暨在被测源代码P上执行测试通过,在变异体源代码P'上执行测试不通过,说明变异注入的错误能够被测试用例T感知到,测试用例T能够“杀死”此次变异,测试用例的有效性在此类变异上没有问题。

变异测试的几个概念

1、首先我们来了解下等价变体的概念:

源代码如下:

for(int i=0;i<10; i++){ // 源程序
  //To-do ...
}

变体1如下:

for(int i=0;i!=10; i++){ //变体1
  //To-do ...
}

变体2如下:

for(int i=0;i<10; i--){ //变体2
  //To-do ...
}

由此可见变体1与源代码是等价的:i从0开始,经历2,3,4,5,6,7,8,9到10,在源代码中由于10<10返回False,退出循环;在变体1中由于10!=10返回False,退出循环。而变体2与源代码是非等价的:i从0开始,经历-1,-2,-3…永远达不到i<10为False的情形。

2、变异算子

对被测源代码进行“合乎语法的微小改动”,这种微小改动就是所谓的变异算子。Mutpy 中定义了以下27个变异体。

  • AOD - arithmetic operatordeletion(删除算术运算符)
  • AOR - arithmetic operatorreplacement(替换算术运算符)
  • ASR - assignment operatorreplacement(替换赋值运算符)
  • BCR - break continuereplacement(交换break和continue语句)
  • COD - conditional operatordeletion(删除条件运算符)
  • COI - conditional operatorinsertion(插入条件运算符)
  • CRP - constant replacement(替换常量)
  • DDL - decorator deletion(替换修饰符)
  • EHD - exception handlerdeletion(删除异常处理)
  • EXS - exception swallowing(吞咽异常)
  • IHD - hiding variable deletion(删除隐藏变量)
  • IOD - overriding methoddeletion(删除覆盖方法)
  • IOP - overridden method callingposition change(重写调用位置更改的方法)
  • LCR - logical connectorreplacement(更换逻辑连接器)
  • LOD - logical operator deletion(删除逻辑运算符)
  • LOR - logical operatorreplacement(替换逻辑运算符)
  • ROR - relational operatorreplacement(替换关系运算符)
  • SCD - super calling deletion(删除超级调用)
  • SCI - super calling insert(插入超级调用)
  • SIR - slice index remove(移除切片索引)
  • CDI – class method decoratorinsertion(插入类方法装饰器)
  • OIL - one iteration loop(一个迭代循环)
  • RIL - reverse iteration loop(反向迭代循环)
  • SDI – static method decoratorinsertion(插入静态方法装饰器)
  • SDL - statement deletion(删除语句)
  • SVD - self variable deletion(删除自变量)
  • ZIL - zero iteration loop(零迭代循环)

3、一阶变异体 和 高阶变异体

看下面代码

[A] z = x * y
[B] z = x / y
[C] z = x/y*2
[D] z =4x/y*2

B是A的一阶变异,C是B的一阶变异,D是A的高阶变异。

测试方法

什么是变异测试?

如果这个过程中,有减分,说明测试用例不完善或者出现重复的测试用例。

测试工具

在变异测试中Java常用的工具为 PITest,Python常用的工具为 Mutpy。



我的回答