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 覆盖率检测原理与增量代码测试覆盖率工具实现
聊聊度量测试覆盖率的几种方式
伊斯坦布尔测试覆盖率的实现原理
测试覆盖率
相关文章:
test 系统学习-04-test converate 测试覆盖率 jacoco 原理介绍
测试覆盖率 测试覆盖率(test coverage)是衡量软件测试完整性的一个重要指标。掌握测试覆盖率数据,有利于客观认识软件质量,正确了解测试状态,有效改进测试工作。 当然,要发挥这些作用,前提是我们掌握了真实的测试覆盖…...
小型企业成为网络犯罪分子获取数据的目标
在过去十年的大部分时间里,网络犯罪的巨额资金来自针对大型组织的勒索软件攻击。这种威胁仍然存在。但犯罪分子可能会将注意力转向中小企业 (SMB)。这对消费者的影响将是巨大的。 将软件即服务 (SaaS) 技术用于核心业务功能继续将中小企业整合到全球供应链中。由于…...
PyTorch的Tensor(张量)
一、Tensor概念 什么是张量? 张量是一个多维数组,它是标量、向量、矩阵的高维拓展 Tensor与Variable Variable是torch.autograd中的数据类型,主要用于封装Tensor,进行自动求导。 data: 被包装的Tensorgrad: data的梯度&…...
spug发布问题汇总记录
问题导览 1. [vite]: Rollup failed to resolve import "element-plus" from "src/main.js". 项目框架简介 vue3viteelement-plus 解决方案 - 1. 配置淘宝镜像源:npm config set registry https://registry.npm.taobao.org/ - 2. npm inst…...
SpringBoot-搭建集成Mybatis的项目
本文介绍了如何在IntelliJ IDEA中使用SpringBoot和Mybatis构建Java Web应用程序。通过本文的学习,读者将了解如何使用IntelliJ IDEA快速搭建一个基于SpringBoot和Mybatis的Java Web应用程序,提高开发效率。IntelliJ IDEA是一款功能强大的Java集成开发环境…...
mysql隐式转换规则
MySQL 中的隐式类型转换发生在比较操作或者其他一些需要特定数据类型参数的上下文中,如果参与操作的表达式或列的数据类型不匹配,MySQL 就会自动进行数据类型转换以适配预期的数据类型。 以下是 MySQL 的一些常见隐式转换规则: 字符串和数字…...
怎么解决 Nginx反向代理加载速度慢?
Nginx反向代理加载速度慢可能由多种原因引起,以下是一些可能的解决方法: 1,网络延迟: 检查目标服务器的网络状况,确保其网络连接正常。如果目标服务器位于不同的地理位置,可能会有较大的网络延迟。考虑使用…...
Eureka工作原理超详细讲解介绍
Eureka 是 Netflix 开源的一款服务注册与发现框架,主要用于构建分布式系统中的服务治理和负载均衡。下面是关于 Eureka 工作原理的详细介绍:1.Eureka 架构: Eureka 采用了客户端-服务器架构,包括 Eureka Server 和 Eureka Client …...
SQL WHERE 语句(条件选择)
WHERE 子句用于过滤记录。 SQL WHERE 子句 WHERE 子句用于提取那些满足指定条件的记录。 SQL WHERE 语法 SELECT column1, column2, ... FROM table_name WHERE condition; 参数说明: column1, column2, ...:要选择的字段名称,可以为多…...
用UCLI(TCL)控制verdi dump 波形
UCLI(Unified Command-line Interface)为Synopsys验证工具了提供一组通用命令,通过UCLI可以执行任意TCL(Tool Command Language)命令。在我们的验证环境中,通常跟ucli打交道的地方是用来控制开始dump和结束…...
如何使用 Python+selenium 进行 web 自动化测试?
Selenium是一个自动化测试工具,它可以模拟用户在浏览器中的操作,比如点击、输入、选择等等。它支持多种浏览器,包括Chrome、Firefox、Safari等等,并且可以在多个平台上运行。 安装和配置Selenium 在使用Selenium之前,…...
约瑟夫问题
约瑟夫问题 题目描述 n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。…...
文件管理方法:利用文件大小进行筛选,高效移动文件至目标文件夹
在日常工作中,文件管理是一项至关重要的任务。为了更高效地管理文件,可以利用文件大小进行筛选,并将文件快速移动至目标文件夹。接下来一起来看看云炫文件管理器如何利用文件大小进行筛选,以及如何高效移动文件至目标文件夹的方法…...
python报错:TypeError: Descriptors cannot be created directly.
问题 报错提示: TypeError:不能直接创建描述符。 如果此调用来自 _pb2.py 文件,则您生成的代码已过期,必须使用 protoc > 3.19.0 重新生成。 如果您不能立即重新生成原型,其他一些可能的解决方法是: 1.…...
Linux 内核调试
文章目录 一、方法论 一、方法论 qemu 虚拟机 Linux内核学习 Linux 内核调试 一:概述 Linux 内核调试 二:ubuntu20.04安装qemu Linux 内核调试 三:《QEMU ARM guest support》翻译 Linux 内核调试 四:qemu-system-arm功能选项整…...
Prometheus-AlertManager 邮件告警
环境,软件准备 本次演示环境,我是在虚拟机上安装 Linux 系统来执行操作,以下是安装的软件及版本: System: CentOS Linux release 7.6Docker: 24.0.5Prometheus: v2.37.6Consul: 1.6.1 docker 安装prometheus,alertmanage,说明一下这里直接将…...
Volcano Controller控制器源码解析
Volcano Controller控制器源码解析 本文从源码的角度分析Volcano Controller相关功能的实现。 本篇Volcano版本为v1.8.0。 Volcano项目地址: https://github.com/volcano-sh/volcano controller命令main入口: cmd/controller-manager/main.go controller相关代码目录: pkg/co…...
开源协议简介和选择
软件国产化已经提到日程上了,先来研究一下开源协议。 引言 在追求“自由”的开源软件领域的同时不能忽视程序员的权益。为了激发程序员的创造力,现今世界上有超过60种的开源许可协议被开源促进组织(Open Source Initiative)所认可…...
大创项目推荐 深度学习卫星遥感图像检测与识别 -opencv python 目标检测
文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐…...
pod的环节
pod 是k8s当中最小的资源管理组件 Pod也是最小化运行容器化的应用的资源管理对象 Pod是一个抽象化的概念,可以理解为一个或多个容器化的集合 在一个pod当中运行一个容器,是最常用的方式 在一个pod当中同时运行多个容器,在一个pod当中可以…...
Unity | Shader基础知识番外(向量数学知识速成)
目录 一、向量定义 二、计算向量 三、向量的加法(连续行走) 四、向量的长度 五、单位向量 六、向量的点积 1 计算 2 作用 七、向量的叉乘 1 承上启下 2 叉乘结论 3 叉乘的计算(这里看不懂就百度叉乘计算) 八、欢迎收…...
一个小白的微不足道的见解关于未来
随着科技的不断发展,IT行业日益壮大,运维工程师在其中扮演着至关重要的角色。他们负责维护和管理企业的技术基础设施,确保系统的正常运行。然而,随着技术的进步和行业的变化,运维工程师的未来将面临着一系列挑战和机遇…...
图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)
一、图的遍历的定义: 从图的某个顶点出发访问遍图中所有顶点,且每个顶点仅被访问一次。(连通图与非连通图) 二、深度优先遍历(DFS); 1、访问指定的起始顶点; 2、若当前访问的顶点…...
抖店做不起来?新手常见起店失败问题总结,看下你中了几条?
我是王路飞。 能看到这篇文章的,肯定是处境符合标题内容了。 抖店的门槛很低,运营思路其实也不算难,但就是很多新手做不起来。 这中间,可能跟平台、项目没什么关系,而是跟你自己有关系,走错了方向&#…...
【每日面试题】精选java面试题之redis
Redis是什么?为什么要使用Redis? Redis是一个开源的高性能键值对存储数据库。它提供了多种数据结构,包括字符串、列表、集合、有序集合、哈希表等。Redis具有快速、可扩展、持久化、支持多种数据结构等特点,适用于缓存、消息队列…...
OSCP 靶场 - Vault
端口扫描 nmap nmap -O 192.168.162.172 smb枚举 smbmap(kali自带) //枚举GUEST用户可以使用的目录 smbmap -u GUEST -H 192.168.162.172 NTLMrelay—smbrelay 1.制作钓鱼文件 使用GitHub - xct/hashgrab: generate payloads that force authentication against an attacker…...
uniapp子组件向父组件传值
目录 子组件向父组件传值子组件1子组件2 父组件最后 子组件向父组件传值 子组件1 <template><view class"content"><view v-for"(item,index) in list" :key"index">{{item}}</view></view> </template>&…...
过滤特殊 微信昵称
$nickName preg_replace(/[\xf0-\xf7].{3}/, , $userData[nickName]);...
LLM、AGI、多模态AI 篇一:开源大语言模型简记
文章目录 系列开源大模型LlamaChinese-LLaMA-AlpacaLlama2-ChineseLinlyYaYiChatGLMtransformersGPT-3(未完全开源)BERTT5QwenBELLEMossBaichuan...
微信小程序中获取用户当前位置的解决方案
微信小程序中获取用户当前位置的解决方案 1 概述 微信小程序有时需要获取用户当前位置,以便为用户提供基于位置信息的服务(附近美食、出行方案等)。 获取用户当前位置的前提是用户手机需要打开 GPS 定位开关;其次,微…...
用vs2012做网站首页/站长工具忘忧草
iOS 10正式版定于9月13日推送,目前GM版已经可以下载。现在,苹果正式关闭了iOS 9.3.4的认证,这意味着iOS 9.3.5将不能再降级。目前iOS 9.3.4并不能越狱(需9.3.3以下),而且存在所谓iOS史上最大的一个远程执行…...
b2c网站的认识/哪里可以代写软文
对于大部分IT人士来说,给电脑重装系统、迁移操作系统、给硬盘分区、磁盘分区克隆等都是经常要做且不得不做的事情,那么使用哪款软件来管理磁盘分区,就成了大多数人比较纠结的问题。究竟有没有什么分区管理软件是比较靠谱又安全的呢࿱…...
工业设计网站外网/seo外链网
【1】决定多长时间启动所有线程。如果使用10个线程,ramp-up period是100秒,那么JMeter用100秒使所有10个线程启动并运行。每个线程会在上一个线程启动后10秒(100/10)启动。Ramp-up需要充足长以避免在启动测试时有一个太大的工作负…...
数字尾巴+wordpress/互联网培训机构排名前十
查找题目描述:输入数组长度 n输入数组 a[1...n]输入查找个数m输入查找数字b[1...m]输出 YES or NO 查找有则YES 否则NO 。输入:输入有多组数据。每组输入n,然后输入n个整数,再输入m,然后再输入m个整数(1<m<n<…...
北京推广网站/广州市新闻发布
2019独角兽企业重金招聘Python工程师标准>>> 1.停止mysql服务 2.转至mysql安装目录的 bin 目录下 3.运行 mysqld --skip-grant-tables 4.新开cmd窗口,直接输入 mysql 然后不输入密码回车. 5.use mysql; 6.更新密码 update user set passwordpasswor…...
教学平台网站建设合同/企业网站推广渠道有哪些
一、准备环境1、两台虚拟机、一台正常运行oracle数据库的,一台装了软件没有启动数据库的(没有进行dbca)2、主库备库 修改环境变量,修改主机名,将主库备库的主机名都写入hosts文件二、开始搭建1.查看主库是否开启归档模…...