test 系统学习-04-test converate 测试覆盖率 jacoco 原理介绍

测试覆盖率

测试覆盖率(test coverage)是衡量软件测试完整性的一个重要指标。掌握测试覆盖率数据,有利于客观认识软件质量,正确了解测试状态,有效改进测试工作。

当然,要发挥这些作用,前提是我们掌握了真实的测试覆盖率数据。通常这并不是一件很直接的事情。

如何度量

那么,如何度量测试覆盖率呢?

在度量测试覆盖率之前,我们需要明确测试覆盖率的定义。毕竟,不同的定义会产生完全不同的覆盖率数据。

这里,我基于个人认知和经验,总结三种最常见的测试覆盖率定义及度量方法。

代码覆盖率

最著名的测试覆盖率就是代码覆盖率。这是一种面向软件开发和实现的定义。它关注的是在执行测试用例时,有哪些软件代码被执行到了,有哪些软件代码没有被执行到。被执行的代码数量与代码总数量之间的比值,就是代码覆盖率。

这里,根据代码粒度的不同,代码覆盖率可以进一步分为源文件覆盖率,类覆盖率,函数覆盖率,分支覆盖率,语句覆盖率等。它们形式各异,但本质是相同的。

如何度量代码覆盖率呢?一般可以通过第三方工具完成。不同编程语言,有不同的工具。

例如Java语言有Jacoco,Go语言有GoCov,Python语言有Coverage.py。

这些度量工具有个特点,那就是它们一般只适用于白盒测试,尤其是单元测试。对于黑盒测试(例如功能测试/系统测试)来说,度量它们的代码覆盖率则相对困难多了。

主流编程语言一般都有现成的单元测试工具,拿过来稍作配置即可使用。但是,如果想更进一步去了解这些工具背后的实现原理,就需要花费一些功夫了。

以Python覆盖率工具Coverage.py为例,它包括执行,分析和生成报告三大模块。最核心的执行模块依赖Python内置的trace函数。这是一个由Python解释器提供的,当每一行Python代码被执行时所激活的函数。

基于trace函数,我们可以得到每一行被执行的代码所在的文件和行数。然后,结合软件源代码,我们就可以分析出测试的代码覆盖情况,最后生成覆盖报告。

对于黑盒测试,例如功能测试/集成测试/系统测试等来说,测试用例通常是基于软件需求而不是软件实现所设计的。

因此,度量这类测试完整性的手段一般是需求覆盖率,即测试所覆盖的需求数量与总需求数量的比值。

需求覆盖率

视需求粒度的不同,需求覆盖率的具体表现也有不同。例如,系统测试针对的是比较粗的需求,而功能测试针对的是比较细的需求。当然,它们的本质是一致的。

如何度量需求覆盖率呢?通常没有现成的工具可以使用,而需要依赖人工计算,尤其是需要依赖人工去标记每个测试用例和需求之间的映射关系。

对于黑盒测试来说,由于测试是基于用户场景而不是软件实现设计的。因此,这个时候去度量软件代码覆盖率,其意义并不显著,至少是不如需求覆盖率的。

代码覆盖率和需求覆盖率有一个共同点,即它们都是面向测试过程的指标。因此有个不足之处,即覆盖率数据可能无法完全反映真实的测试状态和水平。

对于代码覆盖率来说,广为诟病的一点就是100%的代码覆盖率并不能说明代码就被完全覆盖没有遗漏了。因为代码的执行顺序和函数的参数值,都可能是千变万化的。一种情况被覆盖到,不代表所有情况被覆盖到。

对于需求覆盖率来说,100%的覆盖率也不能说“万事大吉”。因为需求可能有遗漏或存在缺陷,测试用例与需求之间的映射关系,尤其是用例是否真正能够覆盖对应的测试需求,也可能是存在疑问的。

缺陷覆盖率

