什么是突变测试?

最近,我反复提到“ 突变测试 ”一词。 因为可以说这种方法能够以超出代码覆盖范围的方式检测测试安全网的空白,所以我花了一些时间来追赶这个话题,然后尝试一下。 这篇文章总结了我的发现,作为对该主题的快速介绍。

什么是变异测试?

变异测试评估现有软件测试的质量。 想法是以较小的方式修改(变异)测试所覆盖的代码,并检查现有测试集是否将检测并拒绝更改[MUTTES]。 如果不符合,则意味着测试不符合代码的复杂性,并且未测试其一个或多个方面。

在Java中,将变量视为与原始代码相比具有单个修改的附加类。 可能是如下所示的if子句中逻辑运算符的更改。

if( a && b ) {...} => if( a || b ) {...}

通过现有测试检测并拒绝这种修饰称为杀死突变体。 当然,有了完善的测试套件,没有任何类别的突变体能够生存。 但是创建所有可能的变体的成本很高,这就是为什么在现实世界中手动执行此方法不可行的原因。

幸运的是,有一些工具可以即时创建突变体,并针对每个突变体自动运行所有测试。 变异创建基于一组所谓的变异算子 ,这些变异算子可以揭示典型的编程错误。 在上面的示例中将采用的一个称为条件突变算子

使用JUnit进行测试

使用Junit书本测试 使用JUnit进行测试是Java开发人员可以学习的最有价值的技能之一。 无论您的背景是什么,无论您是只是想建立一个安全网以减少桌面应用程序的性能下降,还是要基于健壮且可重用的组件来提高服务器端的可靠性,都需要进行单元测试。

弗兰克(Frank)写了一本书,为使用JUnit进行测试的基本知识提供了深刻的切入点,并为您准备了与测试有关的日常工作挑战做好了准备。

学到更多…

它与代码覆盖率有何关系?

正如Martin Fowler所说的那样, “测试覆盖率是查找代码库中未经测试的部分的有用工具 ”。 这意味着覆盖率不佳表明测试套件的安全网中存在令人担忧的漏洞。 但是,仅覆盖范围就不能证明基础测试的质量! 得出的唯一合理结论是,显然没有发现斑点。

为了澄清这一点,例如,考虑一组测试,这些测试完全省略了验证阶段 。 尽管这样的捆绑包可能会实现完整的代码覆盖,但是从质量保证的角度来看,这显然是毫无用处的。 这就是突变测试起作用的地方。

测试套件杀死的突变体越多,生产代码的行为被良好构想并被可靠测试完全覆盖的机会就越大。 听起来诱人? 然后,让我们继续看一个例子,以了解实际应用。

如何使用?

我们从我从《 用JUnit测试》一书中借来的清单开始,然后针对实际上下文对其进行一些修改。 例如,可以将时间轴视为UI控件的模型组件,该控件可以按时间顺序显示列表条目,例如Twitter界面。 在此阶段,我们只关心状态变量fetchCount ,其初始值可以通过正整数来调整。

public class Timeline {static final int DEFAULT_FETCH_COUNT = 10;private int fetchCount;public Timeline() {fetchCount = DEFAULT_FETCH_COUNT;}public void setFetchCount( int fetchCount ) {if( fetchCount <= 0 ) {String msg = "Argument 'fetchCount' must be a positive value.";throw new IllegalArgumentException( msg );}this.fetchCount = fetchCount;}public int getFetchCount() {return fetchCount;}
}

虽然这里没有什么复杂的,但是我们对下面的测试用例感到放心(让我们使用JUnit内置的org.junit.Assert类的各种assert方法来进行验证,在这篇文章中使用了静态导入来简化内容) )。

public class TimelineTest {private Timeline timeline;@Beforepublic void setUp() {timeline = new Timeline();}@Testpublic void setFetchCount() {int expected = 5;timeline.setFetchCount( expected );int actual = timeline.getFetchCount();assertEquals( expected, actual );}@Test( expected = IllegalArgumentException.class )public void setFetchCountWithNonPositiveValue() {timeline.setFetchCount( 0 );}
}

确实,在使用EclEmma收集覆盖率数据的同时运行测试会产生完整的覆盖率报告,如下图所示。

时间线测试覆盖率

可能您已经检测到了弱点。 但是,让我们天真地玩,忽略地平线上的乌云,然后继续进行突变测试。 我们将PIT用于此目的,因为它似乎是该领域中最受欢迎和最活跃的工具。 其他可能性包括µJava和Jumble 。

PIT支持命令行执行 , Ant和Maven构建集成以及第三方产品的 IDE和报告集成。 有关各种使用方案的更多详细信息,请参阅相应的在线文档。

生成的针对特定项目的变异测试HTML报告包含程序包细分,并且可以深入到类级别。 下图显示了时间轴组件的类列表报告。 下面,同一报告在Eclipse IDE中显示为结构树。

幸存者的时间线变异

