jacoco统计自动化代码覆盖率

1. 简介
1.1. 什么是Jacoco
Jacoco是一个开源的代码覆盖率工具,可以嵌入到Ant 、Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序。很多第三方的工具提供了对Jacoco的集成,如sonar、Jenkins等。
1.2. 什么是代码覆盖率
代码覆盖(Code coverage)是软件测试中的一种度量,描述程式中源代码被测试的比例和程度,所得比例称为代码覆盖率。
代码覆盖率是衡量测试质量的一个重要指标。在对一个软件产品进行了单元测试、组装测试、集成测试以及接口测试等繁多的测试之后,我们能不能就此对软件的质量产生一定的信心呢?这就需要我们对测试的质量进行考察。如果测试仅覆盖了代码的一小部分,那么不管我们写了多少测试用例,我们也不能相信软件质量是有保证的。相反,如果测试覆盖到了软件的绝大部分代码,我们就能对软件的质量有一个合理的信心。
代码覆盖分为下面五种情况:
1.2.1. 函数覆盖
函数覆盖(Function Coverage),执行到程序中的每一个函数(或副程式)。
1.2.2. 语句覆盖
语句覆盖(Statement Coverage),又称行覆盖(Line Coverage),段覆盖(Segment Coverage),基本块覆盖(Basic Block Coverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。这里说的是“可执行语句”,因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。需要注意的是,单独一行的花括号{}也常常被统计进去。语句覆盖常常被人指责为“最弱的覆盖”,它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。假如你的上司只要求你达到语句覆盖,那么你可以省下很多功夫,但是,换来的确实测试效果的不明显,很难更多地发现代码中的问题。
1.2.3. 判断覆盖
判断覆盖(Decision Coverage),又称分支覆盖(Branch Coverage),所有边界覆盖(All-Edges Coverage),基本路径覆盖(Basic Path Coverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到了。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。因此我们直接介绍第三种覆盖方式,然后和判定覆盖一起来对比,就明白两者是怎么回事了。
1.2.4. 条件覆盖
条件覆盖(Condition Coverage),它度量判定中的每个子表达式结果true和false是否被测试到了。
1.2.5. 路径覆盖
路径覆盖(Path Coverage),又称断言覆盖(Predicate Coverage)。它度量了是否函数的每一个分支都被执行了。 这句话也非常好理解,就是所有可能的分支都执行一遍,有多个分支嵌套时,需要对多个分支进行排列组合,可想而知,测试路径随着分支的数量指数级别增加。
1.3. Jacoco的功能
1.3.1. 覆盖率计数器
Jacoco使用一系列的不同的计数器来做覆盖率的度量计算。所有这些计数器都是从java的class文件中获取信息,这些class文件可以(可选)包含调试的信息在里面。即使在没有源码的情况下,这种方法也可以实时有效地对应用程序进行度量和分析。在大部分情况下,收集到的信息可以映射到源码,可视化到每一行代码的粒度。但这种方法还是有一些限制。这些class文件必须使用调试信息来编译,这样才可以计算行的覆盖率和提供出源码的高亮。但不是所有的JAVA语言的结构都可以直接编译成一致的二进制代码。在这种情况下,java 编译器会创建所谓的“合成”代码,会导致产生一些不期望得到的覆盖率结果。
1.3.2. 指令覆盖率
Jacoco最小的计数单元是单个java二进制代码指令。指令覆盖率提供了代码是否被执行的信息。这个度量完全独立源码格式,并且总是可用,即使class文件里面没有调试信息。
1.3.3. 分支覆盖率
Jacoco也计算分支的覆盖率,包括所有的if和switch语句。这个度量计算一个方法里面的总分支数,确定执行和不执行的分支数量。分支覆盖率总是可用的,即使class文件里面没有调试信息。注意异常处理是不在分支度量里面统计的。

2. Jacoco的安装
(1)安装ant
首先需要安装ant和jacoco。
下载完apache-ant的压缩包后,解压,放到常用的软件安装路径下即可。ant是基于java的,所以要先确保系统中已经安装了jdk。比如我的ant是安装在本机的,这个时候就需要配置环境变量:

随后在cmd中输入命令 ant -version

到这里就表示ant的安装已经完成了。
(2) 在tomcat中加入jacoco
打开tomcat的bin目录下的catalina.bat文件,在JAVA_OPTS参数中加入一行。

脚本代码如下:

  1. set JAVA_OPTS=-server -Xms1024m -Xmx1024m -XX:PermSize=512M -XX:MaxNewSize=512m -XX:MaxPermSize=512m -Djava.awt.headless=true -javaagent:D:\AutoTest\jacoco\lib\jacocoagent.jar=includes=com.hundsun.*,output=tcpserver,port=8229,address=127.0.0.1 -Xverify:none

参数说明如下:

1) -javaagent: 的后面跟jacoco的安装路径
2) includes= 选项,选择你要覆盖率的服务,也就是包名
3) port=,选择你要打开的端口,jacoco的端口,与所对应的tomcat端口不能一样,与其他端口也不能冲突
4) address= tomcat服务所在机器的ip地址(如果想在跟tomcat服务同一台机器上执行ant任务的话,需要改为127.0.0.1)
5) -Xverify:none,避免启动报错的情况
这样配置后就将jacoco嵌入到了tomcat中,到时候tomcat起来后,就通过开放的端口,来访问jacoco检测到的数据。正常启动tomcat,jacoco就在实时监测tomcat中运行的war包,此时数据全部存放在内存中。

