Jacoco是Java Code Coverage的缩写,顾名思义,它是获取Java代码执行覆盖率的一个工具,一般用它来获取单元测试覆盖率。它经过分析Java字节码来获得代码执行覆盖率,所以它还能够分析任何基于JVM的语言(如Croovy、Kotlin)的覆盖率。本文不讨论如何用Jacoco获取单元测试的代码覆盖率,而是从Jacoco的原理出发,介绍如何经过Jacoco获取SIT或者UAT的测试覆盖率。更准确来说,是获取一个应用执行过的代码占总代码的比率。包括字节码指令覆盖率,分支覆盖率,圈复杂度覆盖率,行覆盖率,方法覆盖率和类覆盖率。html
Jacoco经过修改喂给JVM的字节码来达到获取那些代码执行了的目的。修改方式有两种,一种在线(on-the-fly),是经过Java agent,在JVM执行字节码以前动态对其进行修改,这种方式更灵活,也是Jcoco的一大特性。另外一种是离线(offline)模式,在Java程序字节码文件(.class文件)生成以前进行修改,这样的字节码就不纯了。通常在没法使用on-the-fly方式的时候才使用offline方式。java
上面这些归纳起来说,Jacoco最牛X的地方就在于它可以知道一个基于JVM的应用程序中哪些代码(指令、分支、行、方法、类)被执行了。用它除以总代码量,就获得了代码执行覆盖率。web
由此,咱们能够推断出Jacoco生成单元测试覆盖率报告的原理:单元测试代码会调用被测试代码,被测试代码的字节码指令会被Jacoco截获,用被截获的代码量除以总代码量,就算出了单元测试代码覆盖率。触类旁通,在SIT或者UT的时候,也须要执行Java应用程序中的代码,所以能够也经过Jacoco获取被执行过的代码,从而计算出SIT,UT测试代码覆盖率。apache
接下来经过一个实验介绍如何使用Jacoco获取一个Java web应用代码的执行率。就拿Tomcat自带的example应用来作实验,咱们在启动Tomcat时带上Jacoco的Java agent;而后在页面上作一些点击操做,触发后台Java代码的执行;再抓取包含执行状况数据,放到.exec的二进制文件中;最后由这些二进制文件生成html格式的报告,验证被覆盖的代码是否和咱们点击的内容相关。tomcat
下载Jacoco(https://www.jacoco.org),解压缩。app
下载Tomcat(https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/ 清华mirror),而后解压缩,进入bin目录,找到catalina.bat文件(Windows)。webapp
修改以下代码,让Tomcat在启动时带上Javacoco的agent。tcp
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"
修改成工具
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS% -javaagent:C:\Users\Robot\Application\jacoco-0.8.5\lib\jacocoagent.jar=destfile=jacoco.exec,output=tcpserver"
其中指定了javaagent是C:\Users\Robot\Application\jacoco-0.8.5\lib\jacocoagent.jar,解压Jacoco能够获得;指定了output是tcpserver,也就是须要经过访问一个地址才能获取到数据。默认地址是本地IP地址,端口号是6300。其它参数说明见:https://www.jacoco.org/jacoco/trunk/doc/agent.html。单元测试
设置完成以后,双击Tomcat bin目录下的startup.bat,启动Tomcat。控制台能够看见javaagent设置生效。此时Jacoco就能够动态地拦截喂给JVM的字节码,而且监听6300端口号和因此本机地址,等待获取代码执行状况数据(暂且称为.exec文件数据)的请求。
输入地址http://127.0.0.1:8080/ ,打开Tomcat 欢迎页面,作一些点击操做,能够肯定它已经执行了一些字节码。
获取执行状况数据,在jacococli.jar所在目录(与jacocoagent.jar目录一致)执行命令:
java -jar jacococli.jar dump --port 6300 --destfile data/jacoco-it.exec
Jacoco会在当前目录下生成data/jacoco-it.exec文件,这个文件是一个二进制文件,咱们没法直接查看它,须要用它生成html或者其它格式的文件。
执行以下命令生成html报告。--classfiles制定应用程序的class文件所在目录,--html指定html报告所在目录。
java -jar jacococli.jar report data/jacoco-it.exec --classfiles C:/Users/Robot/Application/apache-tomcat-9.0.29/webapps/examples/WEB-INF/classes --html html
打开html目录下的index.html文件就能够看到报告了。
上面实验比较简单,只为辅助对Jacoco原理的理解。理解了原理以后,参照官网的手册就能够用Jacoco来作一些实用的操做,提升Java代码的质量。