jacoco统计覆盖率最佳实践

  • jacoco总结
    • Jacoco安装
    • 代码覆盖率介绍
      • 行覆盖
      • 分支覆盖
      • 方法覆盖
      • 覆盖率的误区
      • 代码覆盖率意义
    • 覆盖率报告解析
    • 启动jacoco agent进行插桩
      • **单元测试offline模式:**
        • mvn命令增加参数
      • 在pom文件中添加jacoco插件
      • **功能测试on-the-fly模式**:
        • 启jacoco命令:
        • dump - 生成exec文件
        • report - 生成报告
        • instrument - Java类文件和JAR文件的离线检测。
        • merge - 将多个exec文件合并到一个新的exec文件中。
        • classinfo - 在提供的位置打印有关Java类文件的信息。
        • execinfo - 以可读格式打印exec文件内容

jacoco总结

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

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

Jacoco安装

从官网
https://www.jacoco.org/jacoco/下载最新版本并解压到指定目录

代码覆盖率介绍

覆盖率是用来衡量测试代码对功能代码的测试情况。通过统计测试代码中对功能代码中行、分支、类等模拟场景数量,来量化说明测试的充分度。

代码覆盖率=代码的覆盖程度,一种度量方式。

覆盖率简单说:跑了一个测试用例,项目代码中的那些模块、文件、类、方法 执行了。

其中行覆盖率是最细颗粒度,其他覆盖率都可从行覆盖率情况统计算出来。

行覆盖

当至少一个指令被指定源码行执行时,该源码行被认为已执行。

通俗的说就是,测试行为,触发了这某一行代码,则这一行代码就被覆盖了。

分支覆盖

if 和switch 语句算作分支覆盖率,这个指标计算一个方法中的分支总数,并决定已执行和未执行的分支的数量。

全部未覆盖:所有分支均未执行,红色标志

部分覆盖:部分分支被执行,黄色标志

全覆盖:所有分支均已执行,绿色标志。

方法覆盖

当方法中至少有一个指令被执行,该方法被认为已执行,包括构造函数和静态初始化方法。

覆盖率的误区

若代码如下:

if (i>100)j = 10/i        // 没有除0错误
elsej = 10/(i+2)    // i==-2,除0错误

覆盖2个分支,只需要设计i101 和 i1,但是对于找到i==-2这个bug点时没有作用的。

所以:

1、不要简单的追求高的代码覆盖率

2、高覆盖率测试用例不等于测试用例有效

3、没覆盖的分支相当于该分支上的任何错误肯定都找不到

代码覆盖率意义

分析未覆盖部分的代码,反推测试设计是否充分,没有覆盖到的代码是否存在测试设计盲点。

覆盖率报告解析

  • Instructions: Java 字节指令的覆盖率。执行的最小单位,和代码的格式无关。

  • Branches: 分支覆盖率。注意,异常处理不算做分支。

  • Cxty(Cyclomatic Complexity): 圈复杂度, Jacoco 会为每一个非抽象方法计算圈复杂度,并为类,包以及组(groups)计算复杂度。

    圈复杂度简单的说就是为了覆盖所有路径,所需要执行单元测试数量,圈复杂度大说明程序代码可能质量低且难于测试和维护。

  • Lines: 行覆盖率,只要本行有一条指令被执行,则本行则被标记为被执行。

  • Methods: 方法覆盖率,任何非抽象的方法,只要有一条指令被执行,则该方法被计为被执行。

  • Classes: 类覆盖率,所有类,包括接口,只要其中有一个方法被执行,则标记为被执行。注意:构造函数和静态初始化块也算作方法。

类角度相信信息

  • 钻石代表分支覆盖情况、背景颜色代表指令覆盖率

  • 红色钻石/背景:这一行没有分支/指令被执行

  • 黄色钻石/背景:这一行中只有部分分支/指令被执行

  • 绿色钻石/背景:这一行的所有分支/指令都被执行

启动jacoco agent进行插桩

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

,offline模式和on-the-fly模式。

单元测试offline模式:

对应的是jacoco的offline模式。

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

在脱机模式下,可以使用与代理可用的相同财产集配置JaCoCo运行时,除了类文件已经插入指令的include/excludes选项之外。有两种不同的方式来提供配置:

配置文件:如果在类路径选项中提供了文件jacoco-agent.properties,则从该文件加载。文件必须格式化为Java配置文件格式。

