使用Jacoco获取 Java 程序的代码执行覆盖率

摘要:
本文没有讨论如何使用Jacobo获得单元测试的代码覆盖率,而是从Jacobo的原理介绍如何通过Jacobo获得SIT或UAT的测试覆盖率。Jacobo原理简介Jacobo通过修改提供给JVM的字节码来获得执行的代码。将其除以总代码,得到代码执行覆盖率。使用Jacobo生成代码执行覆盖率报告。接下来,我们将介绍如何使用Jacobo通过实验获得Java web应用程序代码的执行率。了解了原理后,可以通过参考官方网站上的手册,使用Jacco进行一些实际操作,以提高Java代码的质量。

Jacoco是Java Code Coverage的缩写,顾名思义,它是获取Java代码执行覆盖率的一个工具,通常用它来获取单元测试覆盖率。它通过分析Java字节码来得到代码执行覆盖率,因此它还可以分析任何基于JVM的语言(如Croovy、Kotlin)的覆盖率。本文不讨论如何用Jacoco获取单元测试的代码覆盖率,而是从Jacoco的原理出发,介绍如何通过Jacoco获取SIT或者UAT的测试覆盖率。更准确来讲,是获取一个应用执行过的代码占总代码的比率。包括字节码指令覆盖率,分支覆盖率,圈复杂度覆盖率,行覆盖率,方法覆盖率和类覆盖率。

Jacoco原理简介

Jacoco通过修改喂给JVM的字节码来达到获取那些代码执行了的目的。修改方式有两种,一种在线(on-the-fly),是通过Java agent,在JVM执行字节码之前动态对其进行修改,这种方式更灵活,也是Jcoco的一大特性。另一种是离线(offline)模式,在Java程序字节码文件(.class文件)生成之前进行修改,这样的字节码就不纯了。一般在无法使用on-the-fly方式的时候才使用offline方式。

上面这些概括起来讲,Jacoco最牛X的地方就在于它能够知道一个基于JVM的应用程序中哪些代码(指令、分支、行、方法、类)被执行了。用它除以总代码量,就得到了代码执行覆盖率。

由此,我们可以推断出Jacoco生成单元测试覆盖率报告的原理:单元测试代码会调用被测试代码,被测试代码的字节码指令会被Jacoco截获,用被截获的代码量除以总代码量,就算出了单元测试代码覆盖率。举一反三,在SIT或者UT的时候,也需要执行Java应用程序中的代码,因此可以也通过Jacoco获取被执行过的代码,从而计算出SIT,UT测试代码覆盖率。

使用Jacoco生成代码执行覆盖率报告

接下来通过一个实验介绍如何使用Jacoco获取一个Java web应用代码的执行率。就拿Tomcat自带的example应用来做实验,我们在启动Tomcat时带上Jacoco的Java agent;然后在页面上做一些点击操作,触发后台Java代码的执行;再抓取包含执行情况数据,放到.exec的二进制文件中;最后由这些二进制文件生成html格式的报告,验证被覆盖的代码是否和我们点击的内容相关。

