【测试】代码覆盖率工具 JaCoCo

JaCoCo 是面向 Java 的开源代码覆盖率工具,JaCoCo 以 Java 代理模式运行,它负责在运行测试时检测字节码。JaCoCo 会深入研究每个指令,并显示每个测试过程中要执行的行。为了收集覆盖率数据,JaCoCo 使用 ASM 即时进行代码检测,并在此过程中从 JVM Tool Interface 接收事件,最终生成代码覆盖率报告。

在这里插入图片描述
JaCoCo 运行有 离线offline)、在线on the fly)模式之说,所谓在线模式就是在应用启动时加入 jacoco agent 进行 插桩,在开发、测试人员使用应用期间实时地进行代码覆盖率分析。相信很多的 Java 项目开发人员并不会去写单元测试代码的,因此覆盖率统计就要把手工测试或接口测试覆盖的情况作为重要依据,显然在线模式更符合实际需求,本文以在线模式为例进行演示。

1.Jacoco 安装

官网下载最新版本并解压到指定目录。

在这里插入图片描述

主要用到如下两个 jar 包:

在这里插入图片描述
在线模式 Jacoco 覆盖率统计包含三个步骤:

  • 启动应用增加 jacoco agent 进行插桩,该步骤会启动 TCP Server。
  • 从 TCP Server dump 生成代码覆盖率文件,生成的文件格式为 .exec 格式的二进制文件。
  • 解析 .exec 格式文件生成 html 格式代码覆盖率报告。

2.准备 Java 示例代码

事先需要创建 Java 示例代码,本文不聚焦 Java 代码相关的内容,大家可以使用自己的 Java 项目代码进行验证,或者直接 clone 本文提供的 Spring Boot 示例代码仓库:https://gitee.com/pepperpapa/jacoco_demo

注意:在线模式使用的代码一定要是类似 Web 应用这种永远不会退出的程序为例,因为收集 jacoco agent 要启用 TCP Server,如果程序执行完就退出了 TCP Server 也就无法关闭了。

在这里插入图片描述

示例代码就是提供两个简单的 URL 访问,访问截图如下:

  • http://127.0.0.1:8080/hello
    在这里插入图片描述
  • http://127.0.0.1:8080/byebye
    在这里插入图片描述

执行构建命令 mvn clean package 后,会在 target 目录生成可运行的 jar 包。

在这里插入图片描述

3.启动 jacoco agent 进行插桩

打开 cmdcd 到示例代码的 target 目录,执行如下命令:

java -javaagent:C:\工具\jacoco-0.8.6\lib\jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=localhost,append=true -jar demo-0.0.1-SNAPSHOT.jar

关键参数说明:

  • -javaagent:C:\工具\jacoco-0.8.6\lib\jacocoagent.jar=includes=*,这个参数就是启用 Jacoco 代理参数,其中 C:\工具\jacoco-0.8.6\lib\jacocoagent.jar 就是之前下载 Jacoco 解压后的 jacocoagent.jar 的绝对路径,includes 表示对要插桩的包进行过滤,* 代表所有的 class 都要进行插桩,也可以根据情况进行过滤,如 includes=com.mycompany.*
  • output=tcpserver,这里不需要改动,表示以 TCP Server 方式启动应用并插桩。
  • port=6300,Jacoco 开启的 TCP Server 的端口,不能被占用。
  • address=localhost,对外开放的地址,也可以指定 IP 地址。
  • demo-0.0.1-SNAPSHOT.jar,就是示例代码构建后 target 目录生成的 jar 包,需要根据实际情况更新。

执行后就会启动 Web 服务,截图如下:

在这里插入图片描述

特别提醒:为了对比实时统计代码覆盖率的效果,此时请先不要请求上面提到的任何一个 URL,切记!

4.dump 生成覆盖率文件

保持服务启动,再打开一个 cmd 窗口同样 cdtarget 目录,执行如下命令从上一步开启的 TCP Server 中 dump 出覆盖率文件:

java -jar C:\工具\jacoco-0.8.6\lib\jacococli.jar dump --address localhost --port 6300 --destfile ./jacoco_tcp_01.exec

参数说明:

  • --destfile ./jacoco_tcp.exec,其中 ./jacoco_tcp.exec 为生成 exec 文件名,表示在当前目录生成。
  • 其他参数和上一步类似,不再特别说明,注意需要更新 jacococli.jar 的绝对路径。

执行成功后,会在 target 目录生成相应的 .exec 文件。

在这里插入图片描述
接下来,我们在浏览器中访问该web示例应用提供的两个 URL,http://127.0.0.1:8080/hellohttp://127.0.0.1:8080/byebye,应用会调用相应的方法并正常返回结果。

然后,我们再次执行 dump 命令再生成一个 .exec 文件,命名为 jacoco_tcp_02.exec

java -jar C:\工具\jacoco-0.8.6\lib\jacococli.jar dump --address localhost --port 6300 --destfile ./jacoco_tcp_02.exec

5.分析 exec 文件生成 html 报告

dump 命令生成的 .exec 文件为二进制文件,需要进行解析,以生成 html 报告为例,执行如下的命令分别将两个 .exec 文件解析成 html 报告。

java -jar C:\工具\jacoco-0.8.6\lib\jacococli.jar report ./jacoco_tcp_01.exec --classfiles .\classes --sourcefiles ..\src\main\java --html report01
java -jar C:\工具\jacoco-0.8.6\lib\jacococli.jar report ./jacoco_tcp_02.exec --classfiles .\classes --sourcefiles ..\src\main\java --html report02

参数说明:

  • ./jacoco_tcp_01.exec,表示要解析的 exec 文件的相对路径。
  • --classfiles .\classes,需要指定生成的 classes 文件目录,参见下图。
  • --sourcefiles ..\src\main\java,需要指定源码的文件目录,参见下图。