3. ant脚本
(1) dump数据
远程的从另外一个jvm上获取数据,并且不用停止应用的运行,这个是非常有用的。但是目标jvm需要把jacoco配置为tcpserver模式,目前使用的,也就是在tomcat的语句中,output格式为tcpserver。
Dump数据,首先需要知道jacoco的位置和端口,然后导出exec的文件的地址,以及其他的一些配置即可。

1) address:目标的jacoco的ip地址

2) port:目标的jacoco开放的端口号

3) retryCount:将尝试建立连接的重试次数。 这可以用于等待目标JVM成功启动。
4) dump:是否转储执行数据。
5) reset:执行导出后是否重置数据
6) destfile:生成的数据的存放位置
7) append:如果设置为 true,执行数据文件已存在,覆盖率数据追加到现有文件中。如果设置为 false,现有执行数据文件将被替换。
(2) report
report命令,需要知道exec文件的位置,以及源代码、类的位置,还有生成报告的格式需要指定。

当涉及到多个源码包和类的时候,建议使用group的方式区分开来。

导出格式的选择。

(4)完整脚本
bulid.xml中的完整代码如下:

  1. <?xml version="1.0" ?>
  2. <project name="wftestReport" xmlns:jacoco="antlib:org.jacoco.ant" default="jacoco">
  3. <!--Jacoco的安装路径-->
  4. <property name="jacocoantPath" value="D:\AutoTest\jacoco\lib\jacocoant.jar"/>
  5.  
  6. <!--最终生成.exec文件的路径,Jacoco就是根据这个文件生成最终的报告的-->
  7. <property name="jacocoexecPath" value="D:\AutoTest\JRES\codeCoverage\mergedwftest.exec"/>
  8.  
  9. <!--生成覆盖率报告的路径,直接放在tomct下面,外界直接访问-->
  10. <property name="reportfolderPath" value="D:\AutoTest\JRES\codeCoverage\report"/>
  11.  
  12. <!--远程tomcat服务的ip地址-->
  13. <property name="server_ip" value="127.0.0.1"/>
  14.  
  15. <!--前面配置的远程tomcat服务打开的端口,要跟上面配置的一样-->
  16. <!--这个端口有别于tomcat的端口,相当于是嵌在tomcat里的监视器-->
  17. <property name="server_port" value="8229"/>
  18.  
  19. <!--源代码路径-->
  20. <!--<property name="checkOrderSrcpath" value="/root/LoginDemo4/src/main/java/" />-->
  21. <!--可以配置多个源代码-->
  22. <property name="express_src" value="D:\AutoTest\JRES\mysrc\src\main\java\"/>
  23.  
  24. <!--.class文件路径-->
  25. <!--跑的是class,标注的是源码?-->
  26. <!--<property name="checkOrderClasspath" value="/root/wftest/target/classes/com/hundsun" />-->
  27.  
  28. <property name="express_class" value="D:\AutoTest\JRES\report\WEB-INF\classes\com\hundsun\reportXml\expression\"/>
  29.  
  30. <!--合并报告路径-->
  31. <property name="mergePath" value="D:\AutoTest\JRES\codeCoverage" />
  32.  
  33. <!--让ant知道去哪儿找Jacoco-->
  34. <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
  35. <classpath path="${jacocoantPath}" />
  36. </taskdef>
  37.  
  38. <!--dump任务:
  39. 根据前面配置的ip地址,和端口号,
  40. 访问目标tomcat服务,并生成.exec文件。-->
  41. <target name="dump">
  42. <jacoco:dump address="${server_ip}" reset="false" destfile="${jacocoexecPath}" port="${server_port}" append="true"/>
  43. </target>
  44. <target name="merge">
  45. <!--将路径下的exec文件全部合并,并存放到destfile中-->
  46. <jacoco:merge destfile="D:\AutoTest\JRES\codeCoverage\merged.exec">
  47. <fileset dir="${mergePath}" includes="*.exec"/>
  48. </jacoco:merge>
  49. </target>
  50.  
  51. <!--jacoco任务:
  52. 根据前面配置的源代码路径和.class文件路径,
  53. 根据dump后,生成的.exec文件,生成最终的html覆盖率报告。-->
  54. <target name="report">
  55. <!--暂时不删除,一旦删除,其他两个的报告也没了-->
  56. <delete dir="${reportfolderPath}" />
  57. <mkdir dir="${reportfolderPath}" />
  58. <jacoco:report>
  59. <executiondata>
  60. <file file="${jacocoexecPath}" />
  61. </executiondata>
  62. <structure name="ucf report">
  63. <group name="express related">
  64. <classfiles>
  65. <fileset dir="${express_class}" />
  66. </classfiles>
  67. <sourcefiles encoding="utf-8">
  68. <fileset dir="${express_src}" />
  69. </sourcefiles>
  70. </group>
  71. </structure>
  72. <html destdir="${reportfolderPath}" encoding="utf-8" />
  73. <csv destfile="D:\AutoTest\JRES\codeCoverage\report.csv" />
  74. </jacoco:report>
  75. </target>
  76. </project>