太震惊了! 我们对高覆盖率的信心是一种错觉。 如您所见,该报告列出了将哪些突变应用于哪一行。 同样,请记住,对于每个突变,将执行一个单独的测试运行,包括所有测试! 带绿色下划线的列表条目表示被杀死的突变体,而红色的表示幸存者。

仔细检查,很快就会知道我们错过了什么。 我们通过在测试用例中添加初始状态验证来解决此问题,如以下代码片段所示(请注意,静态导入Timeline.DEFAULT_FETCH_COUNT )。

public class TimelineTest {[...]@Testpublic void initialState() {assertEquals( DEFAULT_FETCH_COUNT, timeline.getFetchCount() );}[...]
}

就是这个! 现在,突变测试运行会杀死所有突变体。 下图显示了一份报告,其中列出了所有报告。

没有幸存者的时间线变异

很难相信为这么小的一类人创造的突变数量。 9个突变体,仅需22条指令! 这将我们引到本文的最后一部分。

缺点是什么?

上游覆盖率分析,动态创建突变体以及所有必要的测试运行都需要花费大量时间。 我将突变测试纳入了完整的时间轴示例应用程序的构建过程中,该应用程序包含一个包含约350个测试的套件。 与常规运行相比,这将执行时间增加了四倍。

有了这些数字,很明显,出于实际原因,变异测试运行不能像单元测试运行那样频繁地执行。 因此,找到合适的工作流程以在早期反馈和效率方面提供最佳折衷是很重要的。 对于大型软件系统,这可能意味着突变测试运行可能更好地限于夜间构建等。

现场测试中出现了另一个问题,表明PIT可能会遇到基础技术堆栈[STAPIT]的麻烦。 就我而言,似乎不支持用于基于枚举的参数化测试的Burst JUnit 测试运行器 。 因此,特定类别的所有突变都可以幸免。 但是手动复制证明了这些结果是错误的。 因此,您要么不用麻烦的技术,要么将PIT配置为排除麻烦的测试用例。

摘要

这篇文章简要介绍了突变测试。 我们已经了解了什么是测试突变体,突变体的杀死率如何说明现有测试套件的质量,以及该测试技术与代码覆盖率之间的关系。 此外,我们已经了解了如何使用该领域最受欢迎的工具PIT,并对一些执行报告进行了评估。 考虑到从现场测试中得出的一些缺点,得出了本主题的结论。

总之,变异测试似乎是对基于自动化测试的质量保证工具集的有趣补充。 正如开头提到的那样,我对这个话题还很陌生,因此,从更高级的用户那里得知他们可能错过或遗忘的经验和方面会很有趣。

参考文献

  • [MUTTES]:突变测试,维基百科, https ://en.wikipedia.org/wiki/Mutation_testing
  • [STAPIT]:JUnit测试通过了,但是…,Stackoverflow, http ://stackoverflow.com/questions/30789480/
  • [TESCOV]:TestCoverage,Fowler, http ://martinfowler.com/bliki/TestCoverage.html

翻译自: https://www.javacodegeeks.com/2015/10/what-the-heck-is-mutation-testing.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript数组常用的方法总结

导读&#xff1a;在实际开发中&#xff0c;前端工程师除了写页面布局及样式还要对后端返回的数据进行处理&#xff0c;返回的数据大多数是json格式&#xff0c;一般都是返回一个对象或者数组&#xff0c;下面对常用的数组的使用方法进行总结&#xff0c;方便在开发中手到擒来&a…

Python黑魔法,一行实现并行化

Python 在程序并行化方面多少有些声名狼藉。撇开技术上的问题&#xff0c;例如线程的实现和 GIL&#xff0c;我觉得错误的教学指导才是主要问题。常见的经典 Python 多线程、多进程教程多显得偏“重”。而且往往隔靴搔痒&#xff0c;没有深入探讨日常工作中最有用的内容。 传统…

javaScript对账号卡号进行脱敏处理

导读&#xff1a;一般8位以上账号&#xff0c;显示首尾各4位&#xff0c;中间固定用8位*代替&#xff1b;8位及以下账号&#xff0c;显示首尾各2位&#xff0c;中间固定用8位*代替。 这里简单处理一下16位及以上的账号&#xff0c;卡号&#xff0c;其它的情况同理&#xff0c; …

2. python 参数个数可变的函数

如果想要定义一个参数个数不确定的函数&#xff0c; 可以通过*args,**kwargs实现&#xff1a; *args的使用&#xff1a; **kwargs的使用&#xff1a; 二者的混合使用&#xff1a; 另外还有一些关于调用函数时候的时候常用的技巧&#xff1a; 其和是等价的。 其和是等价的 当然也…

JavaScript常用工具类整理(总结版)

导读&#xff1a;在前端开发过程中需要对常用的功能模块进行封装&#xff0c;常用的方法多次调用需要整合&#xff0c;保证组件的复用性与程序的可维护性&#xff0c;这里总结一下&#xff0c;便于后续的使用&#xff01; 目录 1.全局声明工具类 2.定时器 3.判断变量是否是一…

axis2 json_带有Java和Axis2的JSON Web服务