系统配置:选项也可以作为Java系统配置提供。在这种情况下,选项必须以“jacoco-agent”为前缀。例如,*.exec文件的位置可以用系统属性“jacoco-angent.destfile”配置。

<project><reporting><plugins><plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><reportSets><reportSet><reports><!-- select non-aggregate reports --><report>report</report></reports></reportSet></reportSets></plugin></plugins></reporting>
</project>

离线调用jacoco有两种方式,第一种是命令行方式调用jacoco的插件,另外一种是直接在maven中配置jacoco插件。

之前项目中曾经调研过其实还有第三种方式,我是在maven调用是开启了jacoco的代理在maven参数中,官方没有写这样用的方式所以不建议。

mvn命令增加参数

在执行mvn命令时,加上“org.jacoco:jacoco-maven-plugin:prepare-agent”参数即可。 示例:

mvn clean test org.jacoco:jacoco-maven-plugin:0.7.3.201502191951:prepare-agent install -Dmaven.test.failure.ignore=true

在pom文件中添加jacoco插件

具体的配置方法如下:

1.添加依賴

<dependency><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.3</version>
</dependency>

2.配置plugins

      <plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.3</version><configuration><includes><include>com/**/*</include></includes></configuration><executions><execution><id>pre-test</id><goals><goal>prepare-agent</goal></goals></execution><execution><id>post-test</id><phase>test</phase><goals><goal>report</goal></goals></execution></executions></plugin>

其中包含(includes)或排除(excludes)字段的值应该是相对于目录/ classes /的编译类的类路径(而不是包名),使用标准通配符语法:

*   Match zero or more characters
**  Match zero or more directories
?   Match a single character

你也可以这样排除一个包和它的所有子包/子包:

<exclude>com/src/**/*</exclude>

这将排除某些包装中的每个课程,以及任何孩子。例如,com.src.child也不会包含在报表中。

也可以在pom中指定筛选规则:

      <plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>${jacoco.version}</version><configuration><includes><include>com/src/**/*</include></includes><!-- rules裏面指定覆蓋規則 --><rules><rule implementation="org.jacoco.maven.RuleConfiguration"><element>BUNDLE</element><limits>  <!-- 指定方法覆蓋到50% --><limit implementation="org.jacoco.report.check.Limit"><counter>METHOD</counter><value>COVEREDRATIO</value><minimum>0.50</minimum></limit><!-- 指定分支覆蓋到50% --><limit implementation="org.jacoco.report.check.Limit"><counter>BRANCH</counter><value>COVEREDRATIO</value><minimum>0.50</minimum></limit><!-- 指定類覆蓋到100%,不能遺失任何類 --><limit implementation="org.jacoco.report.check.Limit"><counter>CLASS</counter><value>MISSEDCOUNT</value><maximum>0</maximum></limit></limits></rule></rules></configuration><executions><execution><id>pre-test</id><goals><goal>prepare-agent</goal></goals></execution><execution><id>post-test</id><phase>test</phase><goals><goal>report</goal></goals></execution></executions></plugin>

此时运行mvn test生成index.html(即覆盖率报告)位置在:

也可以指定输出目录:

<execution><id>post-unit-test</id><phase>test</phase><goals><goal>report</goal></goals><configuration><dataFile>target/jacoco.exec</dataFile><outputDirectory>target/jacoco-ut</outputDirectory></configuration>
</execution>

功能测试on-the-fly模式

对应的是jacoco的on-the-fly模式。

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

启jacoco命令:

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

基本语法

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

示例

java -
javaagent:jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=localhost,append=true -jar
demo.jar

