编码的喜悦……以及Java中的变异测试

多年以来,为源代码编写单元测试一直是一种好习惯。 并且还可以使用测试覆盖率报告来查看测试覆盖了多少代码。 尽管行+分支覆盖率报告非常有用,但是它并不能告诉您单元测试的实际效果。 因此,甚至在测试中没有一个断言的情况下,甚至有可能达到100%的覆盖率。

对更好的测试方法感兴趣,我参加了今年的“ 欢乐编码 ”会议期间的“突变测试”研讨会。
变异测试是执行和分析单元测试的结果及覆盖范围的一种截然不同的方法。 无需衡量单元测试“访问了”多少代码,而是确定单元测试实际上“测试了”多少代码。

那么它实际上是如何工作的

变异测试背后的基本思想是对(字节)代码进行小改动(变异),然后执行测试以查看是否被单元测试检测到。
可能的突变是将“ > ”更改为“ >= ”,将“ ++ ”替换为“ -- ”,并删除“ void ”方法调用。
因此,每个突变都会创建代码的变更版本,称为“突变”。

在进行实际的变异测试之前,首先需要针对原始代码执行单元测试,以查看是否没有测试失败。

然后,将对每个“突变体”运行单元测试(这可能非常耗时),看是否:

  • 我们的单元测试检测到该突变体:测试失败,因此“突变体”被视为“已杀死”。
  • 在我们的单元测试中,突变体仍然未被注意到:测试没有“没有”失败(“突变体”被认为是“存活”)并且没有注意到突变; 这意味着单元测试实际上是“未”测试(未发现)“突变体”的。

变异测试的一个例子

那么,这种“变异测试”实际上是如何工作的呢?
请考虑以下方法:

public String foo(int i) {if ( i >= 0 ) {return "foo";} else {return "bar";}
}

单元测试仅包含一种测试方法:

@Test
public void testFoo() {testee.foo(0);
}

如果我们要创建代码的“突变体”,将“ >= ”更改为“ > ”,该怎么办?
我们希望我们的单元测试方法能够检测到这一点,对吧? 好吧,在这种情况下不是因为测试方法不包含单个断言。

我们将更改一个“ testFoo”方法以包含一个断言:

@Test
public void testFoo() {String result = testee.foo(0);assertEquals("foo", result);
}

现在,我们的单元测试方法将失败并检测(也称为“杀死”)“突变”代码。

除了将“ >= ”更改为“ > ”以外,还可以创建其他“突变体”:

  • 可以将第一个return方法更改为返回null (而不是"foo" );
    由于使用“ assertEquals”语句,此“突变体”被“ testFoo”方法“杀死”,但仍未被注意到原始的“ testFoo”方法(没有任何断言)。
  • 可以将第二个return方法更改为返回null (而不是"bar" );
    由于没有测试方法实际覆盖此执行路径,因此该“突变”将不会被注意到。

注意 :一些变异测试工具(例如Java的PIT)甚至不会费心为第二个return语句创建“变异”,因为它不会被单元测试所覆盖(如传统的行覆盖率所检测)。

等效突变导致假阳性

与传统的行+分支覆盖相比,突变覆盖可能会导致假阳性。
它可能“错误地”报告(假阳性)单元测试未检测到“突变”为“未”。

例如,考虑以下Java代码:

public int someNonVoidMethod() { return 0; }
public void foo() {int i = someNonVoidMethod();// do more stuff with i
}

在变异测试期间(使用具有某些“非”默认配置的PIT变异测试),可能会创建以下“变异”:

public int someNonVoidMethod() { return 0; }
public void foo() {int i = 0;// do more stuff with i
}

“ mutant”中的“ int i = 0 ”语句在功能上与“ someNonVoidMethod ”返回0的原始代码“等效”。
由于单元测试不会(也不应)失败,因此无法检测到这种“等效突变”。
因此,它将被报告为未覆盖,而实际上它是一个假阳性。

根据文档 ,在使用PIT(一种用于Java的突变测试框架)时,“等效突变”应使用“默认”的一组突变体最小化。
例如,默认情况下会禁用导致“ int i = 0 ”等效突变的PIT的“非无效方法调用突变器”。

