变异测试

简介: 变异测试

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


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与源代码是等价的:i0开始,经历2,3,4,5,6,7,8,910,在源代码中由于10<10返回False,退出循环;在变体1中由于10!=10返回False,退出循环。而变体2与源代码是非等价的:i0开始,经历-1-2-3…永远达不到i<10False的情形。


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(交换breakcontinue语句)
  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

BA的一阶变异,CB的一阶变异,DA的高阶变异


4)可删除变异体


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


5)可存活变异体


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


6)等价变异体


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


3 测试方法


image.png


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


3. 工具


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


1)安装


在线安装

#pip install mutpy


离线安装

#git clone  git@github.com:mutpy/mutpy.git

#cd mutpy/

#python setup.py install


2)被测程序:calculator.py

def mul(x, y):
    return x * y


3)测试程序:test_calculator.py

from unittestimport TestCase
from calculatorimport mul
classCalculatorTest(TestCase):
    def test_mul(self):
        self.assertEqual(mul(2, 2), 4)


4)运行


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 * y3个变异,分别为x / y ,x // yx ** y

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

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

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

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

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

test_calculator.py

from unittestimport TestCase
from calculatorimport mul
classCalculatorTest(TestCase):
    def test_mul(self):
        self.assertEqual(mul(2, 3), 6)


分析一下:

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

对于x / y2/3!= 6False

对于x // y2//3 =0!= 6False

对于x ** y2**3=8!= 6False

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

运行一下。


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%

目录
相关文章
|
12月前
|
机器学习/深度学习 算法 测试技术
【网安专题10.25】10 TitanFuzz完全自动化执行基于变异的模糊测试:生成式(如Codex)生成种子程序,逐步提示工程+第一个应用LLM填充模型(如InCoder)+差分测试
【网安专题10.25】10 TitanFuzz完全自动化执行基于变异的模糊测试:生成式(如Codex)生成种子程序,逐步提示工程+第一个应用LLM填充模型(如InCoder)+差分测试
214 0
|
25天前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
46 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
2月前
|
移动开发 JSON Java
Jmeter实现WebSocket协议的接口测试方法
WebSocket协议是HTML5的一种新协议,实现了浏览器与服务器之间的全双工通信。通过简单的握手动作,双方可直接传输数据。其优势包括极小的头部开销和服务器推送功能。使用JMeter进行WebSocket接口和性能测试时,需安装特定插件并配置相关参数,如服务器地址、端口号等,还可通过CSV文件实现参数化,以满足不同测试需求。
209 7
Jmeter实现WebSocket协议的接口测试方法
|
2月前
|
JSON 移动开发 监控
快速上手|HTTP 接口功能自动化测试
HTTP接口功能测试对于确保Web应用和H5应用的数据正确性至关重要。这类测试主要针对后台HTTP接口,通过构造不同参数输入值并获取JSON格式的输出结果来进行验证。HTTP协议基于TCP连接,包括请求与响应模式。请求由请求行、消息报头和请求正文组成,响应则包含状态行、消息报头及响应正文。常用的请求方法有GET、POST等,而响应状态码如2xx代表成功。测试过程使用Python语言和pycurl模块调用接口,并通过断言机制比对实际与预期结果,确保功能正确性。
223 3
快速上手|HTTP 接口功能自动化测试
|
1月前
|
JavaScript 前端开发 API
vue尚品汇商城项目-day02【9.Home组件拆分+10.postman测试接口】
vue尚品汇商城项目-day02【9.Home组件拆分+10.postman测试接口】
38 0
|
2月前
|
JavaScript 前端开发 测试技术
ChatGPT与接口测试
ChatGPT与接口测试,测试通过
43 5
|
3月前
|
网络协议 测试技术 网络安全
Python进行Socket接口测试的实现
在现代软件开发中,网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯,都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中,Socket(套接字)技术扮演了重要角色。 Socket 允许计算机上的程序通过网络进行通信,它是网络通信的基础。Python 提供了强大且易于使用的 socket 模块,使开发者能够轻松地创建客户端和服务器应用,实现数据传输和交互。 本文将深入探讨如何利用 Python 编程语言来进行 Socket 接口测试。我们将从基础概念开始介绍,逐步引导大家掌握创建、测试和优化 socket 接口的关键技能。希望本文可以给大家的工作带来一些帮助~
|
4月前
|
存储
Postman 接口测试配置 Pre-request Script
Postman 接口测试配置 Pre-request Script
196 5
Postman 接口测试配置 Pre-request Script
|
3月前
|
网络协议 测试技术 网络安全
Python进行Socket接口测试的实现
在现代软件开发中,网络通信是不可或缺的一部分。无论是传输数据、获取信息还是实现实时通讯,都离不开可靠的网络连接和有效的数据交换机制。而在网络编程的基础中,Socket(套接字)技术扮演了重要角色。 Socket 允许计算机上的程序通过网络进行通信,它是网络通信的基础。Python 提供了强大且易于使用的 socket 模块,使开发者能够轻松地创建客户端和服务器应用,实现数据传输和交互。 本文将深入探讨如何利用 Python 编程语言来进行 Socket 接口测试。我们将从基础概念开始介绍,逐步引导大家掌握创建、测试和优化 socket 接口的关键技能。希望本文可以给大家的工作带来一些帮助~
|
3月前
|
SQL Java 测试技术
SpringBoot单元测试快速写法问题之PorkService 接口中的 getPork 方法的作用如何解决
SpringBoot单元测试快速写法问题之PorkService 接口中的 getPork 方法的作用如何解决