【测试开发知识储备】之Jacoco(Java Code Coverage)

文章目录

  • Jacoco是什么
  • Jacoco的主要功能
    • (一)多样化覆盖率指标分析
    • (二) 丰富的报告生成
    • (三)实时数据收集
  • Jacoco的工作原理
    • (一)字节码增强
    • (二)测试执行与数据收集
  • 使用方法
    • 需要工具
    • 步骤
    • 本地启动开启Jacoco覆盖率
    • 效果

在测试过程中,为了解决 统计【行覆盖率】和【已经覆盖行数】两个指标,便于快速查看和复制,我们可以通过Jacoco去解决。

Jacoco是什么

Jacoco 是专门用于 Java 项目测试覆盖率检测的工具,由 EclEmma 项目演变而来。它能够精准地分析出代码中哪些部分已被测试覆盖,哪些部分尚未覆盖,为开发者优化测试用例提供了明确方向
在这里插入图片描述

Jacoco的主要功能

(一)多样化覆盖率指标分析

Jacoco 支持多种覆盖率指标,涵盖行覆盖、分支覆盖、方法覆盖和类覆盖等。行覆盖用于判断代码的每行是否至少有一个指令被执行;分支覆盖聚焦于如 if - else、switch 等语句分支的执行情况;方法覆盖判断方法是否被调用执行;类覆盖则确定类是否被执行。通过这些指标,开发者能全方位了解代码的测试覆盖状况。

(二) 丰富的报告生成

它能生成详细的覆盖率报告,且支持 HTML、XML 和 CSV 等多种格式。这些报告清晰展示代码的覆盖情况,突出显示未覆盖的代码区域,方便开发者分析和排查问题。

(三)实时数据收集

在测试运行时,Jacoco 可动态收集覆盖率数据,无需事后处理,能实时反映代码的测试状态,助力开发者迅速调整测试策略。

Jacoco的工作原理

(一)字节码增强

在测试运行前,Jacoco 会对 Java 字节码进行修改,插入覆盖率收集的逻辑,这一过程即 “字节码增强”。增强后的字节码包含用于记录代码路径执行情况的指令,为准确捕捉代码执行信息奠定基础。

(二)测试执行与数据收集

测试用例运行时,增强后的字节码会执行插入的覆盖率记录逻辑,实时收集代码行、分支、方法和类的执行信息。Jacoco 采用轻量级代理模式,对测试执行性能影响极小。测试完成后,Jacoco 汇总收集到的覆盖率数据,生成详细的覆盖率报告,清晰展示各代码单元的覆盖情况。

使用方法

需要工具

油猴插件:https://www.tampermonkey.net/

步骤

  • 安装tampermonkey插件,并打开插件开关
    在这里插入图片描述
  • 点开详情,将允许访问文件网址打开,才可以生效与本地生成的jacoco覆盖率报告
    在这里插入图片描述
  • 通过管理面板,进入管理页面,新增脚本
    在这里插入图片描述
  • 通过添加新的脚本,将以下脚本键入并保存

// ==UserScript==
// @name         白盒覆盖率报告覆盖率插件
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  用于jacoco报告的计算行覆盖率!
// @author       lulu
// @match        https://coverage.myshopline.cn/jacoco/report/*
// @match        file:///*.html
// @icon         https://www.google.com/s2/favicons?sz=64&domain=myshopline.cn
// @grant        GM_addStyle
// @grant        unsafeWindow
// @grant        GM_setClipboard
// @require      https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
// @require      https://unpkg.com/sweetalert2@10.16.6/dist/sweetalert2.all.min.js// ==/UserScript==(function() {'use strict';var element = document.querySelector("tbody");var thead = document.querySelector('td#i');var theadtdratio = document.createElement('td');var coveredtd = document.createElement('td');// 底部var foot = document.querySelector('tfoot > tr > td:nth-of-type(9)');var footcovered = document.createElement('td');var footratiotd = document.createElement('td');footcovered.setAttribute('class','ctr2')footratiotd.setAttribute('class','ctr2')foot.before(footcovered);foot.after(footratiotd);//设置表头theadtdratio.innerHTML = '行覆盖率比例';coveredtd.innerHTML = 'Covered';thead.before(coveredtd);thead.after(theadtdratio);var coveredConut = 0;// 获取地址var url =window.location.href;var baseUrl = url.substring(0,url.lastIndexOf('/')+1)console.log('读取地址:',baseUrl)for(var i=0; i<element.rows.length; i++){var miss = parseInt(element.rows[i].cells[7].innerHTML.replace(/,/g, ""));var lines = parseInt(element.rows[i].cells[8].innerHTML.replace(/,/g, ""));var link = element.rows[i].cells[0].querySelector('a').getAttribute('href');var covered = lines - missvar result =Math.round((1- miss/lines) * 10000) / 100;//添加结果var td = document.createElement('td');var alink = document.createElement('a');alink.innerHTML = result +'%'alink.href = baseUrl + linktd.appendChild(alink);td.setAttribute('class','ctr2');var coveredtd1 = document.createElement('td');coveredtd1.innerHTML = covered;coveredtd1.setAttribute('class','ctr2')element.rows[i].cells[7].after(coveredtd1);element.rows[i].cells[9].after(td);coveredConut += covered;//totalLines += result;/*//TODO 准备做一键复制var copyButton = document.createElement('span');copyButton.id = i;copyButton.innerHTML = miss +'\n' + lines +'\n' + resultelement.rows[i].appendChild(copyButton);copyButton.onclick = function(miss){//copy(miss+'\t'+lines+'\t'+result);console.log('copy:'+copyButton.innerHTML);//copy(parseInt(element.rows[i].cells[7].innerHTML.replace(/,/g, ""))+'\t'+parseInt(element.rows[i].cells[8].innerHTML.replace(/,/g, ""))+'\t'+td.innerHTML);}*///处于70-80if(result>=75 && result < 100){td.style.backgroundColor = '#00FFCC';}else if(result == 100){td.style.backgroundColor = 'green';}//低于70%else{td.style.backgroundColor = 'red';}//总覆盖率//totalLines += result;console.log(miss,lines,link,result);}footcovered.innerHTML = coveredConut;var tatolratiotd = coveredConut/parseInt(document.querySelector('tfoot > tr > td:nth-of-type(10)').innerHTML.replace(/,/g, "")) ;footratiotd.innerHTML = Math.round(tatolratiotd * 10000) / 100 + '%';if(tatolratiotd>=75 && tatolratiotd < 100){footratiotd.style.backgroundColor = '#00FFCC';}else if(tatolratiotd == 100){footratiotd.style.backgroundColor = 'green';}//低于70%else{footratiotd.style.backgroundColor = 'red';}const copy = (text) => {GM_setClipboard(text, 'text');}})();
  • 打开对应开关即可
    在这里插入图片描述