结论

在参加了研讨会,一些额外的调查并与PIT合作之后,我非常热衷于在不久的将来在当前项目中使用“变异测试”(从新组件开始)。
与传统的覆盖率报告相适应,变异测试覆盖率实际上可以衡量您的测试质量,不能像传统的覆盖率报告那样被愚弄。

如果您也有兴趣:

  • 请查看克里斯·里默(Chris Rimmer)的这个非常有趣的演讲 ,内容涉及突变测试的基本概念。
  • 此外,还有一家名为TheLadders的公司使用PIT突变测试工具撰写了一篇有趣的文章 。
  • Filip van Laenen还写了一篇有关超载杂志第108版中的“变异测试”的文章。
  • 最后但并非最不重要的一点是PIT突变测试网站上的文档。

翻译自: https://www.javacodegeeks.com/2014/03/joy-of-coding-and-mutation-testing-in-java.html

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

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

相关文章

错误1083:配置成在该可执行程序中运行的这个服务不能执行该服务 【解决办法】...

一直好用的服务程序,今天遇到这个问题,搜了一下各位给出的解决办法; 1.程序里多添加serviceInstaller组件的,然而我并没改代码,也没重新编译,不是解决我问题的办法; 2.修改注册表的,…

oracle 更改启动内存,Oracle 11gR2修改内存参数后无法启动问题

Microsoft Windows [版本 6.1.7600]版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\windows\system32>net start oracleserviceorclOracleServiceORCL 服务正在启动 ......OracleServiceORCL 服务已经启动成功。C:\windows\system32>sqlplus / as sysdbaSQL…

查看所有shell类型