测试的目的是发现软件缺陷。因此,衡量测试完整性的终极指标应该是面向测试结果的缺陷覆盖率,即测试所实际发现的缺陷数量与测试所应该发现的缺陷总量的比值。

软件测试一般是分为多个测试阶段的。每个阶段有每个阶段的任务。对于当前测试阶段来说,在后续阶段发现的缺陷中,属于当前阶段(而不是更早阶段)遗漏出去的缺陷是我们需要重点关注的。

虽然讨论缺陷覆盖率有一种“事后诸葛亮”的感觉,但是它的意义是不容忽视的。一方面它提供了评价某一阶段测试工作成效的重要指标,另一方面它为我们改进测试工作提供了重要参考。例如,针对每一个遗漏缺陷深入挖掘,举一反三,可以避免同类问题在未来再次发生。

总结一下,这里介绍了三种常见的测试覆盖率的定义和度量方法,分别是代码覆盖率,需求覆盖率和缺陷覆盖率。它们适用于不同的场景,有各自的优势与不足。需要注意的是,它们不是互相排斥,而是相互补充的。

JAVA覆盖率工具介绍

市场上java主要代码覆盖率工具:EMMA、JaCoCo

总结一下个人对JaCoCo优势的理解:

(1)JaCoCo支持分支覆盖、引入了Agent模式。

(2)EMMA官网已经不维护了,JaCoCo是其团队开发的,可以理解为一个升级版。

(3)JaCoCo社区比较活跃,官网也在不断的维护更新。

我们前期使用的EMMA,也做了全量、差异覆盖率,和精准耦合也结合在了一起,但后来考虑到JaCoCo的优势,也就全部切换了过来。

JaCoCo 简述

