一文搞懂JaCoCo Java代码覆盖率工具

目录

1. JaCoCo 简介

2. JaCoCo 原理

2.1 on-the-fly模式

2.2 offline模式

2.3 on-the-fly和offline对比

3. JaCoCo 使用

3.1 Ant Tasks —— Apache Ant 方式

3.2 Java Agent —— 命令行方式

3.2.1 官方介绍

3.2.2 流程说明

3.2.3 举例

3.3 Maven Plug-in —— Apache Maven 方式

3.4 Eclipse EclDmma Plugin 方式

3.5 Jenkins集成


参考资料:

官方文档

JAVA代码覆盖率工具JaCoCo-原理篇

JAVA代码覆盖率工具JaCoCo-实践篇

JaCoCo控制流分析

 

1. JaCoCo 简介

JaCoCo Java Code Coverage Library

JaCoCo is a free code coverage library for Java, which has been created by the EclEmma team based on the lessons learned from using and integration existing libraries for many years.

 

是一个免费的Java代码覆盖库。

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

 

  • 标示绿色的为行覆盖充分
  • 标红色的为未覆盖的行
  • 黄色菱形的为分支部分覆盖
  • 绿色菱形为分支完全覆盖

 

2. JaCoCo 原理

Jacoco使用插桩的方式来记录覆盖率数据,是通过一个probe探针来注入。

插桩模式有两种:

2.1 on-the-fly模式

JVM通过 -javaagent参数指定jar文件启动代理程序,代理程序在ClassLoader装载一个class前判断是否修改class文件,并将探针插入class文件,探针不改变原有方法的行为,只是记录是否已经执行。

2.2 offline模式

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

2.3 on-the-fly和offline对比

on-the-fly更方便简单,无需提前插桩,无需考虑classpath设置问题。

以下情况不适合使用on-the-fly模式:

(1)不支持javaagent

(2)无法设置JVM参数

(3)字节码需要被转换成其他虚拟机

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

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

 

3. JaCoCo 使用

 

3.1 Ant Tasks —— Apache Ant 方式

参见 https://www.eclemma.org/jacoco/trunk/doc/ant.html

 

3.2 Java Agent —— 命令行方式

参见

http://www.eclemma.org/jacoco/trunk/doc/agent.html

https://www.jacoco.org/jacoco/trunk/doc/cli.html

3.2.1 官方介绍

JaCoCo使用class文件插桩来记录执行覆盖率数据。class文件是使用Java代理(Java agent)动态检测的。这种机制允许在类加载期间独立于应用程序框架对所有类文件进行内存预处理。

JaCoCo代理收集执行信息,并在请求时或JVM退出时转储它。有三种不同的执行数据输出模式:

  1. File System:在JVM终止时,执行数据被写入本地文件。
  2. TCP Socket Server:外部工具可以连接到JVM并通过套接字连接检索执行数据。执行数据重置和JVM退出的执行数据转储。
  3. TCP Socket Client:在启动时JaCoCo代理连接到给定的TCP端点(endpoint)。执行数据根据请求写入套接字连接。执行数据重置和JVM退出时的执行数据转储。

 

jacocoagent.jar文件是JaCoCo发行版的一部分,包含所有必需的依赖项。

可以使用以下JVM选项激活Java代理:

-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]

参数说明:

Option

Description

Default

destfile

Path to the output file for execution data.

jacoco.exec

append

If set to true and the execution data file already exists, coverage data is appended to the existing file. If set to false, an existing execution data file will be replaced.

true

includes

A list of class names that should be included in execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?). Except for performance optimization or technical corner cases this option is normally not required.

* (all classes)

excludes

A list of class names that should be excluded from execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?). Except for performance optimization or technical corner cases this option is normally not required. If you want to exclude classes from the report please configure the respective report generation tool accordingly.

empty (no excluded classes)

exclclassloader

A list of class loader names that should be excluded from execution analysis. The list entries are separated by a colon (:) and may use wildcard characters (* and ?). This option might be required in case of special frameworks that conflict with JaCoCo code instrumentation, in particular class loaders that do not have access to the Java runtime classes.

sun.reflect.DelegatingClassLoader