本地启动开启Jacoco覆盖率

  • 编辑运行配置
    在这里插入图片描述

  • 调整运行模板的junit code coverage配置为项目目录,并选择jacoco覆盖率统计工具
    在这里插入图片描述

  • 导出本地日志,保存后会自动打开报告可以查看
    在这里插入图片描述

在这里插入图片描述

效果

在这里插入图片描述

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

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

相关文章

Docker 介绍与使用

Docker 文章目录 Docker介绍与虚拟机的比较启动速度占用资源 优势更容易迁移更容易维护更容易扩展 使用场景持续集成提供可伸缩的云服务搭建微服务架构 镜像与容器镜像构成&#xff08;分层结构&#xff09;镜像与容器的区别 安装 Docker常用命令介绍镜像相关容器相关 实战&…

《AI大模型应知应会100篇》第62篇:TypeChat——类型安全的大模型编程框架

第62篇&#xff1a;TypeChat——类型安全的大模型编程框架 摘要 在构建 AI 应用时&#xff0c;一个常见的痛点是大语言模型&#xff08;LLM&#xff09;输出的不确定性与格式不一致问题。开发者往往需要手动解析、校验和处理模型返回的内容&#xff0c;这不仅增加了开发成本&a…

upload-labs通关笔记-第5关 文件上传之.ini绕过

目录 一、ini文件绕过原理 二、源码审计 三、渗透实战 1、查看提示 2、制作.user.ini文件 &#xff08;1&#xff09;首先创建一个文本文件 &#xff08;2&#xff09;保存文件名为.user.ini 2、制作jpg后缀脚本 &#xff08;1&#xff09;创建一个文本文件 &#xf…

为什么 Linux 上默认没有 host.docker.internal

在 Linux 环境中&#xff0c;host.docker.internal 是 Docker 为容器提供的一个特殊 DNS 名称&#xff0c;用于指向宿主机的 IP 地址&#xff08;类似 macOS/Windows 中的行为&#xff09;。但这个功能在 Linux 上默认不启用&#xff0c;需要手动配置才能使用。以下是详细解释和…

C++GO语言微服务和服务发现②

01 创建go-micro项目-查看生成的 proto文件 02 创建go-micro项目-查看生成的main文件和handler ## 创建 micro 服务 命令&#xff1a;micro new --type srv test66 框架默认自带服务发现&#xff1a;mdns。 使用consul服务发现&#xff1a; 1. 初始consul服务发现&…

Redis--常见数据类型List列表

目录 一、概念 二、命令 2.1 LPUSH 2.2 LPUSHX 2.3 RPUSH 2.4 RPUSHX 2.5 LRANGE 2.6 LPOP 2.7 RPOP 2.8 LINDEX 2.9 LINSERT 2.10 LLEN 2.11 阻塞版本命令 三、内部编码 一、概念 列表类型是用来存储多个有序的字符串&#xff0c;列表中的每个字符串称为元素&…

QListWedget控件使用指南

