当前位置: 首页 > news >正文

jacoco生成单元测试覆盖率报告

前言

单元测试是日常编写代码中常用的,用于测试业务逻辑的一种方式,单元测试的覆盖率可以用来衡量我们的业务代码经过测试覆盖的比例。

目前市场上开源的单元测试覆盖率的java插件,主要有Emma,Cobertura,Jacoco。具体对比如下:

工具JacocoEmmaCobertura
原理使用 ASM 修改字节码修改 jar 文件,class 文件字节码文件基于 jcoverage,基于 asm 框架对 class 文件插桩
覆盖粒度行,类,方法,指令,分支行,类,方法,基本块,指令,无分支覆盖项目,包,类,方法的语句覆盖/分支覆盖
插桩on the fly、offlineon the fly、offlineoffline,把统计代码插入编译好的class文件中
生成结果在 Tomcat 的 catalina.sh 配置 javaangent 参数,指出需要收集覆盖率的文件,shutdown 时才收集,只能使用 kill 命令关闭 Tomcat,不要使用 kill -9html、xml、txt,二进制格式报表html,xml
缺点需要源代码1、需要 debug 版本,并打来 build.xml 中的 debug 编译项; 2、需要源代码,且必须与插桩的代码完全一致1、不能捕获测试用例中未考虑的异常; 2、关闭服务器才能输出覆盖率信息(已有修改源代码的解决方案,定时输出结果;输出结果之前设置了 hook,会与某些服务器的 hook 冲突,web 测试中需要将 cobertura.ser 文件来回 copy
性能小巧插入的字节码信息更多
执行方式maven,ant,命令行命令行maven,ant
jenkins集成生成 html 报告,直接与 hudson 集成,展示报告,无趋势图无法与 hudson 集成有集成的插件,美观的报告,有趋势图
报告实时性默认关闭,可以动态从jvm dump出数据可以不关闭服务器默认是关闭服务器时才写结果
维护状态持续更新停止维护停止维护

其实上面的对比意义不大,只看最后一条即可,只有jacoco还在持续更新,所以我们肯定首选jacoco。

maven工程使用jacoco配置

在jacoco官网上就有关于maven插件配置的示例,包含单模块单元测试覆盖率报告和统计多模块单元测试覆盖率报告的配置。这里我也分单模块和多模块进行配置说明。

顺便说明,在官网提供的单模块配置中,需要使用两个命令才能生成测试覆盖率报告:

$> mvn clean test # 生成jacoco.exec文件,这里记录了测试执行的情况
$> mvn jacoco:report # 从jacoco.exec文件中解析并生成html测试报告

单模块工程覆盖率报告生成

在pom.xml文件中添加如下插件配置:

<plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><execution><id>default-prepare-agent</id><goals><goal>prepare-agent</goal></goals></execution><execution><id>default-report</id><phase>test</phase><goals><goal>report</goal></goals></execution></executions>
</plugin>

这里相比官网,我添加了如下配置:

<phase>test</phase>

这个配置可以让我们在执行mvn test的时候直接生成测试报告,不用单独执行mvn jacoco:report

另外我移除了如下配置:

<execution><id>default-check</id><goals><goal>check</goal></goals><configuration><rules><rule><element>BUNDLE</element><limits><limit><counter>COMPLEXITY</counter><value>COVEREDRATIO</value><minimum>0.60</minimum></limit></limits></rule></rules></configuration>
</execution>

这一段主要是用于检查测试覆盖率是否达到要求的配置,我们很少在这个阶段进行覆盖率检查,所以可以去掉这段配置为pom.xml瘦身,当然如果有需要可以加上,并且使用如下命令检查:

$> mvn jacoco:check

完成上述配置后,使用如下命令即可生成测试报告(测试报告在target/site/jacoco中):

$> mvn test

多模块工程覆盖率报告生成

在多模块的工程中,测试执行的数据文件(jacoco.exec)和报告通常分散在不同的模块中,看聚合结果非常不便,因此我们通常会考虑将报告聚合起来看结果。

聚合报告的方式有两种,一种是使用jacoco的maven插件提供的聚合功能,这种方式在配置上比较麻烦,但是配置完成后可以不依赖外部应用直接查看结果。 另一种方式是使用外部工具(如sonar)自动聚合报告,这种方式配置简单,但是需要以来外部应用。

使用sonar聚合报告的配置

使用sonar聚合报告的配置,只需要直接在工程的root模块中,配置如下插件:

<build><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.7</version><executions><execution><id>default-prepare-agent</id><goals><goal>prepare-agent</goal></goals></execution><execution><id>default-report</id><goals><goal>report</goal></goals><phase>test</phase></execution></executions></plugin></plugins>
</build>

然后再在root工程的根目录下配置sonar的扫描配置文件sonar-project.properties即可:

sonar.projectKey=${projectKey}
sonar.projectName=${projectName}
sonar.projectVersion=${projectVersion}
sonar.language=java
sonar.modules=${module1},${module2}
sonar.sources=src/main/java
sonar.java.binaries=target/classes
sonar.sourceEncoding=UTF-8
sonar.coverage.jacoco.xmlReportPaths=..

这里对属性作简单说明:

  • ${projectKey}是工程在sonar中的ID
  • ${prjectName}是工程在sonar中的名字
  • ${projectVersion}是工程在sonar中的版本,通常来说可以自行定义,不过建议跟应用保持一致,如1.0
  • ${module1},${module2}是工程模块,即模块在根目录的相对路径(笔者这里没有验证是相对目录还是模块名称,因为在我这里这两个是一致的,通常也建议保持一致,猜测是相对路径,因为sonar并没有分析pom.xml文件,实际上无法知道你的模块路径),多个模块用英文逗号分隔

我们特别注意sonar.coverage.jacoco.xmlReportPaths这个属性的配置,值是..,表示上一层目录。这是因为sonar-scanner在扫描报告时,会在执行路径生成.scannerwork文件夹,并以此文件夹为workdir,而我们需要扫描的目录是根目录,因此需要使用..回到根目录。

这点可以在sonar-scanner的扫描日志中看到:

INFO: Base dir: ~/workspace/griffin
INFO: Working dir: ~/workspace/griffin/.scannerwork

我的执行目录是~/workspace/griffin,因此basedir是~/workspace/griffin,而working dir是~/workspace/griffin/.scannerwork

完成上述配置之后,我们就可以通过如下命令将报告扫描并上传到sonar了:

$> mvn clean test
$> sonar-scanner -Dsonar.host.url=${sonarUrl} -Dsonar.login=${sonarUsername} -Dsonar.password=${sonarPassword}

这个过程发生了什么?

  • 先通过maven运行单元测试,并在每个模块生成jacoco.exec执行数据文件
  • 通过jacoco.exec数据文件,在每个模块的target/site/jacoco生成xml报告(还有html等其他格式的报告)
  • sonar-scanner扫描根目录下所有xml报告并上传到sonar服务
  • sonar服务整合计算报告,并生成结果

最终我们可以在sonar中看到如下报告:

sonar

使用jacoco聚合报告的配置

使用jacoco的聚合报告配置,配置稍微复杂一些,需要使用maven的ant插件,我们可以在root工程的根目录下创建一个jacoco.xml文件,它本质是一个pom文件, 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.jacoco</groupId><artifactId>jacoco-coverage-aggregate</artifactId><version>1.0.0-SNAPSHOT</version><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-antrun-plugin</artifactId><version>3.0.0</version><executions><execution><phase>post-integration-test</phase><goals><goal>run</goal></goals><configuration><target><echo message="Generating JaCoCo Reports" /><taskdef name="report" classname="org.jacoco.ant.ReportTask"><classpath path="${basedir}/target/jacoco-jars/org.jacoco.ant.jar" /></taskdef><mkdir dir="${basedir}/target/coverage-report" /><report><executiondata><fileset dir="${basedir}/${module1}/target"><include name="jacoco.exec" /></fileset><fileset dir="${basedir}/${module2}/target"><include name="jacoco.exec" /></fileset><fileset dir="${basedir}/${module3}/target"><include name="jacoco.exec" /></fileset></executiondata><structure name="jacoco-multi Coverage Project"><group name="jacoco-multi"><classfiles><fileset dir="${basedir}/${module1}/target/classes" /><fileset dir="${basedir}/${module2}/target/classes" /><fileset dir="${basedir}/${module3}/target/classes" /></classfiles><sourcefiles encoding="UTF-8"><fileset dir="${basedir}/${module1}/src"/><fileset dir="${basedir}/${module2}/src"/><fileset dir="${basedir}/${module3}/src"/></sourcefiles></group></structure><html destdir="${basedir}/target/coverage-report/html" /><xml destfile="${basedir}/target/coverage-report/coverage-report.xml" /><csv destfile="${basedir}/target/coverage-report/coverage-report.csv" /></report></target></configuration></execution></executions><dependencies><dependency><groupId>org.jacoco</groupId><artifactId>org.jacoco.ant</artifactId><version>0.8.7</version></dependency></dependencies></plugin></plugins></build>
</project>

在这个配置中,我有三个模块,因此在配置文件中有${module1}, ${module2}, ${module3}三个占位符,分别代表三个模块的目录名(实际使用的时候需要改成真正的值),另外对于pom文件,groupId,artifactId和version是必须的元素,在这里其实随便起名即可,示例中给了一个勉强通用的配置,当然建议改成和工程相当的值。

完成上述配置后,使用如下两个命令即可生成合并的测试报告:

$> mvn clean test
$> mvn clean verify -f jacoco.xml

最终可以在{project.basedir}/target/coverage-report目录下看到聚合的报告结果,包含html和xml:

jacoco

这个过程发生了什么?

  • 先通过maven运行单元测试,并在每个模块生成jacoco.exec执行数据文件
  • 使用maven指定jacoco.xml文件作为pom文件,利用ant插件聚合单元测试覆盖率报告
  • ant插件通过executiondata标签的配置搜集jacoco的数据文件
  • ant插件通过structure标签的配置读取项目源码和字节码
  • org.jacoco.ant.ReportTask类通过ant插件加载的执行数据和源码计算覆盖率生成报告

如果这时候希望聚合上报结果到sonar,则需要将sonar-project.properties中的报告路径配置为聚合报告的结果:

sonar.coverage.jacoco.xmlReportPaths=../target/coverage-report/coverage-report.xml

相关文章:

jacoco生成单元测试覆盖率报告

前言 单元测试是日常编写代码中常用的&#xff0c;用于测试业务逻辑的一种方式&#xff0c;单元测试的覆盖率可以用来衡量我们的业务代码经过测试覆盖的比例。 目前市场上开源的单元测试覆盖率的java插件&#xff0c;主要有Emma&#xff0c;Cobertura&#xff0c;Jacoco。具体…...

【CSS Tricks】如何做一个粒子效果的logo

效果展示 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>粒子效果Logo</title>…...

如何使用ssm实现基于Javaweb的网上花店系统的设计与实现

TOC ssm653基于Javaweb的网上花店系统的设计与实现jsp 研究背景 自计算机发展以来给人们的生活带来了改变。第一代计算机为1946年美国设计&#xff0c;最开始用于复杂的科学计算&#xff0c;占地面积、开机时间要求都非常高&#xff0c;经过数十几的改变计算机技术才发展到今…...

Elastic 的 OpenTelemetry PHP 发行版简介

作者&#xff1a;Pawel Filipczak 宣布 OpenTelemetry PHP 的 Elastic 发行版的第一个 alpha 版本。在本篇博文中了解使用 OpenTelemetry 来检测 PHP 应用程序是多么简单。 我们很高兴推出 OpenTelemetry PHP 的 Elastic Distribution 的第一个 alpha 版本。在这篇文章中&…...

TCP 和 UDP 协议的区别?

参考TCP 和 UDP的区别_tcp和udp的区别-CSDN博客...

【PHP】使用thinkphp5查询最大值时,把varchar类型字段转换成数字

有时候我们需要把carchar类型的字段进行聚合函数运运行&#xff08;max、min、avg&#xff09;&#xff0c;但是如果直接用聚合函数&#xff0c;得到的结果是错误的&#xff0c;因为varchar字段是字符串&#xff0c;无法直接使用聚合函数&#xff0c;所以需要把varchar字段转换…...

Java 正则表达式详解

正则表达式 (Regular Expression&#xff0c;简称 regex) 是一种强大的文本处理工具&#xff0c;可以用来匹配、搜索和替换文本中的特定模式。在 Java 中&#xff0c;正则表达式由 java.util.regex 包提供支持。 1. 理解正则表达式语法 正则表达式使用特殊的字符和符号来定义…...

MySQL篇(窗口函数/公用表达式(CTE))(持续更新迭代)

目录 讲解一&#xff1a;窗口函数 一、简介 二、常见操作 1. sumgroup by常规的聚合函数操作 2. sum窗口函数的聚合操作 三、基本语法 1. Function(arg1,..., argn) 1.1. 聚合函数 sum函数&#xff1a;求和 min函数 &#xff1a;最小值 1.2. 排序函数 1.3. 跨行函数…...

Jira Cloud涨价5%-20%,钉钉项目Teambition成优选替代

近日&#xff0c;Jira再次宣布涨价&#xff0c;Cloud版涨幅达到5%-20%&#xff0c;这一消息来源于Atlassian官方面向合作伙伴发布的2024年最新涨价通知。 Atlassian旗下核心产品&#xff0c;包括Jira、Confluence、JiraServiceManagement等的Cloud版本价格将有所提高&#xff…...

Python语言基础教程(下)4.0

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…...

【HTTP】构造HTTP请求和状态码

状态码 用于响应中&#xff0c;表示响应的结果如何 正确&#xff1f;错误&#xff1f;什么原因&#xff1f; HTTP 中的状态码都是标准约定好的 200 OK 成功了&#xff0c;一切顺利 在抓包到的响应中 404 Not Found 访问的资源&#xff08;URL 中的路径&#xff09;没找…...

Delta Lake如何使用

1. 安装 Java 确保你的系统上安装了 Java 8 或更高版本。可以通过以下命令检查 Java 是否已安装&#xff1a; java -version2. 安装 Apache Spark 下载 Spark&#xff1a; 从 Apache Spark 官方网站 下载适合的版本&#xff0c;建议下载预编译的版本&#xff08;例如&#xf…...

面试题 - parallelStream() 有什么缺点 - ForkJoinPool,它和传统的线程池(如 ThreadPoolExecutor)的区别

底层使用 ForkJoinPool &#xff0c;不同与线程池适用于连续的内存分布的数据结构&#xff0c;如数组和ArrayList()&#xff0c;并不适用于链表适用于 cpu 密集的工作&#xff0c;cpu 的核数多效率高&#xff0c;并行流能否真正提高性能&#xff0c;很大程度上取决于系统的可用…...

切换淘宝最新镜像源npm详细讲解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 在中国大陆&#xff0c;npm&#xff08;Node Package Manager&#xff09;的默认源由于网络限制&#xff0c;速度可能较慢。为了解决这个问题&#xff0c;淘宝提供了一个镜像源&#xff0c;它同步了 npm 的…...

STM32F407单片机编程入门(十二) FreeRTOS实时操作系统详解及实战含源码

文章目录 一.概要二.什么是实时操作系统三.FreeRTOS的特性四.FreeRTOS的任务详解1.任务函数定义2.任务的创建3.任务的调度原理 五.CubeMX配置一个FreeRTOS例程1.硬件准备2.创建工程3.调试FreeRTOS任务调度 六.CubeMX工程源代码下载七.小结 一.概要 FreeRTOS是一个迷你的实时操…...

网络安全-利用 Apache Mod CGI

目录 一、环境 二、开始操作 三、总结 一、环境 蚁剑官网拉取 二、开始操作 蚁剑连接 一样终端命令不能执行 可以看到putenv已经禁用 我们开始一下&#xff0c;跳入一个新终端且可以执行命令 我们具体看一下干了什么事情 上传了一个htaccess这个文件的作用是让以后所有ant文…...

ACE之ACE_Reactor_Notify

简介 ACE_Reactor_Notify作为Reactor的实现类ACE_Reactor_Impl内部通知来唤醒eventloop 抽象 #mermaid-svg-9UguTLk5S9joDMfi {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-9UguTLk5S9joDMfi .error-icon{fill:#…...

【小沐学GIS】blender导入OpenStreetMap城市建筑(blender-osm、blosm)

文章目录 1、简介1.1 blender1.2 osm地图 2、OpenStreetMap下载方式2.1 Simple2.2 Overpass API2.3 OSM星球2.4 Geofabrik下载2.5 其他方法2.6 BBBike 3、blender-osm插件3.1 简介3.2 操作 结语 1、简介 1.1 blender https://www.blender.org/ Blender 是一款免费的开源 3D …...

数字IC设计\FPGA 职位经典笔试面试整理--语法篇 Verilog System Verilog(部分)

注&#xff1a; 资料都是基于网上一些博客分享和自己学习整理而成的 Verilog 1. 数据类型 Verilog一共有19种数据类型 基础四种数据类型&#xff1a;reg型&#xff0c;wire型&#xff0c;integer型&#xff0c;parameter型 reg型   reg类型是寄存器数据类型的关键字。寄存…...

【EtherCAT】CiA402简介

目录 1、CiA402是CANopen协议的子协议 2、CiA402是 用于驱动和运动控制的CANopen设备配置文件 3、 CiA402主要由三部分组成 4、CiA介绍 4.1、操作模式 4.2、对象字典 5、一般对象字定义 6、详细对象字定义 7、Profile position mode 8、Homing mode 9、 Position co…...

基于Java(SpringBoot、Mybatis、SpringMvc)+MySQL实现(Web)小二结账系统

结账系统 1.引言 1.1.编写目的 此说明书在概要设计的基础上&#xff0c;对小二结账系统的各个模块、程序分别进行了实现层面上的要求和说明。在以下的详细设计报告中将对在本阶段中对系统所做的所有详细设计进行说明。在本阶段中&#xff0c;确定应该如何具体的实现所要求的…...

echarts柱状图实现动态展示时报错

echarts柱状图实现动态展示时报错 1、问题&#xff1a; 在使用Echarts柱状图时&#xff0c;当数据量过多&#xff0c;x轴展示不下的时候&#xff0c;可以使用dataZoom实现动态展示。如下图所示&#xff1a; 但是当鼠标放在图上面滚动滚轮时或拖动滚动条时会报错&#xff0c;…...

Komiko 视频到视频功能炸裂上线!

Komiko 平台作为行业的创新先锋&#xff0c;近日宣布推出全新的视频到视频&#xff08;Video-to-Video&#xff09;功能&#xff0c;这一举措犹如一颗重磅炸弹&#xff0c;瞬间在漫画、动画和插画创作的世界里掀起了惊涛骇浪&#xff0c;进一步巩固了其作为 AI 驱动的一体化创作…...

软件工程:如何做好软件产品

1、什么是产品 从项目到产品 产品&#xff1a;满足行业共性需求的标准产品。即要能够做到配置化的开发&#xff0c;用同一款产品最大限度地满足不同客户的需求&#xff0c;同时让产品具有可以快速响应客户需求变化的能力。 好的产品一定吸收了多个项目的共性&#xff0c;一定是…...

《前端面试题:CSS的display属性》

CSS display属性完全指南&#xff1a;深入理解布局核心属性 掌握display属性是CSS布局的基石&#xff0c;也是前端面试必考知识点 一、display属性概述&#xff1a;布局的核心控制 display属性是CSS中最重要、最基础的属性之一&#xff0c;它决定了元素在页面上的渲染方式和布…...

Webhook 配置备忘

本文地址&#xff1a;blog.lucien.ink/archives/552 将下列代码保存为 install.sh&#xff0c;然后 bash install.sh。 #!/usr/bin/env bash set -e wget https://github.mirrors.lucien.ink/https://github.com/adnanh/webhook/releases/download/2.8.2/webhook-linux-amd64.…...

掌握子网划分:优化IP分配与管理

子网划分是通过调整子网掩码&#xff0c;将单一IP网络划分为多个逻辑子网的过程&#xff0c;其核心原理是借用主机位作为子网位以优化地址分配和管理。具体方法与原理如下&#xff1a; 一、子网划分基本原理 核心目的&#xff1a; 减少IP浪费&#xff1a;避免大块地址闲置&…...

【Python 算法零基础 4.排序 ⑨ 堆排序】

目录 一、问题描述 二、算法对比 1.朴素算法 ① 数组模拟容器 ② 有序数组模拟容器 2.二叉堆 ① 二叉堆特点 ② 数组表示二叉树 ③ 堆 ④ 大顶堆 ⑤ 小顶堆 ⑥ 元素插入 ⑦ 获取堆顶 ⑧ 堆顶元素删除 三、代码分析 1.工具函数 2.调整大顶堆函数 Ⅰ、计算子节点索引 Ⅱ、找出最…...

uniapp 集成腾讯云 IM 消息搜索功能

UniApp 集成腾讯云 IM 消息搜索功能实战指南 一、功能实现原理 腾讯云 IM 通过 消息漫游 服务端搜索接口 实现消息检索&#xff0c;核心机制如下&#xff1a; 数据存储&#xff1a;消息默认存储7天&#xff08;可扩展至30天&#xff09;索引构建&#xff1a;基于消息内容自…...

VMware 安装 CentOS8详细教程 (附步骤截图)附连接公网、虚拟机yum源等系统配置

1 下载安装镜像 centos8官方源已下线,旧的下载地址已不可用,需要切换centos-vault源 华为云CentOS8镜像下载地址 阿里云CentOS8镜像下载地址 中科大CentOS8镜像下载地址 2 安装CentOS8 2.1 创建虚拟机 打开VMware Workstation 左上角 文件-新建虚拟机...