下载Jacoco(https://www.jacoco.org),解压缩。

下载Tomcat(https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/ 清华mirror),然后解压缩,进入bin目录,找到catalina.bat文件(Windows)。

使用Jacoco获取 Java 程序的代码执行覆盖率第1张

修改如下代码,让Tomcat在启动时带上Javacoco的agent。

set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"

修改为

set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS% -javaagent:C:UsersRobotApplicationjacoco-0.8.5libjacocoagent.jar=destfile=jacoco.exec,output=tcpserver"

其中指定了javaagent是C:UsersRobotApplicationjacoco-0.8.5libjacocoagent.jar,解压Jacoco可以得到;指定了output是tcpserver,也就是需要通过访问一个地址才能获取到数据。默认地址是本地IP地址,端口号是6300。其它参数说明见:https://www.jacoco.org/jacoco/trunk/doc/agent.html

使用Jacoco获取 Java 程序的代码执行覆盖率第2张

设置完成之后,双击Tomcat bin目录下的startup.bat,启动Tomcat。控制台可以看见javaagent设置生效。此时Jacoco就可以动态地拦截喂给JVM的字节码,并且监听6300端口号和所以本机地址,等待获取代码执行情况数据(暂且称为.exec文件数据)的请求。

使用Jacoco获取 Java 程序的代码执行覆盖率第3张

输入地址http://127.0.0.1:8080/ ,打开Tomcat 欢迎页面,做一些点击操作,可以确定它已经执行了一些字节码。

使用Jacoco获取 Java 程序的代码执行覆盖率第4张

获取执行情况数据,在jacococli.jar所在目录(与jacocoagent.jar目录一致)执行命令:

java -jar jacococli.jar dump  --port 6300 --destfile data/jacoco-it.exec

Jacoco会在当前目录下生成data/jacoco-it.exec文件,这个文件是一个二进制文件,我们无法直接查看它,需要用它生成html或者其它格式的文件。

使用Jacoco获取 Java 程序的代码执行覆盖率第5张

 执行如下命令生成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

使用Jacoco获取 Java 程序的代码执行覆盖率第6张

打开html目录下的index.html文件就可以看到报告了。

使用Jacoco获取 Java 程序的代码执行覆盖率第7张

 小结

上面实验比较简单,只为辅助对Jacoco原理的理解。理解了原理之后,参照官网的手册就可以用Jacoco来做一些实用的操作,提高Java代码的质量。

免责声明:文章转载自《使用Jacoco获取 Java 程序的代码执行覆盖率》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇git代码合并与冲突Object-C与Swift混合开发下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Tomcat8史上最全优化实践

Tomcat8史上最全优化实践 1、Tomcat8优化 1.1、Tomcat配置优化 1.1.1、部署安装tomcat8 1.1.2 禁用AJP连接 1.1.3、执行器(线程池) 1.1.4 3种运行模式 1.3、使用Apache JMeter进行测试 1.3.1、下载安装 1.3.2、修改主题和语言 1.3.3、创建首页的测试用例 1.3.4、...

为什么测试覆盖率如此重要

摘要:就软件质量而言,测试覆盖率是软件测试中的重要指标。接下来一起了解测试范围、测试技术,测试标准以及如何改进它。 由于软件中普遍存在的错误,全世界都见证了一些灾难性事件。2008年在英国希思罗机场5号航站楼开业。 工程师对终端的工作充满信心,这与他们的严格测试标准有关。由于行李处理系统在现实情况运行时陷入了瘫痪,导致系统完全关闭。在接下来的10天里,大约...

深入Java虚拟机之内存区域与内存溢出

一.内存区域 Java虚拟机在执行Java程序的过程中会把他所管理的内存划分为若干个不同的数据区域。Java虚拟机规范将JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。下面详细阐述各数据区所存储的数据类型。 程序计数器(ProgramCounterRegister) 一块较小的内存空间,它是当...

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

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

Java基础-对象的内存分配与初始化(一定要明白的干货)

首先,什么是类的加载?类的加载由类加载器执行.该步骤将查找字节码(classpath指定目录),并从这些字节码中创建一个Class对象。Java虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。一旦某个类的Class对象被载入到内存,他就被用来创建这个类的所有对象。 类的加载会发生在什么时候呢?所有的类都是在其...

Java字节码常量池深入剖析

继续来分析Java字节码,上一节分析了魔数的规则,接下来继续往下分析,其上次总结的规则也一起贴出来: 1、使用javap -verbose命令分析一个字节码文件时,将会分析该字节码文件的魔数、版本号、常量池、类信息、类的构造方法、类中的方法信息、类变量与成员变量等信息。 2、魔数:所有的.class字节码文件的前4个字节都是魔数,魔数值为固定值:0xCAF...