一、变异测试的目的
变异测试是一种软件测试技术,用于评估测试用例的有效性。其核心思想是通过在源代码中引入人为的缺陷(称为“变异”),然后运行测试用例,检查这些变异是否被检测到。如果测试用例能够发现这些变异,说明它们有效;否则,测试用例可能需要改进。
二、变异测试的步骤
- 生成原始程序:首先需要一个正确的程序版本。
- 创建变异体:通过修改源代码生成多个变异体,每个变异体包含一个小的人为错误。
- 运行测试用例:对原始程序和所有变异体执行相同的测试用例。
- 比较结果:如果某个变异体在测试中失败(即被“杀死”),说明测试用例有效;如果通过(即“存活”),则测试用例可能不够充分。
- 分析结果:根据变异体的存活率评估测试用例的质量。
三、变异测试的举例
假设有一个简单的Python函数,用于计算两个数的和:- def add(a, b):
- return a + b
复制代码 生成变异体
我们可以通过修改代码生成多个变异体,例如:
变异体1:将+改为-- def add(a, b):
- return a - b
复制代码 变异体2:将+改为*- def add(a, b):
- return a * b
复制代码 变异体3:将+改为/- def add(a, b):
- return a / b
复制代码 运行测试用例
假设我们有以下测试用例:- def test_add():
- assert add(2, 3) == 5
- assert add(-1, 1) == 0
- assert add(0, 0) == 0
复制代码 比较结果
原始程序:所有测试用例通过。
变异体1:add(2, 3)返回-1,测试失败,变异体被“杀死”。
变异体2:add(2, 3)返回6,测试失败,变异体被“杀死”。
变异体3:add(2, 3)返回0.666...,测试失败,变异体被“杀死”。
在这个例子中,所有变异体都被测试用例发现,说明测试用例有效。
因为测试失败,所以说明之前的用例有效,被测代码有改动(有变异)。在未修改源代码之前,测试用例理论上是可以通过;现在修改代码(有变异)后,按照逻辑,原本的测试用例就通不过了;若还能通过,则说明有极大可能性的测试用例无效,须补充完善。
四、常见的变异类型
基于变异测试,我们对测试用例有效性的定义是: 有效性=发现的变异数量÷注入的变异总数
从原理上讲,代码变异主要分为以下三类:
- 第一类可以称为等效变异。例如,把a+b变成a-(-b)。这种变异我们不做,因为它不是一个bug。
- 第二类可以称为实际等效变异。例如,把int类型变成short类型,理论上会有溢出的问题。一般情况下,大家很少用short类型,只要是整数就直接用int类型,但值的范围无论如何都不会超过几十或者几百。比如,变量numberOfDays的值是天数(number of days),这种变异我们也不做。
- 第三类变异为运算符类的变异。几乎都是bug,很清楚,没有争议。我们主要做的就是这类变异。
[table][tr][td]变异类型[/td][td]例子[/td][/tr][tr][td]算数运算符[/td][td]+改成-,++改成--[/td][/tr][tr][td]关系运算符[/td][td]!=改成==,>改成 |