(5)脚本使用
以上内容全部放在一个build.xml中,如图所示:

在这个目录下进行cmd命令执行,

访问目标tomcat服务,并生成.exec文件。 

接下来,我们可以执行命令ant report ,来生成代码覆盖报告。

到此jacoco已经生成了代码覆盖率的报告,路径如下图所示:

4. 报告解读 

(1)颜色
没有覆盖:在这一行中没有分支被执行(红色方块)
部分覆盖:这一行的分支中只有一部分被执行(黄色方块)
完全覆盖:这一行的所有分支都被执行(绿色方块)

数量越多,进度条越长;红色越多,覆盖的越少。

 指令覆盖
 分支覆盖
 行覆盖
 方法覆盖
 类覆盖

jacoco统计自动化代码覆盖率的更多相关文章

  1. 使用JaCoCo统计单元测试代码覆盖率

    1 JaCoCo介绍 JaCoCo是EclEmma团队基于多年覆盖率库使用经验总结而研发的一个开源的Java代码覆盖率库. 2 JaCoCo覆盖率计数器 JaCoCo 包含了多种尺度的覆盖率计数器(C ...

  2. jacoco统计自动化测试代码覆盖率

    一.下载jacoco, ant工具 jacoco: http://www.eclemma.org/jacoco/: ant: http://ant.apache.org 并添加到环境变量: 二.不停j ...

  3. PowerShell调用jira rest api实现jira统计自动化

    通过调用JIRA Rest web api实现统计自动化,首先进行登录模拟: $content = @{username='用户名';password='密码'} $JSON=$content|con ...

  4. Jacoco统计web接口/功能测试的代码覆盖率【转】

    原文:https://www.jianshu.com/p/d2fd02d4164b 一.代码覆盖率 通常我们在做单元测试的时候会接触到代码覆盖率的概念,通过在单元测试的过程中收集代码覆盖率去判断测试用 ...

  5. 利用JaCoCo统计接口测试中代码覆盖率

    ​        做接口测试,很多时候都会听到,你接口测试的覆盖率是多少?很多人会回答80%,你怎么统计的,他说覆盖了80%的需求.这个回答没有错误,但是片面,我们不能只考虑需求的覆盖率,还有业务的覆 ...

  6. ant+Jacoco 统计tomcat远程部署后项目接口自动化测试或者功能测试代码覆盖率

    1.安装ant 环境,https://ant.apache.org/bindownload.cgi 2.下载jacoco包  https://www.eclemma.org/jacoco/ ,解压后, ...

  7. jenkins+jacoco+ant自动化代码和应用服务代码分离场景获取远程服务的覆盖率

    前提 自动化代码和应用服务代码分离.jenkins和tomcat服务器分离 思想 1.在tomcat启动javaagent监听. 2.运用其他job_B已部署的应用服务代码 3.拉取自动化代码,开始测 ...

  8. 使用Jacoco统计服务端代码覆盖情况实践

    一.背景 随着需求的迭代,需求增加的同时,有可能会伴随着一些功能的下线.如果不对系统已经不用的代码进行梳理并删除不需要的代码,那么就会增加系统维护成本以及理解成本.但经历比较长的迭代以及系统交接,可能 ...

  9. jacoco统计Android手工测试覆盖率并自动上报服务器

    改进了几个点 1. 不用借助Instrumentation启动,正常启动即可: 2. 测试代码不用push到主分支,主分支代码拉到本地后用git apply patch方式合并覆盖率代码: 3. 测试 ...

随机推荐

  1. pjd-fstest The test suite checks POSIX compliance - 测试文件系统posix 接口兼容性

    pjd-fstest: 参考网址:https://www.tuxera.com/community/posix-test-suite/ fstest是一套简化版的文件系统POSIX兼容性测试套件,它可 ...

  2. ElasticSearch7 设置外网访问失败

    elasticsearch外网访问9200端口失败,bootstrap checks failed,the default discovery settings are unsuitable for ...

  3. vi 中按了 Ctrl+S 后死机不能动怎么办?

    我们下意识想保存文档时,会不知觉地按下 Ctrl+S 组合键.但如果是正在 Linux 的 Shell 中使用 vi 编辑文本,这么按就糟了,会直接出现卡住.不能动.卡死的现象. 不过,后来我搞明白了 ...

  4. 小型数据库性能对比(对比了SQLite、FireBird、FastDB、SQLServer2000绿色版、Access、BDB、PostgreSQL)

    一.全面对比 SQLite.FireBird.FastDB.SQLServer2000绿色版.Access.BDB.PostgreSQL对比结果如下: 二.国产数据库 三.SQLite 与Postgr ...

  5. VMWare ESX server安装

    和装普通虚拟机是一样的 需要添加两块网卡. F11同意协议 直接回车即可‘ 选择字符集 输入密码 按F11安装系统 按回车键重启 按F2 配置网络管理 启用两块网卡,按回车确定 配置IPV4地址 用空 ...

  6. 用arthas的watch方法观察执行方法的输入输出

    watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象 参数名称 参数说明 class-pattern 类名表达式匹配 method-pattern 方法名表达式匹配 express 观 ...

  7. Spring-AOP-配置实现五大通知

    码云: xml配置方法:https://gitee.com/MarkPolaris/spring_aop_1 注解配置方法:https://gitee.com/MarkPolaris/spring-e ...

  8. 大话设计模式Python实现-单例模式

    单例模式(Singleton Pattern):保证类仅有一个实例,并提供一个访问它的全局访问点. 下面是单例模式的demo: #!/usr/bin/env python # -*- coding:u ...

  9. Java修饰符作用域

    作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × 修饰 ...

  10. Python extend函数解读

    num = [1,2] print('将1迭代2次') num.extend([1]*2) print(num) print('将2迭代3次') num.extend([2] * 3) print(n ...