代码覆盖率Jacoco

jacoco源码:https://github.com/jacoco/jacoco
参考文章:https://blog.csdn.net/tushuping/category_10738357.html

Jacoco原理

  • Jacoco使用插桩方式来记录覆盖率数据,通过probe探针来注入
  • 插桩:是将一段代码通过某种策略插入到另一段代码,或者替换另一段代码,来收集程序运行时的动态上下文信息
    • 这里的代码既可以是字节码也可以是源码
    • JaCoCo就是字节码插桩方式
  • 字节码插桩的两种模式
    • on-the-fly模式
      • 在JVM中通过添加 -java agent 参数指定特定的 jar 文件启动 Instrumentation 的代理程序
      • 代理程序会在 ClassLoader 装载一个 class 前判断是否已经转换修改了该文件,如果没有则将探针插入class文件中,探针不改变原有方法的行为,只是记录是否已经执行
    • offline模式
      • 在测试之前先对文件进行插桩,生成插过桩的class或jar包,测试插过桩的class和jar包,生成覆盖率信息到文件,最后再统一处理,生成报告。
    • on-the-fly和offline对比
      • on-the-fly更方便简单,无需提前插桩,无需考虑classpath设置问题

Jacoco使用-命令行方式

  • 下载Jacoco:https://www.jacoco.org/jacoco/index.html
    • 下载后解压,只需要用到lib下的 jacocoagent.jar 和 jacococli.jar
  • 启动jacocoagent:
java -javaagent:xxx/jacocoagent.jar=includes=*,output=tcpserver,port=6300,adress=localhost,append=true -jar demo-0.0.1.jar

# emo-0.0.1.jar为被测项目jar包
# includes:需要在哪些包下面插桩,*表示所有,可以指定某个模块,比如:com.example.wms.controller
# output:覆盖率以什么方式输出,有3种方式
#	1.tcpserver:当去启动生成exec文件时,才会把所有插桩数据导出来,相当于一个服务
#	2.tcpclient:用的比较少
#	3.file:会在本地生成一个文件,当被测应用停止的时候,会把插桩数据写入该文件(用的比较少)
# adress+port:当想要访问覆盖率数据时,就需要访问 adress+port
  • 生成exec文件
java -jar xxx/jacococli.jar dump --address 127.0.0.1 --port 6300 --destfile jacoco-demo.exec

# address和port指向jacocoagent启动IP和端口
# jacoco-demo.exec 为生成exec文件名
  • 根据exec文件,生成report报表
java -jar xxx/jacococli.jar report jacoco-demo.exec --classfiles xxx/target/classes --sourcefiles xxx/src/main/java --html html-report --xml report.xml --encoding=utf-8

# classfiles为字节码路径
# sourcefiles为源码路径

Jacoco增量覆盖

什么是增量覆盖

  • 每行代码有3种状态:新增、删除、不变
  • 修改前后跑同一个测试用例,每行有4种状态:修改前覆盖/修改前未覆盖、修改后覆盖/修改后未覆盖
  • 增量覆盖共有3*4=12种情况,比较重要的有:新增代码未覆盖、新增代码已覆盖、不变的代码修改前覆盖,修改后未覆盖等

增量原理

  • 计算出两个版本的差异代码
  • 将差异代码在report阶段传给jacoco
  • 修改jacoco源码,生成报告时判断代码是否是增量代码,只有增量代码才生成报告
    在这里插入图片描述

增量覆盖实现

  • jacoco二开:https://gitee.com/Dray/jacoco
  • 增量代码获取:https://gitee.com/Dray/code-diff

Jacoco使用-Apache Ant方式

参考:https://www.eclemma.org/jacoco/trunk/doc/ant.html

