发表于 | Testing Concepts, Types of testing | 最后更新:“2016年10月20日”
Sci-Fi(科幻小说)的支持者:你不要抱有希望,这不是那种我们正在讨论的突变 :)
什么是突变测试?
突变测试是一种基于故障的测试技术,这种技术让软件程序的变量都受限于测试数据集。这样做是为了确定测试集在隔离偏差方面的有效性。
这听起来有一些复杂,不是吗?
让我们从一个示例学习:
这样说吧,现在有一个可以让新用户注册的医院网站。它要读取病人的生日或者年龄。如果病人大于14岁,就会分配一个普通医师作为他们的主要医生。为了实现这个,将会调用那个可以查找这类医生的“普通医师”函数。
现在,可能还有其他的功能。或许,13岁以下的病人会分配到一个儿科医生那里,如此类推。但是我们将只会讲大于14岁的例子。
代码可能像下面那样写:
1) Read Age
2) If age>14
3) Doctor= General Physician()
4) End if
请注意以上代码不适用于任何编程语言,也不能运行。这只是假设。
作为一个测试人员,假设我的数据集是14,15,0,13——一些随机数字。
目标就是要检查数据集那4个数值(14,15,0和13)是否能通过这些代码足以能识别所有可能出现的问题。
也可以阅读 => Tips to design test data before executing your test cases (在执行你的测试用例前设计测试数据的建议)
突变测试怎样完成这样的任务?
首先,你要创建程序的突变体-变量(mutants- variations)。一个突变体(mutant)不是什么就是一个写成有偏差的程序。它包括一个self-seeded缺陷。
例子如下:
- Arithmetic operator replacement
- Logical connector replacement
- Statement removal
- Relational operator replacement
- Absolute value insertion, etc.
这些替代品也叫做“Mutation Operators”。
让我给你展示一些例子:
Mutant #1: Relational operator replacement
1) Read Age
2) If age<14 ‘Changing the > with <’
3) Doctor= General Physician()
4) End if
Mutant #2:
1) Read Age
2) If age=14 ‘Changing the > with =’
3) Doctor= General Physician()
4) End if
Mutant #3:
1) Read Age
2) If age>=14 ‘Changing the > with >=’
3) Doctor= General Physician()
4) End if
Mutant #4:
1) Read Age
2) If age<=14 ‘Changing the > with <=’
3) Doctor= General Physician()
4) End if
Mutant #5: Statement Removal
1) Read Age
2) If age=14
3) ‘remove the doctor assignment statement’
4) End if
Mutant #6: Absolute Value Insertion
1) Read Age
2) If age>14
3) Doctor= Mr.X (Absolute value insertion- let’s say X is a pediatrician)
4) End if
Mutant #7: Incorrect syntax
1) Read Age
2) If age%%14 (incorrect syntax)
3) Doctor=General Physician()
4) End if
Mutant #8: Does the same thing as the original test
------------
1) Read Age
2) If age> 14 & age>14 ‘means the same thing as age>14’
3) Doctor= General Physician()
4) End if
一旦所有突变体都被创建出来,它们就会受测试数据集支配。我们的数据集是14、15、0和13。我们的数据集将会发现这些突变体中的哪个?
从下面表格中找出来:
你可以看到我们的数据里数值14当和突变体2、3和4配对在一起的时候就失败了。或者说14干掉了突变体2、3和4。但是,1、6和8这样的突变体就没有这样的效果。
如果你的数据集干掉了所有的突变体,它就是有效的。否则,就包括更多和更好的测试数据。不是每个在数据集里的数值都必须干掉所有突变体。但综合在一起,他们就应该要干掉所有的(突变体)。例如:14干掉2、3和4,15干掉1、2和4,如此类推。
5、7和8是什么?
Mutant #5 – 就是那种与你提供的任何数据值都无关,都会失败的程序实例。这是因为对于有效和无效的值它都不会做任何编程。
Mutant #7 – 将会是一个编译错误。或许对于脚本语言来说这是一个阻止执行的错误。
Mutant #8 – 像主程序一样的东西。
正如你所看到的,上面的突变体一点用处都没有。
因此,突变体要避免:
- 语法错误/“Still-Born”突变体:你只需要语法正确的突变体。例子:Mutant 7
- 等效突变体:那些像原始程序那样做完全相同的事情的突变体。例子:Mutant 8
- 琐碎突变:可以被任何数据集杀死。例子:Mutant 5
注意要点:
- 突变体的数量,即使对于小程序来说,也可以很多。虽然是一个有限的数字,但是还是很大。正以为这样,突变体的一个子集经常会被使用。随机地选择突变体是很常见的。
- 上面列出的变异算子不是一个详尽的列表,也可以有许多其他的变化。我简单化了这些概念以便于容易理解。
- 变异算子也与应用程序的编程语言、设计和规格说明不一样。
- 如果在测试的最后阶段还有一些突变体存在,这意味着它可能是一个无效的突变体(像5、7和8)也可能是数据集不合适。如果是后者,返回以及改变数据集。
- 突变体测试是一个结构化的、白盒和单元测试方法。它用fault-injection或者fault-seeding来产生它的突变体。
- 有很多适用于自动化测试的单元测试框架和工具,有以下类型:
- Jester for JUnit
- Pester for Python
- MuClipse for eclipse,等等
你想,如果需要这么多的努力,当我要测试大量代码时将会发生什么?
突变体测试依赖于两样东西:
- 有能力的程序员设想:如果一个程序员有足够的能力编写和测试一小段代码,他也会擅长编写更大的程序。
- 耦合效应的设想:如果2个单元结合起来形成一个程序,每一个单元本身又是很好的,那么这个组合也将会很好。
所以,侧重点在于最小的单元代码和信赖于程序员将突变体测试规模变成更大的程序的技能。
总结:
我希望你可以喜欢阅读和学习一种有趣的测试技术——突变测试。
关于作者:这篇文章是STH团队成员Swati S所写。
【英文原文:http://www.softwaretestinghelp.com/what-is-mutation-testing/】
{测试窝原创译文,译者:梁仲兴}
译者简介:梁仲兴,专注于云计算、自动化、网络运维领域的工作者。