关键参数说明:

  • destfile 执行数据的输出文件的路径。
  • append 如果设置为true并且执行数据文件已经存在,则覆盖率数据将附加到现有文件中。如果设置为false,则将替换现有的执行数据文件。
  • includes 应包含在执行分析中的类名列表,意思就是要收集哪些类的覆盖率信息。列表条目由冒号(:)分隔,并且可以使用通配符(*和?)。除了性能优化或技术拐角情况外,通常不需要此选项。
  • excludes 应从执行分析中排除的类名列表。列表条目由冒号(:)分隔,并且可以使用通配符(*和?)。除了性能优化或技术拐角情况外,通常不需要此选项。如果您想从报告中排除类,请相应地配置相应的报告生成工具。与includes相反。
  • exclclassloader 应从执行分析中排除的类加载器名称的列表。列表条目由冒号(:)分隔,并且可以使用通配符(*和?)。如果特殊框架与JaCoCo代码插入冲突,特别是无法访问Java运行时类的类加载器,则可能需要此选项。
  • output 有 4 个值,分别是 file、tcpserver、tcpclient、mbean,默认是 file。使用 file 的方式只有在停掉应用服务的时候才能产生覆盖率文件,而使用 tcpserver 的方式可以在不停止应用服务的情况下下载覆盖率文件,后面会介绍如何使用 dump 方法来得到覆盖率文件。
    • file:在JVM终止时,执行数据被写入本地文件。
    • tcpserver:外部工具可以连接到JVM,并通过套接字连接检索执行数据。可以在虚拟机退出时进行可选的执行数据重置和执行数据转储。
    • tcpclient:在启动时,JaCoCo代理连接到给定的TCP端点。根据请求将执行数据写入套接字连接。可以在虚拟机退出时进行可选的执行数据重置和执行数据转储。
    • none:不做任何产出。
  • address 是 IP 地址,当输出方法为tcpserver时要绑定到的IP地址或主机名,或者当输出方法是tcpclient时要连接到的IP或主机名。在tcpserver模式中,值“*”会使代理接受任何本地地址上的连接。
  • port 是端口(输出方法为tcpserver时要绑定到的端口,或输出方法为tcpclient时要连接到的端口。在tcpserver模式下,端口必须可用,这意味着如果多个JaCoCo代理应在同一台计算机上运行,则必须指定不同的端口。
  • dumponexit 如果设置为真覆盖率,则将在VM关闭时写入数据。只有在指定了文件或输出为tcpserver/tcpclient并且VM终止时连接打开时,才能写入转储。
  • classdumpdir相对于代理看到的所有类文件转储到的工作目录的位置。这对于调试或动态创建的类(例如使用脚本引擎时)非常有用。

dump - 生成exec文件

基于参数

java -jar jacococli.jar dump [--address <address>] --destfile <path> [--help] [--port <port>] [--quiet] [--reset] [--retry <count>]
Option Description
--address <address> 要连接的主机名或ip地址(默认本地主机)
--destfile <path> 要将执行数据写入的文件
--help show help
--port <port> 要连接的端口(默认值为6300)
--quiet 禁止stdout上的所有输出
--reset 转储后重置测试目标上的执行数据
--retry <count> 重试次数(默认为10)
java -jar jacococli.jar dump --address 127.0.0.1 --port 6300 --destfile ./jacoco-demo.exec

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>]
java -jar jacococli.jar report jacoco-demo.exec --classfiles ../../../target/classes --sourcefiles ../../main/java --html http-report --xml report.xml --encoding=utf-8

注意 jacococli.jar 是放到了test下的resource下上述命令。

Option Description
<execfiles> 要读取的JaCoCo*.exec文件列表
--classfiles <path> Java类文件的位置
--csv <file> CSV报告的输出文件
--encoding <charset> 源文件编码(默认使用平台编码)
--help show help
--html <dir> HTML报表的输出目录
--name <name> 用于此报告的名称
--quiet 禁止stdout上的所有输出
--sourcefiles <path> 源文件的位置 ,既源码位置

instrument - Java类文件和JAR文件的离线检测。

基本参数

java -jar jacococli.jar instrument [<sourcefiles> ...] --dest <dir> [--help] [--quiet]
Option Description
<sourcefiles> 源文件的位置 ,既源码位置
--dest <dir> 将插入指令的Java类写入的路径
--help show help
--quiet suppress all output on stdout

merge - 将多个exec文件合并到一个新的exec文件中。

基本参数

java -jar jacococli.jar merge [<execfiles> ...] --destfile <path> [--help] [--quiet]
Option Description
<execfiles> 要读取的JaCoCo*.exec文件列表
--destfile <path> 将合并的执行数据写入的文件
--help show help
--quiet suppress all output on stdout

这个merge参数是讲多个exec整合为一个文件,据我使用经验来说有两方面用途吧,一是讲多个模块的覆盖率信息统计到一起,二是将n次相同模块的测试结果整合统计。都很有用。

示例

java -jar jacococli.jar merge jacoco-demo.exec jacoco-demo1.exec --destfile ./demo.exec

classinfo - 在提供的位置打印有关Java类文件的信息。

java -jar jacococli.jar classinfo [<classlocations> ...] [--help] [--quiet] [--verbose]
Option Description
<classlocations> Java类文件的位置
--help show help
--quiet suppress all output on stdout
--verbose show method and line number details

execinfo - 以可读格式打印exec文件内容

