目录
3.1 Ant Tasks —— Apache Ant 方式
3.3 Maven Plug-in —— Apache Maven 方式
参考资料:
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退出时转储它。有三种不同的执行数据输出模式:
- File System:在JVM终止时,执行数据被写入本地文件。
- TCP Socket Server:外部工具可以连接到JVM并通过套接字连接检索执行数据。执行数据重置和JVM退出的执行数据转储。
- 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集成