JaCoCo 是一个开源的覆盖率工具(官网地址:http://www.eclemma.org/JaCoCo/),它针对的开发语言是java,其使用方法很灵活,可以嵌入到Ant、Maven中;可以作为Eclipse插件,可以使用其JavaAgent技术监控Java程序等等。

很多第三方的工具提供了对JaCoCo的集成,如sonar、Jenkins等。

JaCoCo包含了多种尺度的覆盖率计数器,包含指令级覆盖(Instructions,C0coverage),分支(Branches,C1coverage)、圈复杂度(CyclomaticComplexity)、行覆盖(Lines)、方法覆盖(non-abstract methods)、类覆盖(classes),后面会一一介绍。

我们先看看其覆盖率结果展现如下图1-1所示,方便读者先有一个大概的了解。

JaCoCo 基本概念

行覆盖率:度量被测程序的每行代码是否被执行,判断标准行中是否至少有一个指令被执行。

类覆盖率:度量计算class类文件是否被执行。

分支覆盖率:度量if和switch语句的分支覆盖情况,计算一个方法里面的

总分支数,确定执行和不执行的分支数量。

方法覆盖率:度量被测程序的方法执行情况,是否执行取决于方法中是否有至少一个指令被执行。

指令覆盖:计数单元是单个java二进制代码指令,指令覆盖率提供了代码是否被执行的信息,度量完全独立源码格式。

圈复杂度:在(线性)组合中,计算在一个方法里面所有可能路径的最小数目,缺失的复杂度同样表示测试案例没有完全覆盖到这个模块。

输入图片说明

这个图包含了几种不同的收集覆盖率信息的方法,每种方法的实现方法都不一样,带颜色的部分是JaCoCo比较有特色的地方。

上面各个名次含义(带颜色的为JaCoCo支持):

输入图片说明

上表JaCoCo支持的部分,再详细的解释下:

插桩模式

(1)JaCoCo在Byte Code时使用的ASM技术修改字节码方法,可以修改Jar文件、class文件字节码文件。

(2)JaCoCo同时支持on-the-fly和offline的两种插桩模式。

On-the-fly插桩:

JVM中通过-javaagent参数指定特定的jar文件启动Instrumentation的代理程序,代理程序在通过Class Loader装载一个class前判断是否转换修改class文件,将统计代码插入class,测试覆盖率分析可以在JVM执行测试代码的过程中完成。

Offline模式:

在测试前先对文件进行插桩,然后生成插过桩的class或jar包,测试插过桩的class和jar包后,会生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。

对比

On-the-fly和offline比较:

On-the-fly模式更方便简单进行代码覆盖分析,无需提前进行字节码插桩,无需考虑classpath 的设置。

存在如下情况不适合on-the-fly,需要采用offline提前对字节码插桩:

(1)运行环境不支持java agent。

(2)部署环境不允许设置JVM参数。

(3)字节码需要被转换成其他的虚拟机如Android Dalvik VM。

(4)动态修改字节码过程中和其他agent冲突。

(5)无法自定义用户加载类。

java方法控制流分析

JaCoCo是如何在字节码注入的?

我们带着疑问来看下面的内容:

先举个实例,有个java方法:

输入图片说明

编译后转换成字节码后,内容如下:

输入图片说明

我们知道JaCoCo是字节码注入方式,它是通过一个Probe探针的方式来注入的,具体如下:

探针是字节指令集插入到java方法中,程序执行后可以被记录,它不会改变原有代码的行为。

我们看看探针前后插入比较:

输入图片说明

颜色的部分就是探针注入的地方。

JaCoCo是根据控制流Type来采用不同的探针插入策略的。

一个用java字节码定义的java方法的控制流图可能有以下的type,每一个type连接一个源指令与目标指令,type不同探针的注入策略也会不同,如下是type定义:

输入图片说明

探针不改变该方法的行为,但记录他们已被执行的事实,从理论上讲,可以在控制流图的每一个边插入一个探针,作为探针实现本身需要多个字节码指令,这将增加几倍的类文件的大小和执行速度。

在这里插入图片描述

参考资料

iOS 覆盖率检测原理与增量代码测试覆盖率工具实现

聊聊度量测试覆盖率的几种方式

伊斯坦布尔测试覆盖率的实现原理

测试覆盖率

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用Docker本地部署一个开源网址导航页并分享好友公网使用

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Golang里空结构体struct{}的介绍和使用

s t r u c t struct struct是 G o l a n g Golang Golang里的关键字,用于定义结构类型 比如 type Student struct{id intname string }struct{}是有 0 0 0个元素的结构体. struct{}{}表示类型struct{}的值为空{} 1.性质 1.1不占用内存 大小为 0 0 0,…

java中常用的日期API

目录 LocalDateTime类(日期时间) DateTimeFormater(格式化器) Period类(计算日期间隔) Duration类(计算时间间隔) 本章我要讲的是JDK 8中新增的时间API,因为传统的时间…

【源码预备】Calcite基础知识与概念:关系代数概念、查询优化、sql关键字执行顺序以及calcite基础概念

文章目录 一. 关系代数的基本知识二. 查询优化三. SQL语句的解析顺序1. FROM2. WHERE3. GROUP BY4. HAVING5. SELECT 四. Apache Calcite中的基本概念1. Adapter2. Calcite中的关系表达式2.1. 关系表达式例子2.2. 源码底层结构 3. Calcite的优化规则4. Calcite的Trait--算子物理…

RS485模块常识的解析

1. RS485数据采集模块常识 a) RS485总线基本特性 根据RS485工业总线标准,RS485工业总线为特性阴抗120Ω的半双工通讯总线,其最大负载能力为32个有效负载(包括主控设备与被设备) b) RS485总线传输距离 当使用0.56mm(24AWG)双绞线作…

rabbitmq延时队列相关配置