在这里插入图片描述

最终,target 目录会生成 report01report02 两个目录,分别打开其中的 index.html 查看代码覆盖率结果。

我们发现 report01 中的代码覆盖率为 73 % 73\% 73%,其中 say()bybye() 两个方法没有被覆盖:

在这里插入图片描述
在这里插入图片描述
而我们访问了对应的服务之后生成的 report02 覆盖率报告为 100%,say()bybye() 这两个方法都覆盖到了:

在这里插入图片描述
在这里插入图片描述

6.覆盖率指标说明

  • Instructions:Java 字节 指令的覆盖率。执行的最小单位,和代码的格式无关。
  • Branches分支覆盖率。注意,异常处理不算做分支。
  • CxtyCyclomatic Complexity):圈复杂度,Jacoco 会为每一个非抽象方法计算圈复杂度,并为类、包以及组(groups)计算复杂度。圈复杂度简单地说就是为了覆盖所有路径,所需要执行单元测试数量,圈复杂度大说明程序代码可能质量低且难于测试和维护。
  • Lines行覆盖率,只要本行有一条指令被执行,则本行则被标记为被执行。
  • Methods方法覆盖率,任何非抽象的方法,只要有一条指令被执行,则该方法就会被计为被执行。
  • Classes类覆盖率,所有类,包括接口,只要其中有一个方法被执行,则标记为被执行。注意:构造函数和静态初始化块也算作方法。
### JaCoCo 使用指南及相关信息 JaCoCoJava Code Coverage Library)是一款开源的Java代码覆盖率工具,它提供了详细的代码覆盖信息,帮助开发人员了解测试用例对代码的覆盖情况[^4]。以下是关于JaCoCo的主要特点和使用方法的详细介绍。 #### 一、JaCoCo 的主要特点 1. **精确度高**:JaCoCo能够提供准确的代码覆盖率数据,帮助开发人员评估测试用例的有效性。 2. **支持多种测试框架**:JaCoCo支持JUnit、TestNG等多种常用的Java测试框架,可以与不同的测试框架无缝集成。 3. **灵活的配置选项**:JaCoCo提供了丰富的配置选项,可以根据项目的需求进行灵活的配置,满足不同项目的测试需求。 4. **可视化的报告**:JaCoCo可以生成直观、易于理解的代码覆盖率报告,通过图表和图形展示代码的覆盖情况,帮助开发人员快速定位问题和改进点。 5. **与构建工具集成**:JaCoCo可以与常见的构建工具(如Maven、Gradle、SBT)集成,方便开发人员在构建过程中自动执行代码覆盖率检查,并生成相应的报告[^4]。 #### 二、JaCoCo 的覆盖率统计类型 JaCoCo支持以下几种覆盖率统计类型: - 指令覆盖率(Instruction Coverage) - 分支覆盖率(Branch Coverage) - 行覆盖率(Line Coverage) - 方法覆盖率(Method Coverage) - 类覆盖率(Class Coverage) 这些统计类型可以帮助开发人员全面了解代码的覆盖情况,从而发现潜在的问题和改进空间[^4]。 #### 三、JaCoCo 在不同环境中的使用方法 ##### 1. 在 SBT 环境中使用 JaCoCo 在 SBT 项目中,可以通过 `sbt-jacoco` 插件来集成 JaCoCo。以下是基本配置示例: ```scala // 开启 JaCoCo 插件 jacoco.settings // 自定义报告路径(如果需要) jacoco.reportDirectories := Seq(baseDirectory.value / "reports/jacoco") // 排除某些包或类不参与覆盖率计算 jacoco.excludes := Seq("com.example.*.utils.*") ``` 通过上述配置,可以控制报告的生成与格式,并排除不需要参与覆盖率计算的包或类[^1]。 ##### 2. 在 Gradle 环境中使用 JaCoCo 在 Gradle 项目中,可以通过简单的插件应用来开启 JaCoCo 功能。以下是配置示例: ```groovy plugins { id 'jacoco' } task jacocoTestReport(type: JacocoReport) { afterEvaluate { classDirectories.from = sourceSets.main.output executionData.from(fileTree(dir: '.').include('**/jacoco/test.exec')) reports { html.destination "${project.buildDir}/reports/jacoco" } } } ``` 通过上述配置,可以在构建过程中自动生成 HTML 格式的覆盖率报告[^2]。 ##### 3. 在命令行中使用 JaCoCo 如果需要在命令行中使用 JaCoCo,可以按照以下步骤操作: 1. 编译被测程序: ```bash javac -cp xxxxxx[依赖] xxx.java ``` 2. 使用 `javaagent` 插桩运行被测程序: ```bash java -cp xxxxxx[依赖] -javaagent:[yourpath/]jacocoagent.jar=destfile=xxxx.exec xxx[被测程序] xxxxx[输入] ``` 通过上述步骤,可以手动运行被测程序并生成覆盖率数据文件[^3]。 #### 四、JaCoCo 的应用场景 JaCoCo 可以广泛应用于各种 Java 开发场景,例如: - 单元测试覆盖率分析 - 集成测试覆盖率分析 - 持续集成流程中的覆盖率检查 - 毕业设计或科研项目中的覆盖率统计[^3] ### 示例代码 以下是一个简单的 JaCoCo 报告生成示例(基于 Gradle): ```groovy plugins { id 'java' id 'jacoco' } jacocoTestReport { dependsOn test reports { xml.required = true csv.required = false html.required = true } } ``` 通过上述配置,可以在测试完成后生成 XML 和 HTML 格式的覆盖率报告。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G皮T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值