第一步:配置build.xml文件

  1. build.xml文件位置:/home/perfma/jacoco-build/***-build.xml
  2. 以下配置项,需要修改:
    2.1 生成覆盖率报告的路径:jacocoReportPath
    2.2 远程tomcat服务打开的端口:server_port_gateway
    2.3 源代码路径:gatewaySrcPath
    2.4 class文件路径:gatewayClassesPath
<?xml version=1.0 encoding=UTF-8?>
<project name=JaCoCo default=run xmlns:jacoco=antlib:org.jacoco.ant>
    <!--Jacoco的安装路径-->
    <property name=jacocoAntPath value=/home/perfma/jacoco/lib/jacocoant.jar/>
    <!--最终生成.exec文件的路径,Jacoco就是根据这个文件生成最终的报告的-->
    <property name=jacocoExecPath value=/home/perfma/jacocoExec/>
    <!--生成覆盖率报告的路径-->
    <property name=jacocoReportPath value=/home/perfma/jacoco-report/aob-tdolphin-tom/>
    <!--远程tomcat服务的ip地址  xxx.xx.xxx.163(172.16.1.31)-->
    <property name=server_ip_test163 value=127.0.0.1/>
    <!--前面配置的远程tomcat服务打开的端口,要跟上面配置的一样-->
    <property name=server_port_gateway value=9011/>

    <!--源代码路径-->
    <property name=gatewaySrcPath value=/home/perfma/tdolphin-tom-code/tdolphin-tom/tdolphin-tom/src/main/java/>

    <!--.class文件路径-->
    <property name=gatewayClassesPath value=/home/perfma/tdolphin-tom-code/tdolphin-tom/tdolphin-tom/target/classes/>

    <!--让ant知道去哪儿找Jacoco-->
    <taskdef uri=antlib:org.jacoco.ant resource=org/jacoco/ant/antlib.xml>
        <classpath path=${jacocoAntPath}/>
    </taskdef>

    <target name=run>
        <echo message=start.../>
        <echo message=dump.../>
        <antcall target=dump/>
        <echo message=merge.../>
        <antcall target=merge/>
        <echo message=report.../>
        <antcall target=report/>
        <echo message=end.../>
    </target>

    <!--dump任务:
                      根据前面配置的ip地址,和端口号,访问目标tomcat服务,并生成.exec文件。-->
    <target name=dump>
        <jacoco:dump address=${server_ip_test163} reset=true destfile=${jacocoExecPath}/jacoco_gateway.exec port=${server_port_gateway} append=false/>
    </target>

    <target name=merge>
        <jacoco:merge destfile=${jacocoExecPath}/merged.exec>
            <fileset dir=${jacocoExecPath} includes=*.exec/>
        </jacoco:merge>
    </target>

    <!--jacoco任务:
                     根据前面配置的源代码路径和.class文件路径,
                     根据dump后,生成的.exec文件,生成最终的html覆盖率报告。-->
    <target name=report>
        <jacoco:report>
            <executiondata>
                <file file=${jacocoExecPath}/merged.exec/>
            </executiondata>

            <structure name=JaCoCo Report>
                <group name=coverage>
                    <sourcefiles encoding=UTF-8>
                        <fileset dir=${gatewaySrcPath}/>
                    </sourcefiles>
                    <classfiles>
                        <fileset dir=${gatewayClassesPath}/>
                    </classfiles>
                </group>

            </structure>

            <html destdir=${jacocoReportPath} encoding=utf-8/>
            <csv destfile=${jacocoReportPath}/report.csv/>
            <xml destfile=${jacocoReportPath}/report.xml/>
        </jacoco:report>
    </target>
</project>

第二步:启动被测应用

1.修改启动命令,以tdolphin-tom-jacoco应用为例,配置如下:
📢注意:端口号需要与build.xml文件中的端口号一致

jps -l | grep tdolphin-tom-jacoco | awk -F ' ' '{print$1}' | xargs -I {} kill -9 {}
sleep 2

APP_NAME=tdolphin-tom-jacoco
PERFMA_HOME=/home/perfma
LOGS_DIR=$PERFMA_HOME/logs/${APP_NAME}
VERSION=baseversion-0.0.1-SNAPSHOT
mkdir -p $LOGS_DIR
nohup java -javaagent:/home/perfma/jacoco/lib/jacocoagent.jar=includes=*,output=tcpserver,port=9011,address=127.0.0.1 -jar ${APP_NAME}-${VERSION}.jar &
echo ${APP_NAME}-${VERSION}.jar

第三步:测试被测应用

📢注意被测应用的端口号,不要搞错了

第四步:生成报告

1.执行 ant -f build.xml 生成报告
2.打包下载整个jacocoReport文件夹到本地,打开index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值