java -jar jacococli.jar execinfo [<execfiles> ...] [--help] [--quiet]
Option Description
<execfiles> list of JaCoCo *.exec files to read
--help show help
--quiet suppress all output on stdout

jacoco统计覆盖率最佳实践相关推荐

  1. 使用powermock 测试static 方法,jacoco统计覆盖率问题

    使用powermock 对private 和static 方法进行mock 测试, public class LogUtil {public static BaseAuditLog getLogBea ...

  2. 资源放送丨《Oracle 12C~19C统计信息的最佳实践》PPT视频

    前段时间,墨天轮邀请到云和恩墨解决方案专家 黄廷忠 分享了直播<Oracle 12C~19C统计信息的最佳实践>,在这里我们共享一下PPT和视频,供大家参考学习. 优化器是Oracle数据 ...

  3. 直播预告丨Oracle 12C~19C统计信息的最佳实践

    Oracle 12C~19C统计信息的最佳实践-08/11 优化器是Oracle数据库最大的黑盒子,决定着所有SQL语句在数据库中的执行计划,影响SQL语句运行的效率.统计信息做为优化器的指路人,为优 ...

  4. 直播预告丨 Oracle 12C~19C统计信息的最佳实践

    优化器是Oracle数据库最大的黑盒子,决定着所有SQL语句在数据库中的执行计划,影响SQL语句运行的效率.统计信息做为优化器的指路人,为优化器选择最佳执行计划不断输送信息.Oracle不断在为统计信 ...

  5. 代码覆盖率以及jacoco统计代码覆盖率的原理

    一.什么是代码覆盖率 简单来说,代码覆盖率是指,至少被执行了一次的条目数占整个条目数的百分比. 如果"条目数"是语句,对应的就是代码行覆盖率:如果"条目数"是函 ...

  6. jacoco + junit + mock 单测没有统计覆盖率问题

    使用junit :直接在pom文件中直接引入: <properties><project.build.sourceEncoding>UTF-8</project.buil ...

  7. jacoco统计server端功能测试覆盖率

    jacoco可以统计,功能测试时,server代码调用的覆盖情况.这里对服务器端的java代码进行统计.   操作步骤如下:   第一步:更改server的启动脚本,使用jacocoagent.jar ...

  8. Oracle 12c数据库优化器统计信息收集的最佳实践

    Oracle 12c数据库优化器统计信息收集的最佳实践 转载自     沃趣科技(ID:woqutech) 作者         刘金龙(译) 原文链接   http://www.oracle.com ...

  9. jacoco增量覆盖率实践

    Jacoco增量覆盖率说明 能找到这里,说明对jacoco的原理和使用有了一定的了解,而我写这边文章主要是网络上基本没有完整文档加代码的jaocco增量覆盖说明,所以我想分享些东西让需要这方面的人快速 ...

最新文章

  1. Django博客系统(写博客页面展示分类)
  2. OpenvSwitch — 操作实践
  3. getElementById取得文本框中的值
  4. JavaScript的鼠标事件
  5. java-并发-并发容器(3)
  6. mysql in 很大 优化_【转】mysql in语句优化
  7. boost::container模块实现范围分配器适配器
  8. Android Studio开发基础之自定义View组件
  9. InstallShield For .Net制作.Net项目安装包之完整代码
  10. Web前端工作笔记012---IE8兼容_WebSocket
  11. 跨境电商适合做独立站吗?是入平台好还是独立站好?
  12. Linux自动解压部署WEB项目脚本
  13. win7休眠设置在哪里_win7电脑不休眠怎么设置
  14. Linux 批量创建用户及设置随机密码
  15. 永远的《毕业生》之《Scarborough Fair》
  16. 关于网线水晶头的接法详解
  17. VS_设置护眼背景色
  18. 【外文翻译】外国友人写得很不错的Java Lambda表达式入门教程,我终于翻译好给大家啦!!!...
  19. Apache Cordova development lands on Visual Studio Code
  20. 小米商城热销模块样式

热门文章

  1. 适合新手了解的GUN/Linux起源
  2. Android13 适配指南
  3. 冰冰学习笔记:内存操作函数
  4. ret,retf,iret等的区别
  5. dockerfile制作:制作python3下的robotframework运行环境
  6. 漫画解读:什么是数据仓库?
  7. 图像化转向名词解释_图形学名词解释2(转帖)
  8. 解决vue-router在3.0版本以上重复点菜单报错问题
  9. 荣耀笔试复盘第二题-
  10. Java开发微信dat文件解析工具,android原生开发笔记应用