QListWedget公共函数 函数签名功能描述QListWidget(QWidget *parent nullptr)构造函数&#xff0c;创建一个QListWidget对象&#xff0c;可指定父部件&#xff08;默认为nullptr&#xff09;。virtual ~QListWidget()虚析构函数&#xff0c;释放QListWidget对象及其资源。voi…

Seata源码—1.Seata分布式事务的模式简介

大纲 1.Seata分布式事务框架简介 2.Seata AT模式实现分布式事务的机制 3.Seata AT模式下的写隔离机制 4.Seata AT模式下的读隔离机制 5.官网示例说明Seata AT模式的工作机制 6.Seata TCC模式的介绍以及与AT模式区别 7.Seata Saga模式的介绍 8.单服务多个库的分布式事务…

【Qt】之音视频编程2:QtAV的使用篇

QtAV 基本播放控制功能实现&#xff08;C & QML&#xff09; QtAV 提供了完整的播放控制 API&#xff0c;支持 播放、暂停、停止、快进快退、截屏 等功能。以下是具体实现方法&#xff1a; 1. C 控制方式 基本播放控制 #include <QtAV> #include <QtAV/AVPlaye…

歌词滚动效果

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 设置标签页图标 --><link rel"shortcut icon&…

基于大模型的TIA诊疗全流程智能决策系统技术方案

目录 一、多模态数据融合与预处理系统1.1 数据接入模块1.2 数据预处理伪代码二、TIA智能预测模型系统2.1 模型训练流程2.2 混合模型架构伪代码三、术中智能监测系统3.1 实时监测流程3.2 实时预测伪代码四、智能诊疗决策系统4.1 手术方案推荐流程4.2 麻醉方案生成伪代码五、预后…

Java 日期解析与格式化:从标准格式到自然语言解析

使用 Java 搭配 Apache Commons Lang3 和 Natty 库&#xff0c;实现灵活高效的日期解析与格式化。 一、背景 将不同格式的日期统一成一个格式。日期格式可能有以下几种类型&#xff1a; 标准格式&#xff1a;2024-02-28、14/05/2022、2002年5月6日非英文月份缩写&#xff1a;…

Room持久化库:从零到一的全面解析与实战

简介 在Android开发中,Room作为官方推荐的数据库持久化库,提供了对SQLite的抽象层,使得数据库操作更加安全、高效且易于维护。 Room通过注解处理器和编译时验证,显著降低了数据库操作的复杂度,同时支持响应式编程模式,使开发者能够轻松实现数据变化的实时监听。对于企业…

MySQL(6)如何删除数据库和表?

在 MySQL 中删除数据库和表是常见的管理操作。下面将详细介绍如何使用 SQL 语句以及图形化工具来删除数据库和表。 步骤一&#xff1a;连接 MySQL 服务器 首先&#xff0c;连接到 MySQL 服务器&#xff0c;可以使用命令行工具 mysql 或图形化工具如 MySQL Workbench。 使用命…

携固态电池、新形态钢壳叠片电池等产品 豪鹏科技将亮相CIBF 2025

携固态电池、新形态钢壳叠片电池等产品 豪鹏科技将亮相CIBF 2025 来源&#xff1a; 电池百人会-电池网 豪鹏科技&#xff08;展位号:14W001&#xff09;将携固态电池、新形态钢壳叠片电池及高安全性钠离子电池等前沿技术产品亮相CIBF 2025&#xff0c;凭借多年的技术积累和产…

React学习———useEffect和useLayoutEffect

useEffect useEffect是React的一个Hook&#xff0c;用于在函数组件中处理副作用。副作用包括数据获取、订阅、手动DOM操作以及其他需要再渲染后执行的操作 基本用法 useEffect(() > {// 副作用逻辑return () > {// 可选的清理函数} }, [依赖数组])第一个参数&#xff…

“天神之眼”计算平台的算力设计(预计500-1000 TOPS)

关于比亚迪“天神之眼”计算平台的算力设计&#xff08;预计500-1000 TOPS&#xff09;&#xff0c;其技术路径和行业意义值得深入探讨。以下从实现方式、技术挑战和行业影响三个维度展开分析&#xff1a; 1. 多芯片互联的技术实现路径 &#xff08;1&#xff09;芯片选型方案…

FPGA: Xilinx Kintex 7实现PCIe接口

在Xilinx Kintex-7系列FPGA上实现PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;接口&#xff0c;通常使用Xilinx提供的7 Series Integrated Block for PCIe IP核&#xff0c;结合Vivado设计流程。以下是实现PCIe接口的详细步骤和关键点&#xff0c;适…

ArcGIS Desktop使用入门(二)常用工具条——图形

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…

JT/T 808 通讯协议及数据格式解析

文章目录 一、引言二、协议数据帧结构三、消息头结构&#xff08;Message Header&#xff09;四、常用消息类型&#xff08;Message ID&#xff09;五、典型消息体结构解析六、数据转义规则七、校验码计算方法八、终端与平台通信流程示意&#xff08;简要&#xff09;九、平台接…