inclbootstrapclasses

Specifies whether also classes from the bootstrap classloader should be instrumented. Use this feature with caution, it needs heavy includes/excludes tuning.

false

inclnolocationclasses

Specifies whether also classes without a source location should be instrumented. Normally such classes are generated at runtime e.g. by mocking frameworks and are therefore excluded by default.

false

sessionid

A session identifier that is written with the execution data. Without this parameter a random identifier is created by the agent.

auto-generated

dumponexit

If set to true coverage data will be written on VM shutdown. The dump can only be written if either file is specified or the output is tcpserver/tcpclient and a connection is open at the time when the VM terminates.

true

output

Output method to use for writing coverage data. Valid options are:

file: At VM termination execution data is written to the file specified in the destfile attribute.

tcpserver: The agent listens for incoming connections on the TCP port specified by the address and port attribute. Execution data is written to this TCP connection.

tcpclient: At startup the agent connects to the TCP port specified by the address and port attribute. Execution data is written to this TCP connection.

none: Do not produce any output.

Please see the security considerations below.

file

address

IP address or hostname to bind to when the output method is tcpserver or connect to when the output method is tcpclient. In tcpserver mode the value "*" causes the agent to accept connections on any local address.

loopback interface

port

Port to bind to when the output method is tcpserver or connect to when the output method is tcpclient. In tcpserver mode the port must be available, which means that if multiple JaCoCo agents should run on the same machine, different ports have to be specified.

6300

classdumpdir

Location relative to the working directory where all class files seen by the agent are dumped to. This can be useful for debugging purposes or in case of dynamically created classes for example when scripting engines are used.

no dumps

jmx

If set to true the agent exposes functionality via JMX under the name org.jacoco:type=Runtime. Please see the security considerations below.

false

report

java -jar jacococli.jar report [<execfiles> ...] --classfiles <path> [--csv <file>] [--encoding <charset>] [--help] [--html <dir>] [--name <name>] [--quiet] [--sourcefiles <path>] [--tabwith <n>] [--xml <file>]

参数说明:

Option

Description

Required

Multiple

<execfiles>

list of JaCoCo *.exec files to read

 

--classfiles <path>

location of Java class files

--csv <file>

output file for the CSV report

  

--encoding <charset>

source file encoding (by default platform encoding is used)

  

--help

show help

  

--html <dir>

output directory for the HTML report

  

--name <name>

name used for this report

  

--quiet

suppress all output on stdout

  

--sourcefiles <path>

location of the source files

 

--tabwith <n>

tab stop width for the source pages (default 4)

  

--xml <file>

output file for the XML report

  

3.2.2 流程说明

 

3.2.3 举例

现有sprintbootdemo项目如下:

 

打包放置临时目录

运行命令:

java -javaagent:F:/tools/jacoco-0.8.6/lib/jacocoagent.jar=output=file,destfile=test-jacoco.exec -Dserver.port=8090 -jar test-0.0.1-SNAPSHOT.jar

启动spring程序

 

浏览器访问对应网址 localhost:8090

控制台输出对应打印内容,页面显示 Hello Springboot返回值

 

证明调用成功。

Ctrl + C 停止 JVM

 

当前目录生成 test-jacoco.exec 文件。

运行 report生成命令生成report

java -jar F:/tools/jacoco-0.8.6/lib/jacococli.jar report test-jacoco.exec --classfiles ./test-0.0.1-SNAPSHOT/BOOT-INF/classes --html ./test-report --sourcefiles E:\test_code\Java\testSpringboot\test\src\main\java

classesfiles和sourcefiles写对应自己项目的文件目录

 

如上提示,分析成功。

查看当前目录生成test-report文件夹。进入文件夹,以浏览器方式打开index.html

 

结果如下:

 

可选择相应文件查看结果。如:

 

可见结果与上述预期一致,Impl1覆盖,而Impl2未覆盖。

 

3.3 Maven Plug-in —— Apache Maven 方式

参见 http://www.eclemma.org/jacoco/trunk/doc/maven.html

 

3.4 Eclipse EclDmma Plugin 方式

 

3.5 Jenkins集成

 

 

 

 


版权声明:本文为d_chunyu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。