前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >变异测试

变异测试

作者头像
顾翔
发布2022-05-22 10:11:39
6770
发布2022-05-22 10:11:39
举报

变异测试在1970年被一个学生DickLipton提出,首次发现和公之于众。变异测试最初是为了定位揭示测试单元的弱点。这个理论是:如果一个边缘被引入,同时出现的行为(通常是输出)不受影响的情况下,那么这说明了:变异代码从没有被执行过(产生了过剩代码)或者测试单元无法定位错误。

1. 基本概念

变异测试是指如果代码中,对一个小的操作进行一点改动(比如“+”改为“-”),测试用例在完整的情况下就可以发现程序被改动,而报错。首先我们来了解下等价变体的概念。

源代码如下:

代码语言:javascript
复制
for(int i=0;i<10; i++){ // 源程序
  //To-do ...
}

变体1如下:

代码语言:javascript
复制
for(int i=0;i!=10; i++){ //变体1
  //To-do ...
}

变体2如下:

代码语言:javascript
复制
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. 6个概念

在变异测试中需要关注以下六点

1)变异算子

1987年,针对Fortran 77语言定义了22个变异算子,而在下面我们介绍的Mutpy中定义了以下27个变异体。

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

2)一阶变异体

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的高阶变异

4)可删除变异体

如果测试用例测试源代码和测试编译代码不一致,则这个测试用例可以删除

5)可存活变异体

如果测试用例测试源代码和测试编译代码不一致,则这个测试用例不可以删除

6)等价变异体

变异体与源代码语法不同,语义相同,则为等价变异体

3 测试方法

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

3. 工具

在变异测试中Java常用的工具为PITest,Python常用的工具为Mutpy,现在我们来学习一下Mutpy。

1)安装

在线安装

代码语言:javascript
复制
#pip install mutpy

离线安装

代码语言:javascript
复制
#git clone  git@github.com:mutpy/mutpy.git
#cd mutpy/
#python setup.py install

2)被测程序:calculator.py

代码语言:javascript
复制
def mul(x, y):
    return x * y

3)测试程序:test_calculator.py

代码语言:javascript
复制
from unittestimport TestCase
from calculatorimport mul
 
classCalculatorTest(TestCase):
    def test_mul(self):
        self.assertEqual(mul(2, 2), 4)

4)运行

代码语言:javascript
复制
root@ubuntu:/home/jerry/muttest#  mut.py --target calculator --unit-test test_calculator -m

[*] Start mutation process:

   - targets: calculator

   - tests: test_calculator

[*] 1 tests passed:

   - test_calculator [0.00040 s]

[*] Start mutants generation and  execution:

   - [#    1] AOR calculator:

--------------------------------------------------------------------------------

   1: def mul(x, y):

- 2:     return x * y

+ 2:     return x / y

--------------------------------------------------------------------------------

[0.01345 s] killed by test_mul  (test_calculator.CalculatorTest)

   - [#    2] AOR calculator:

--------------------------------------------------------------------------------

   1: def mul(x, y):

- 2:     return x * y

+ 2:     return x // y

--------------------------------------------------------------------------------

[0.01476 s] killed by test_mul  (test_calculator.CalculatorTest)

   - [#    3] AOR calculator:

--------------------------------------------------------------------------------

   1: def mul(x, y):

- 2:     return x * y

+ 2:     return x ** y

--------------------------------------------------------------------------------

[0.01048 s] survived

[*] Mutation score [0.11673 s]: 66.7%

   - all: 3

   - killed: 2 (66.7%)

   - survived: 1 (33.3%)

   - incompetent: 0 (0.0%)

   - timeout: 0 (0.0%)

You have new mail in  /var/mail/root

注:我在Win10下测试没有成功,在Linux下测试成功。

各位可以看到3个变异,存活了1个,杀死了22个,最后得分为66.7%。分析一下原因。

这里对于x * y的3个变异,分别为x / y ,x // y和x ** y。

在测试用例中x=2,y=2 ,测试结果为4 返回 True;

在变异x / y,测试结果为1 返回 False;

在变异x // y,测试结果为1 返回 False;

在变异x ** y,测试结果为2 返回 True。

所以当x=2,y=2变异x ** y是与源代码等价的。我们修改一下测试代码。

test_calculator.py

代码语言:javascript
复制
from unittestimport TestCase
from calculatorimport mul
 
classCalculatorTest(TestCase):
    def test_mul(self):
        self.assertEqual(mul(2, 3), 6)

分析一下:

源代码:2 * 3 = 6,返回True

对于x / y:2/3!= 6,False;

对于x // y:2//3 =0!= 6,False;

对于x ** y:2**3=8!= 6,False。

所以三个都被杀死了,得分为100%。

运行一下。

代码语言:javascript
复制
root@ubuntu:/home/jerry/muttest#  mut.py --target calculator --unit-test test_calculator -m

[*] Start mutation  process:

   - targets: calculator

   - tests: test_calculator

[*] 1 tests passed:

   - test_calculator [0.00050 s]

[*] Start mutants  generation and execution:

   - [#    1] AOR calculator:

--------------------------------------------------------------------------------

  1: def mul(x, y):

- 2:     return x * y

+ 2:     return x / y

--------------------------------------------------------------------------------

[0.05670 s] killed by  test_mul (test_calculator.CalculatorTest)

   - [#    2] AOR calculator:

--------------------------------------------------------------------------------

  1: def mul(x, y):

- 2:     return x * y

+ 2:     return x // y

--------------------------------------------------------------------------------

[0.03214 s] killed by  test_mul (test_calculator.CalculatorTest)

   -  [#   3] AOR calculator:

--------------------------------------------------------------------------------

  1: def mul(x, y):

- 2:     return x * y

+ 2:     return x ** y

--------------------------------------------------------------------------------

[0.04315 s] killed by  test_mul (test_calculator.CalculatorTest)

[*] Mutation score  [0.20079 s]: 100.0%

   - all: 3

   - killed: 3 (100.0%)

   - survived: 0 (0.0%)

   - incompetent: 0 (0.0%)

   - timeout: 0 (0.0%)

得分果然是100%

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 软件测试培训 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档