突变测试涉及以较小的方式修改程序的源代码或字节
代码。不能检测并拒绝
突变代码的测试套件被认为是有缺陷的。
在极端情况下,它将在您的测试中检测到无用的断言
1==1
:-)有一些用于执行变异测试的工具(使用Java和其他编程语言),其中一些与xUnit框架很好地集成在一起。但是,配置这些工具并解释其结果对我而言似乎很耗时,并且这些工具可能会返回许多必须手动滤除的假阴性(称为等效突变体)。因此,我很好奇是否值得花更多的时间来学习该技术。
您发现这些工具或总体上的突变测试对改进测试有用吗?
在突变测试中您发现了哪些缺陷?
/>
我已经阅读了一些使用此技术的动手经验,但没有详细说明在实际测试用例中发现了哪些缺陷以及它们有多严重。
#1 楼
我是其中一种Java工具(http://pitest.org)的作者。我发现突变测试在实践中很有用,可以处理大型遗留公司代码库和较小的测试驱动程序项目。
我已经看到很多对变异测试价值的不屑一顾,例如Bj Rollison的答案。我通常不同意他提出的观点,但是对如何/应该使用突变测试做出了一些隐含的假设。
在测试中进行突变测试很有用(以我的经验)以下方式
1。从一个中小型项目开始。
在这种情况下,变异测试在您编写代码时为您提供支持。您可以现实地争取获得较高的突变得分。
突变测试将突出您的测试套件中的空白(我一直看到的示例是针对交互的测试,这些测试不检查方法是否实际返回了它们的值。旨在计算,未经检查的边界以及很多您未遵循声称要遵循的TDD流程的实例,因为您可以取出方法调用而不会导致测试失败。
尚存的变异将导致您执行以下三项操作之一
a)编写新测试
b)删除一些代码
c)重写一些代码
结果通常是b)或c)。
b)是不言自明的-您可以删除一些无用的代码,c)不那么明显,并且与等效的突变有关。我发现,经常可以将突变为等效突变的代码可以更好地表达为无法突变为等效突变的代码。结果通常更易于理解和维护。
某些等价突变将始终存在,但是-通常是由于代码中的性能问题引起的。
构成中小型项目的定义有些棘手-但要足够小,以至于在足够短的时间内完成分析,可以作为编码反馈循环的一部分被接受。幸运的是,近年来,突变测试工具的性能得到了提高。 (有关原因/方式的一些讨论,请参见http://pitest.org/java_mutation_testing_systems/)。
2。为了在现有的大型代码库中支持新开发
与上面相同,但分析仅限于新代码。它既可以在开发时使用,也可以在成对审阅中使用,等等。它可以发现测试套件之间的差距,但也可以引起一些有关代码的有用讨论。
3。为了支持在现有的较大代码库中对现有代码进行更改,
在这种情况下,会挑选感兴趣的代码库中的一部分进行分析-通常是为了支持重构。
和以前一样,您最终可能会添加测试,但可能不会被删除或重写代码,因为无论如何它都可能会被替换。一旦对所有尚存的突变进行了调查,您就可以准确地理解重构所涉及的风险。
大多数人似乎认为应该使用突变测试。
4。尝试为现有项目获得100%/ 85%/ 75%的突变得分
我从未尝试过,也不会期望它会带来多少价值。
如果代码库很大,则分析时间将很长,并且尚存的突变数可能会很高。尝试评估每个人都非常耗时(javalanche旨在在这个领域提供一些帮助-尽管我自己没有尝试过
,但收集它会带来很高的性能成本)。
变异测试也许仍然可以用来评估现有套件的整体质量。可以从尚存的突变中随机抽取一个样本,并对每个样本进行评估,以查看其是否等效-然后可以用来确定可能存在的对应于测试套件缺陷的尚存突变数。但是,这不是我尝试过的事情。
评论
您是否在实际项目中尝试过Pitest?您需要花费多少时间调查幸存的突变?您发现的缺陷有多严重?
– dzieciou
2012年11月26日15:14
是的,如上所述有几个实际项目。变异测试的主要目的不是发现缺陷,而是评估测试套件的质量。我发现许多测试套件的缺陷与突变测试和许多不必要的代码。但是,我通过突变测试发现了一些缺陷-主要是错误的条件边界。
–亨利
2012年11月26日15:20
评估尚存的突变需要花费多少时间。 。 。很难说。这通常是正常开发过程的一部分,没有单独衡量。这就是我试图驾车回家的重点,因为在事实质量评估阶段将变得困难之后再应用它。我取得成功的地方一直是开发过程的一部分。
–亨利
2012年11月26日15:29
感谢您的回答,这无疑为我提供了一些有关突变测试的新信息和新见解。
–山姆·伍兹(Sam Woods)
2012年11月26日在18:18
亨利,您提出了一些非常好的论据,赞成使用变异测试来测试私有构建中的单元测试的有效性。我是从更高级别的角度对组件的集成测试和系统级别的测试进行发言的,应该对此进行澄清。
– Bj Rollison
2012年11月27日,2:15
#2 楼
从学术角度来看,变异测试通常很有趣。我从未见过或听说有人在按计划交付给客户的软件上使用突变测试。与返回的感知值相比,进行变异测试所花费的时间和金钱是巨大的。在复杂的项目中,有几个开发人员参与了产品突变测试,即使是很小的组件也可能阻止连续的集成周期。通常,为了提高测试用例的有效性(假设您遇到无效的测试用例的问题),突变测试可能是最昂贵的解决方案之一。突变测试可能对培训有用,或规模较小,参与者有限且没有时间表的项目,但通常比只翻转一点并分析测试子集的结果要复杂得多。
此外,错误的假设是,oracle(人工或自动)将检测所有故障。自动化的oracle只能检测经过编程检查的问题。
评论
因此,看起来使用传统的测试设计技术来覆盖值/状态的重要分区将更好地改善测试质量。
– dzieciou
2012年11月25日22:24
不清楚由突变产生的错误的种类是否代表开发人员将要创造的错误。
–user246
2012年11月26日下午1:55
@ User246这与设置静态分析工具(例如FindBugs)不同吗?许多程序员会犯导致NullPointException的错误,因此您将FindBugs设置为对此敏感。同样,对于突变测试,您可以打开具有代表性的突变类型(如果现在可以清楚地知道其中的哪种类型...)
– dzieciou
2012年11月26日6:49
#3 楼
突变测试已在某些小型系统中使用,例如:请参阅文章“在安全关键软件中确定测试充分性的直观方法”。这是摘要:安全关键软件必须遵守严格的质量标准
,并且必须经过全面测试。但是,对软件进行详尽的测试通常是不切实际的。
软件测试团队面临的两个主要挑战是有效测试用例的生成和测试充分性的证明。
本文提出了一种直观而保守的方法来确定测试安全关键软件的充分性。通过案例研究证明了该方法:核反应堆的堆芯温度监测系统。我们结合了独特的执行路径测试用例的保守测试
覆盖率和突变测试的结果来确定测试的充分性。虽然突变测试是一种强大的技术,但困难在于
增强对计算出的测试的信心:
必须在所有可能的代码执行路径上诱发突变测试期间的错误,必须研究未杀死的突变体的特性,并且
必须检测所有等效的突变体。
这方面;
给出了突变体的静态,动态和覆盖率分析结果,
提出了一种鉴定可能等效的突变体的技术。
评论
欢迎使用SQAT.SE-您能提供执行摘要吗?在SE环境中,指向文章的链接(尤其是“付费”)不是很有帮助...
–安德鲁(Andrew)
2012年11月30日6:28
评论
我找到了以下使用突变测试的示例。如果满足特定条件,我们有方法foo()会在对象X上调用方法bar()。在测试中,我们检查对象X的模拟是否在满足条件时发生了交互,但没有检查在不满足条件时是否没有这种交互。当测试仍为绿色时,突变体将删除“ if”语句(或其中的反向条件)。这建议遵循两个选项:(a)要么“如果”语句是不必要的,要么(b)可以添加新的检查交互性的测试。