确保 RabbitMQ 的延时消息插件已经安装和启用。你可以通过执行以下命令来安装该插件: rabbitmq-plugins enable rabbitmq_delayed_message_exchange 如果提示未安装,以下是安装流程: 查看mq版本: 查看自己使用的 MQ(…

Sectigo与Geotrust ov多域名证书的区别

Sectigo和Geotrust都是比较知名的CA认证机构。其中,Sectigo原名Comodo,在2018年整合SSL证书业务,改名为Sectigo,旗下的SSL证书产品根证书也变为Sectigo。Geotrust则是另一个备受信任的数字证书品牌,现在是Digicert旗下…

不会代码(零基础)学语音开发(语音控制舵机)

舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。 舵机,作为模块系列S产品的四大重要组件之一,其在应用中发挥着十分重要的作用。舵机常使用的地方:航模,智能小车,机器人,以及工业领域等等 这…

锐捷 | 策略路由

一、组网要求 1)三层交换机的192.168.2.0/24网段访问外网固定走172.16.1.1这条线 2)三层交换机的192.168.3.0/24网段访问外网固定走172.16.2.1这条线 二、组网拓扑 三、配置要点 1、根据规划,在设备接口上配置IP地址 2、配置OSPF进程 3、所…

第五周:深度学习知识点回顾

前言: 讲真,复习这块我是比较头大的,之前的线代、高数、概率论、西瓜书、樱花书、NG的系列课程、李宏毅李沐等等等等…那可是花了三年学习佳实践下来的,现在一想脑子里就剩下几个名词就觉得废柴一个了,朋友们有没有同感…

不能错过的AI前沿开源工具!

🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

【软件测试】2024年准备中/高级测试岗技术面试...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、软件测试基础知…

NVM NodeJs版本管理 通关宝典

NVM NodeJs版本管理 通关宝典🏹 文章目录 NVM NodeJs版本管理 通关宝典🏹一、NVM是什么二、开始使用NVM三、NVM 命令速查四、手动安装特定Node版本(Windows)🙄4.1 NVM for windows 运行机制4.2 手动安装流程 五、切换 NVM 下载镜像源六、常见…

如何实现安卓端与苹果端互通

在移动应用开发中,如何实现安卓端和苹果端的互通是一个重要的问题。二者缺少一个都会有损失,那如何实现安卓端跟苹果端互通,下面简单的介绍几点方法来帮助你再不同的平台上实现数据交互和功能互通。 基于Web技术 使用Web技术是一种常见并且…

ReactNative 常见问题及处理办法(加固混淆)

文章目录 摘要 引言 正文ScrollView内无法滑动RN热更新中的文件引用问题RN中获取高度的技巧RN强制横屏UI适配问题低版本RN(0.63以下)适配iOS14图片无法显示问题RN清理缓存RN navigation参数取值pod install 或者npm install 443问题处理 打开要处理的…

spark的任务提交方式及流程

本地模式 local 测试用,不多赘述 分布式模式 standalone standalone集群是spark 自带的一个资源调度集群,分为两个角色,master/worker,master负责接收任务请求、资源调度(监听端口7077),worker负责运行exec…

汇报学习1

汇报的重点 项目的意义:可复制的经验、未来的领头基层要多具体的案例且真正有意义提拔的人的标准 汇报的维度 多做定期和主动的回报。 适当的工作汇报,也是对对方尊重的体现。(每一周或每两三天的回报里,要体现对领导的尊重&#…

【2023年度技术盘点】「年终盘点后端系列」探索服务架构体系的技术风向,构建微服务核心能力(升级版)

探索服务架构体系的技术风向,构建微服务核心能力 文章导航大纲前提背景架构未来的风向云原生化的微服务架构(未来软件架构)历史历代服务架构路径新时代架构预测服务架构方向—云原生化微服务云原生化微服务提升了哪些方面 云原生化微服务架构…

Vue 之 修饰符汇总

一、简介 在Vue中,修饰符是一种特殊的语法,用于修改指令或事件绑定的行为,它们以点号(.)的形式添加到指令或事件的后面,并可以改变其默认行为或添加额外的功能,如:禁止事件冒泡、数…