[xfxuexi ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh 具体你使用的是那一个,取决于你的用户配置,可以在/etc/passwd文件查看最后一个字段 [xfxuexi ~]$ head -1 /etc/passwd…

Vue—事件修饰符

Vue事件修饰符 Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节&#xff0c;如&#xff1a; event.preventDefault() 或 event.stopPropagation()。Vue.js通过由点 (.) 表示的指令后缀来调用修饰符。 .stop.prevent.capture.self.once <!-- 阻止单击事件冒泡 -->…

如何安装 Angular CLI 并且检查 CLI 的版本

想在系统中安装 Angular CLI &#xff0c;如何进行安装并且如何检查 CLI 的版本&#xff1f; 可以使用命令&#xff1a; npm install -g angular/cli 进行安装。 使用命令 ng version 来查看 Angular 的 CLI 的版本 转载于:https://www.cnblogs.com/huyuchengus/p/10879166.htm…

与Maven和Docker的集成测试

Docker是其中的新热点之一。 与传统虚拟机相比&#xff0c;它具有一套不同的技术和思想&#xff0c;并通过容器的思想实现了相似但同时又有所不同的事物&#xff1a;几乎所有VM都具有强大的功能&#xff0c;但速度更快&#xff0c;并且具有非常有趣的附加功能。 在本文中&…

oracle转mysql总结经验,oracle转mysql总结(转)

ares-sdk初始开发测试使用的是oracle数据库&#xff0c;由于宁波通商的特殊需要&#xff0c;必须把数据库环境从oracle转向mysql。 现对转换过程中出现的问题及经验总结如下&#xff1a;主键生成策略创建一个专门记录序列的表sequence,记录有当前序列号,序列的间隔如1创建记录当…

vue 顶级组件

快 有时候懒的把一些通用组件写到 template里面去&#xff0c;而业务中又需要用到&#xff0c;比如表示 loading状态这样组件。如果是这样的组件&#xff0c;可以选择把组件手动初始化&#xff0c;让组件在整个app生命周期中始终保持活跃。 如&#xff1a; // a.js import Vu…

2018-2019-2 网络对抗技术 20165329 Exp 8 Web基础

2018-2019-2 网络对抗技术 20165329 Exp 8 Web基础 原理与实践说明 实践内容概述基础问题回答实践过程记录 1.Web前端&#xff1a;HTML2.Web前端&#xff1a;javascipt3.Web后端&#xff1a;MySQL基础4.Web后端&#xff1a;编写PHP网页5.最简单的SQL注入&#xff0c;XSS攻击测试…

为JVM分配内存:一个案例研究

这篇文章是关于最近的性能调整练习的。 与往常一样&#xff0c;这些开始于关于症状的模糊表述。 这次&#xff0c;魔鬼采取了“应用程序速度慢&#xff0c;我们无法访问源代码的形式。 我们有什么改善情况的选择”。 对该应用程序进行仔细研究后发现&#xff0c;它由捆绑在一起…

洛谷P4822 冻结

题目描述 “我要成为魔法少女&#xff01;” “那么&#xff0c;以灵魂为代价&#xff0c;你希望得到什么&#xff1f;” “我要将有关魔法和奇迹的一切&#xff0c;封印于卡片之中„„” 在这个愿望被实现以后的世界里&#xff0c;人们享受着魔法卡片&#xff08;\(SpellCard\…

Vue基础指令集锦

v-model双向绑定数据 <input type"text" v-model"msg"> {{msg}} ###v-on 事件 <div id"box"><button v-on:click"say">按钮</button><button click"say">按钮</button> </div>…

oracle删除实体,oracle 按条件删除、查询表

---查询表的名称&#xff0c;字段信息以及字段注释selectus.table_name, --表名ut.COLUMN_NAME,--字段名称uc.comments,--字段注释ut.DATA_TYPE,--字典类型ut.DATA_LENGTH,--字典长度ut.NULLABLE--是否为空from user_tab_columns utinner JOIN user_col_comments ucon ut.TABLE…

Thymeleaf与Spring集成(第2部分)

1.简介 这是Thymeleaf与Spring教程集成的第二部分。 您可以在此处阅读第一部分&#xff0c;在那里您将学习如何配置该项目。 如本教程第一部分开头所述&#xff0c;Web应用程序将发送两种类型的请求&#xff1a; 插入新访客&#xff1a;将同步请求发送到服务器以添加新访客。…

数据结构(一)

1.数据结构---数据在计算机中的存储和组织。 物理结构&#xff1a;线性存储和链式存储。 逻辑结构&#xff1a;数据的关系和联系&#xff0c;线性结构和非线性结构&#xff08;树一对多&#xff0c;前继&#xff0c;后驱&#xff09;。 数据结构和算法是伴生的&#xff0c;算法…

Vue实例和生命周期

创建一个Vue实例 每个Vue应用都是通过Vue函数创建一个新的Vue实例开始&#xff1a; var vm new Vue({//选项 }) 数据与方法 当一个Vue实例被创建时&#xff0c;它向Vue的响应式系统中加入了其data对象中能找到的所有属性。当这个属性的值发生变化时&#xff0c;视图将产生…

boid模型的Matlab程序,动物集群运动行为模型系列之五-—本科毕业设计.doc

动物集群运动行为模型系列之五-—本科毕业设计动物集群运动模型摘要本文主要模拟了鱼群的集群运动、鱼群躲避捕食者追捕的运动情况以及鸟群觅食运动的模拟&#xff0c;以此研究动物个体间的信息传递机制&#xff0c;同时也是对群体智能的初步探索。针对问题一&#xff0c;需要我…

【 jquery 】常用

$("#input1").show(slide); 渐进显示$("#input1").hide(slide); 渐进隐藏 siblings() 方法返回被选元素的所有同级元素 $("#family_name_pinyin").val(arr[0].replace(" ", "")).siblings("span").hide();…

我们正在破解JDBC,因此您不必

我们喜欢使用JDBC 没人说。 曾经 更严重的是&#xff0c;如果考虑一下&#xff0c;JDBC实际上是一个非常出色的API。 这也可能是Java成为当今流行平台的原因之一 。 在JDK 1.1 之前 &#xff0c; 以及在ODBC之前 &#xff08;这已经很久了&#xff09;&#xff0c;很难想象有任…

python之requests

转载:https://www.cnblogs.com/zhangxinqi/p/9201594.html 阅读目录 1、requests简介2、requests的安装3、requests请求4、请求响应5、requests异常处理6、cookies7、请求会话(Session)8、SSL证书验证9、代理设置10、身份认证11、编码12、其他说明1、requests简介 requests是通…