axis2 json我最近遇到一位客户&#xff0c;要求我使用Java Web服务重建其旧产品。 他们希望它模块化并且易于使用。 我想到的第一件事是使用宁静的方法。 但是让我烦恼的是&#xff0c;Java宁静的方法是使用XML !&#xff0c;我更喜欢一种更简单的通信方式&#xff0c;易于理解…

如何对技术视频转换文章投稿进行二次创作

导读&#xff1a;在技术社区经常会收到一些大的平台&#xff08;华为云博客、infoq等平台的投稿任务&#xff09;&#xff0c;经过对数千篇通用技术稿件&#xff0c;积攒了一些小技巧。所以&#xff0c;在你创作之前还是要好好的看一下&#xff0c;希望对你有帮助&#xff01;看…

iOS开发-UIScrollView原理

转载:http://www.cnblogs.com/xiaofeixiang/p/5144256.html UIScrollView 在开发中是不可避免&#xff0c;关于UIScrollView都有自己一定的理解。滚动视图有两个需要理解的属性&#xff0c;frame和bounds&#xff0c;frame是定义了视 图在窗口的大小和位置&#xff0c;bounds表…

使用Spring MVC进行资源版本控制

提供静态资源时&#xff0c;通常的做法是将某种版本信息附加到资源URL。 这使浏览器可以无限期地缓存资源。 每当资源的内容更改时&#xff0c;URL中的版本信息也会更改。 更新的URL会强制客户端浏览器放弃缓存的资源&#xff0c;并从服务器重新加载最新的资源版本。 使用Spri…

边缘计算如何实现海量IoT数据就地处理

1.什么是IoT边缘&#xff1f;Gartner数据显示&#xff0c;到2021年底将有超过50&#xff05;的大型企业部署至少一个边缘计算应用&#xff1b;到2023年底&#xff0c;50&#xff05;以上的大型企业将至少部署6个用于物联网或沉浸式体验的边缘计算应用。工业一体机的售价一般在1…

.propertie文件注释

在.properties文件中注释,前边加#就可以转载于:https://www.cnblogs.com/toSeeMyDream/p/5539322.html

《鸿蒙理论知识01》HarmonyOS概述之技术特性

导读:多种设备之间能够实现硬件互助、资源共享,依赖的关键技术包括分布式软总线、分布式设 备虚拟化、分布式数据管理、分布式任务调度等。 目录 1.分布式软总线 2.分布式设备虚拟化 3.分布式数据管理 4.分布式任务调度

《鸿蒙理论知识02》HarmonyOS开发平台和工具

目录 1.应用和开发工具的演进 2.超 级 终 端 应 用 开 发 面 临 全 新 挑 战

不常用 保存下来

一、数学函数  数学函数主要用于处理数字&#xff0c;包括整型、浮点数等。 ABS(x) 返回x的绝对值   SELECT ABS(-1) -- 返回1 CEIL(x),CEILING(x) 返回大于或等于x的最小整数   SELECT CEIL(1.5) -- 返回2 FLOOR(x) 返回小于或等于x的最大整数   SELECT FLOOR(1.5) --…

用Lucene建立搜索索引

本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中&#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要&#xff0c;然后了解Lucene中搜索的工作方式。 此外&#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中&#xff0c;以…

《鸿蒙理论知识03》HarmonyOS概述之系统安全

在搭载 HarmonyOS 的分布式终端上,可以保证“正确的人,通过正确的设备,正确地使 用数据”。 通过“分布式多端协同身份认证”来保证“正确的人”。 通过“在分布式终端上构筑可信运行环境”来保证“正确的设备”。 通过“分布式数据在跨终端流动的过程中,对数据进行分类分…

Shell基础学习(六) 流程控制

1、if if的语法格式 if conditon thencommand1command2commandn fi 2、if else if conditon thencommand1command2commandn elsecommand1command2commandn fi 3、if elseif else if conditon thencommand1command2commandn else if conditoncommand1command2commandn elsecomma…

《鸿蒙理论知识04》HarmonyOS概述之系统定义

目录 系统定位 技术架构 系统服务层 框架层 系统定位 HarmonyOS 是一款“面向未来”、面向全场景(移动办公、运动健康、社交通信、媒体 娱乐等)的分布式操作系统。在传统的单设备系统能力的基础上,HarmonyOS 提出了基 于同一套系统能力、适配多种终端形态的分布式理念,…

jQuery on 绑定的事件触发多次

jquery用on绑定事件&#xff0c;在代码执行过程中&#xff0c;可能会遇到多次执行的情况。 解决方案是在on的事件前面加上一个off&#xff0c;再on。 $(#btnBind).off(click).on(click,function () {alert(123); });$("#xxx").off(keydown).focus().on(keydown,funct…

twitter api_Java应用程序上的Twitter API

twitter api是否曾想过将推文附加到Java应用程序&#xff1f; 我为此寻找了最好的API&#xff0c;很幸运&#xff0c;我找到了它&#xff01; http://twitter4j.org/ 一个简单的方法&#xff1a; 我们需要做的第一件事是在您的Twitter帐户中创建一个应用程序&#xff0c;为其授…