仅记录一下Java项目使用jacoco生成测试覆盖率的报告,以便后续参考
一、代码覆盖率
代码覆盖率,是一种通过计算测试过程中被执行的源代码占全部代码的比例,进而间接度量软件质量的过程。它在保证测试质量的时候潜在保证实际产品的质量。可以基于此在程序中寻找到没有被测试用例测试过的地方,进一步创建新的测试用用例来增加覆盖率。按性质,它属于白盒测试的范畴,即主要依据源代码的内部结构来设计测试用例,通过设计不同的输入来测试软件的不同部分。
代码覆盖率通常分为四种:
-
语句覆盖率(Statement Coverage)
衡量测试用例执行过程中覆盖到的代码语句比例。计算方法是统计被执行的代码语句数量与总代码语句数量的比例。 -
分支覆盖率(Branch Coverage)
衡量测试用例执行过程中覆盖到的代码分支比例。计算方法是统计被执行的代码分支数量与总代码分支数量的比例。 -
条件覆盖率(Condition Coverage)
衡量测试用例执行过程中覆盖到的条件语句比例。计算方法是统计被执行的条件语句数量与总条件语句数量的比例。 -
路径覆盖率(Path Coverage)
衡量测试用例执行过程中覆盖到的代码路径比例。计算方法是统计被执行的代码路径数量与总代码路径数量的比例。 -
函数覆盖率(Function Coverage)
衡量测试用例执行过程中覆盖到的函数或方法比例。计算方法是统计被执行的函数或方法数量与总函数或方法数量的比例。 -
边界值覆盖率(Boundary Value Coverage)
衡量测试用例执行过程中覆盖到的边界值情况比例。计算方法是统计覆盖到的边界值测试用例数量与总边界值测试用例数量的比例。 -
错误处理覆盖率(Error Handling Coverage)
衡量测试用例执行过程中覆盖到的错误处理情况比例。计算方法是统计覆盖到的错误处理测试用例数量与总错误处理测试用例数量的比例。
二、Jacoco插桩模式
Offline 模式和 On-the-fly 模式
-
离线(offline)
编译时插桩,在测试前先对文件进行插桩,然后生成插过桩的class或jar包,测试插过桩 的class和jar包后,会生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。 -
在线(on the fly)
在线模式就是在应用启动时加入jacoco agent进行插桩,在开发、测试人员使用应用期间实时地进行代码覆盖率分析。
为了不影响源码及性能问题,更多情况会用到on the fly的模式。
三、Jacoco插桩的原理
jacoco 以 tcpserver 方式进行插桩的本质,就是如果应用启动过程中,进行了 jacoco 插桩,且成功了。它会在你当前这个启动服务器中,在一个端口{$port}上,开启一个 tcp 服务,这个 tcp 服务,会一直接收 jacoco 的执行覆盖率信息并传到这个 tcp 服务上进行保存。他既然是个 tcp 服务,那 jacoco 也提供了一种以 api 的方式连接到这个 tcp 服务上,进行覆盖率数据的 dump 操作。
(细节可能描述的不是很精确,但差不多就是这么个过程。这个 tcp 服务,在你没有关闭应用的时候,是一直开着的,可以随时接受连接)
四、Jacoco插桩使用
1.下载jacoco插件
Jacoco
2.首先要有公司的代码权限
3.启动被测的服务,这里是用jar包启动的方式(只做本地启服务的例子,具体集成自动化方面使用还是需要参考大佬的案例)
java -javaagent:jacocoagent.jar=includes=*,output=tcpserver,port=6300,address=localhost,append=true -jar gulimall-thrid-party-0.0.1-SNAPSHOT.jar
命令讲解
-javaagent
jdk5 之后新增的参数,主要用来在运行 jar 包的时候,以一种方式介入字节码加载过程,如有兴趣自行百度。注意后面有个冒号:
/home/admin/jacoco/jacocoagent.jar
需要用来介入 class 文件加载过程的 jar 包,想深入了解的,百度 “插桩” 哈。
这是一个 jar 包的绝对路径。
includes=*
这个代表了,启动时需要进行字节码插桩的包过滤,* 代表所有的 class 文件加载都需要进行插桩。
假如你们公司内部代码都有相同的包前缀:com.mycompany
你可以写成:
includes=com.mycompany.*
output=tcpserver,output 有 4 个值,分别是 file、tcpserver、tcpclient、mbean,默认是 file。使用 file 的方式只有在停掉应用服务的时候才能产生覆盖率文件,而使用 tcpserver 的方式可以在不停止应用服务的情况下下载覆盖率文件,后面会介绍如何使用 dump 方法来得到覆盖率文件。
这个地方不用改动,代表以 tcpserver 方式启动应用并进行插桩
port=2014,(端口比较随便,找个能用的端口就行,直接我为什么将端口写成 8044
,我的想法是 BUG 死死
与 8044
挺配的,所以就用它作为端口号了) (address
和 port
是使用 tcpserver 方式需要的 2 个参数,也是执行 ant dump 方法必须要用到的。)
这是 jacoco 开启的 tcpserver 的端口,请注意这个端口不能被占用
address=192.168.110.1
这是对外开发的 tcpserver 的访问地址。可以配置 127.0.0.1,也可以配置为实际访问 ip
配置为 127.0.0.1 的时候,dump 数据只能在这台服务器上进行 dump,就不能通过远程方式 dump 数据。
配置为实际的 ip 地址的时候,就可以在任意一台机器上 (前提是 ip 要通,不通都白瞎),通过 ant xml 或者 api 方式 dump 数据。
举个栗子:
我如上配置了 192.168.110.1:2014 作为 jacoco 的 tcpserver 启动服务,
那我可以在任意一台机器上进行数据的 dump,比如在我本机 windows 上用 api 或者 xml 方式调用 dump。
如果我配置了 127.0.0.1:2014 作为启动服务器,那么我只能在这台测试机上进行 dump,其他的机器都无法连接到这个 tcpserver 进行 dump。
总结:
这句内容,如下,格式是固定的,只有括号内的东西方可改变,其它尽量不要动,连空格都不要多:
-javaagent:(/home/admin/jacoco/jacocoagent.jar)=includes=(*),output=tcpserver,port=(2014),address=(192.168.110.1)
比如我可以改成其他的:
javaagent:/home/admin/jacoco_new/jacocoagent.jar=includes=com.company.*,output=tcpserver,port=2019,address=192.168.110.111
注意其他地方基本不用改动
4.请求被测服务的接口,意思是要捣鼓下被测服务。
5.获取jacoco.exec文件
java -jar jacococli.jar dump --address 127.0.0.1 --port 6300 --destfile jacoco.exec
6.使用jacoco.exec文件与项目源码,基于源码生成覆盖率报告
java -jar jacococli.jar report ./jacoco.exec --classfiles D:\shaoxchen\newgulimall\gulimall-thrid-party\target\classes --sourcefiles D:\shaoxchen\newgulimall\gulimall-thrid-party\src\main\java --html html-report --xml report.xml --encoding=utf-8
五、Jacoco报告展示
部分内容引用,感谢。
https://blog.csdn.net/Michaelwubo/article/details/121142621
https://zhuanlan.zhihu.com/p/659896804