javascript:void(0)

jacoco能解决什么问题
  • 自动化测试虽然快,但是不知道是不是有漏测
  • 提高测试设计质量
  • 可快速对比多次测试之间的差距
  • 测试完整性的一种手段
jacoco需要依赖的 - 困难
  • 最好有独立的测试环境(测试环境隔离)
  • 在统计覆盖率的时候,有干扰项(可能不是自动化测试用例跑出来的)
  • 测试环境不能有分布式jar,不然接口测试分流了 可能会统计不准(一个节点跑出了30%,一个节点跑出了70%)
    分布式情况的统计合并(对测试用例,流量的配置)
  • 依赖模块或第3方可能导致用例中断统计不准(需要对依赖模块的档板隔离)
  • 增量覆盖率(差异化,不同版本的覆盖率对比再修改自动化测试脚本)
on-the-fly
  • 插桩模式,jacoco在外围动态收集覆盖率信息

jacoco操作步骤

jacoco_jacoco

  1. 配置jacocoagent参数,启动服务 java - javaagent:jacocoagent.jar [=options]应用
  2. 生成 jacoco.exec ant dump
  3. ant 构建生成覆盖率报告 ant report
includes:包含在执行分析中的类名列表,*表示全部
output:表示使用tcpserver代理侦听由address和port属性指定的TCP端口,并将执行的数据写入此TCP连接,从而实现不停止项目运行实时生成代码覆盖率报告
port:开启的端口号
address: 开启的ip地址,本地写127.0.0.1
jar:运行服务的jar包地址
java - javaagent:jacocoagent.jar [=options]应用

什么方法级别覆盖率你都还不满足,想看到底哪行代码覆盖到了?
那你得知道这有多坑了,最基本的配置是做不到的,我们还需要配置自己的 class 文件路径和源码路径!

注意要具体到 class 目录和 java 目录!,即 com 目录的上一级目录,就能完美展示源码的覆盖率情况了

jacoco_maven_02

jacoco实战

以Api的方式来进行操作的好处

Jacoco 官方的 Api 示例
地址: https://www.jacoco.org/jacoco/trunk/doc/api.html
可以屏蔽不同方式的构建部署,如果你想把这个功能做成平台,那 api 想必是很好的一种方式。

也就是说,我只需要把 jacoco 插桩到测试服务器上,暴露 tcp 的 ip 和端口,剩余的提取代码执行数据、生成覆盖率报告,就可以用统一的方式进行就好了。
众所周知,jacoco 官方提供了 Maven 插件方式、Ant 的 xml 方式,均有对应的 dump 和 report 来进行覆盖率数据的 dump 和报告生成,如果有兴趣可以研究一下,我也不过于啰嗦。
  • 构建工具。我司现有 Maven 构建、ANT 构建,想必有的公司还有用 gradle 的。部署方式。Ant、Maven 插件启动、java -jar 启动、tomcat 启动 war 包 (打包方式就随便了)

tomcat war包的方式插桩

只需要改动 catalina.sh 中的启动参数即可。
前面提到过,主要改动主要是改动 java -jar,tomcat 是通过一个 JAVA_OPTS 参数来控制额外的 java 启动参数的,我们只需要在合适的地方把上面的启动命令追加到 JAVA_OPTS 即可
打开 catalina.sh,找到合适的地方修改 JAVA_OPTS 参数:

理论上,任何地方修改 JAVA_OPTS 参数均可,但我们实验过后,在以下位置加入,是一定可以启动成功的,当然您也可以尝试其他位置.
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.security.SecurityListener.UMASK=`umask`"
源脚本中有这个注释掉的地方,我们在下方修改 JAVA_OPTS:
在其下方,加一句:

JAVA_OPTS="$JAVA_OPTS -javaagent:$jacocoJarPath=includes=*,output=tcpserver,port=2014,address=192.168.110.1"

检验是否启动成功:
ps -ef|grep jacoco
netstat -anp |grep 'address'


maven 插件的方式启动

mvn clean install
export MAVEN_OPTS="-javaagent:$jacocoJarPath=includes=*,output=tcpserver,port=2014,address=192.168.110.1"
mvn tomcat7:run -Dport=xxx
export MAVEN_OPTS=""


mvn clean install
export MAVEN_OPTS="-javaagent:$jacocoJarPath=includes=*,output=tcpserver,port=2014,address=192.168.110.1"
mvn spring-boot:run -Dport=xxx
export MAVEN_OPTS=""

关于启动之后

  • 就可以直接给测试用了

覆盖率报告生成

就本质上来说,覆盖率报告的生成,只需要两个必须的东西,一个是 class 文件,一个是针对这些 class 产生的执行信息 (就是 exec 文件)。
当然了源码起到很重要的作用就是可以让你在报告里面来回跳转查看代码详情,如果没有源码,则没办法点进去方法。
综上来说,那也可以说成一个完善的覆盖率报告,可以有源码、class 文件、和对应的 exec 文件即可。

可能出现的问题

造成覆盖率报告数据不准确的原因有哪些?

最最最最底层的原因。 部署时的 class 文件和生成报告的时候,用的 class 文件不一致。有以下几种情况:

  1. 测试服务器(就是你的应用所在的那个环境)中的 class 文件和我管理平台上编译环境不一致,导致产生的 class 文件跟部署时的 class 文件有差异。这个可以通过不手动编译,而是从 测试服务器部署位置的目录来拷贝传输,来解决
  2. 测试服务器版本变更了,但是管理平台上的代码没变更(或者说新代码拉取下来了,但是没有重新编译。),导致 class 文件不一致
  3. 管理平台上的新版本代码的版本号没有填写,默认每次拉取最新代码,这会导致生成报告的时候,源码变了,class 文件没变,覆盖率插桩收集的时候,用的还是老代码 所以,要想准确。需要保证,测试服务器部署时的代码版本和管理平台上写的版本号完全一致。