jacoco对接Jenkins为什么可以做到迭代统计?

总问题:
jacoco做代码覆盖率,如果发布代码了,会重新统计覆盖率。为什么我对接了Jenkins反而可以做到版本迭代的覆盖统计?

详情情况如下:

正常情况:
服务端当前正在运行的版本为v1.0的代码,我去做功能测试,然后去dump覆盖率的exec文件,统计的是你本次测试的覆盖率,比如 v1.0 1000行代码,本次功能测试覆盖了500行,覆盖率为50%并且可以看见覆盖的代码是哪些

迭代发版:
此时开发修复了bug重新部署了v1.0.1版本代码,再次做功能测试,然后去dump覆盖率的exec文件,统计本次测试的覆盖率,比如 v1.0.1 是1001行代码,本次功能测试覆盖了100行,覆盖率应该为10%

原因:
因为两次发版对于jacoco来说,是两次独立的覆盖率统计,自己亲测demo代码也确实是这样的,统计第一次时,停服务重启服务,再次覆盖统计,两次统计的代码是没有关系的。

对接Jenkins后:
但是当我把jacoco对接到Jenkins发现两次居然是可以关联的,虽然这就是我想要的理想效果,但是我不懂为什么?

对接方式:
1.jacoco的启动方式没有变化的,采用tcpserver形式,修改项目的启动脚本插入agent参数
nohup java -Dfile.encoding=UTF-8
-javaagent:/opt/devops/server/oxford-pic-book/jacocoagent.jar=includes=*,
output=tcpserver,
port=6300,
address=0.0.0.0,
append=true
-jar /opt/devops/xxxxx项目的.jar
-Xms1024m -Xmx2048m -Djava.security.egd=file:/dev/./urandom -jar /opt/devops/server/$sn/$sn.jar > /dev/null 2>&1 &

获取exec文件的方式:
在项目里面封装两个接口
调用接口1,在服务器上执行命令 生成 exec文件的命令 java -jar " + basePath + "jacococli.jar dump --address 127.0.0.1 --port 6300 --destfile " + basePath + "getdemo.exec

调用接口2,去把服务器上生成的exec文件 dump到 Jenkins项目文件里面

Jenkins 对应的job:
1.采用插件 jacoco,去扫项目文件的exec文件,编译class文件(这个是jacoco插件现成功能,我并没有做额外的改动)
2.每次构建Jenkins的jobs时,都去调用接口拉起新的exec文件,统计覆盖率

现在问题来了:
1.当我构建job时,如果项目代码一直在运行,这时覆盖率是叠加的,这个是正确的。因为我没发布项目代码,不管我构建多少次,exec文件,都是归属于本次测试

2.可是当我重新部署了项目代码,再次构建项目,按理说应该是算做一次新的独立的代理覆盖率。
因为我重新部署代码,意味着我把 javaagent 这个jacoco的监控服务停了,那么相应的本次覆盖的exec的数据,也是应该清0了没有了。当你再次启动javaagetn的监控服务时,是一个全新的干净的服务,exec的数据也是全新的。 造成的现像就是和上次测试覆盖率是没有关系。

3.可是结果恰恰相反,当我再次构建job时,拉取的exec文件会统计我上个版本覆盖的代码+本次覆盖的代码,并且哪些两个版本的差异代码,覆盖情况也是没有问题的,覆盖了,就是绿的,没覆盖就是空白的

这就是我想要的效果
应用场景:
1.测试期,肯定是需要反复发布代码的,我想要的就是我这一个测试周期总的覆盖率。因为你不可能每次发版都去跑一遍全量的用例,来保证覆盖度。如果不跑全量用例

我现在的疑问:
1.造成现在我想要的效果,是因为我对接了Jenkins,Jenkins的jacoco插件,赋予了这样的能力,还是其他什么原因?

我们公司,我在推广实施这个。求帮助解答

23号构建


20号构建

19号

可以看出来,是叠加的,最起码新的覆盖率,会包括之前统计的(这几次构建,不都是同一套代码,是有改完bug重新部署上去的代码)

是不是你的destfile没有清空,导致了前后多次覆盖率出现了累积

做个实验,每次发版后,下载下来的exec文件,不用Jenkins,直接使用原始方式命令方式做统计,发现还是累加覆盖的。说明,应该和思寒老师猜测的一样,问题是出在了服务端和Jenkins没关。就是每次这个exec文件就是累加的

实验了一下,就是思寒老师说的,当dump生成的 demo.exec 覆盖率文件,已经存在了,每次dump就是往demo.exec文件追加数据,从而造成了,覆盖率是累加的效果

现在问题,我 设置了 append=false 只要这个exec文件存在,也不会清除原内容覆盖成本轮的覆盖率结果。从我测试的结果来看,能累计统计的原因就是 已经存在exec文件每次不删除就会追加这个exec文件会越来越大,我的exec文件目前已经81M了,和append=true还是false没有关系。不知道对不对。

别从csdn上道听途说,看官方文档

https://www.jacoco.org/jacoco/trunk/doc/cli.html

刚看完谢谢思寒老师,做了对比实验

实验1

这个执行数据,在程序结束的时候,会不会丢失?

样本:

启动程序,执行case1, dump exec文件到 path1路径,生成报告,查看覆盖率,涵盖case1

参数 默认append =true

1组实验:

杀死程序重启,执行case2,dump exec文件到path2路径,生成报告,查看覆盖率 结果是case2

说明:确实执行数据是在内存里面的,jvm停止,覆盖率消失

2组实验:

杀死程序重启,执行case2,dump exec文件到path1路径,生成报告,查看覆盖率case1+case2

说明:当exec文件存在时,新dump下来的数据是追加操作

实验2

验证,当append=false时,如果exec文件已经存在,是否会覆盖而不是追加?

官网说:

append 如果设置为true并且执行数据文件已经存在,则覆盖数据将附加到现有文件中。如果设置为 false,将替换现有的执行数据文件。

样本:

启动程序,执行case1, dump exec文件到 path1路径,生成报告,查看覆盖率涵盖case1

参数 append =false

1组实验:

不杀死程序,执行case2,dump exec文件到path1路径,生成报告,查看覆盖率 结果是case1+case2

2组实验:

不杀死程序,执行case2,dump exec文件到path2路径,生成报告,查看覆盖率 结果是 case1+case2

结论:1组实验&2组实验结合说明,如果不重启,执行去多次dump,设置为 append =false 也是追加覆盖,因为不杀死进程都认为是一轮次覆盖结果,和exec文件是否存在无关

3组实验:

杀死程序,执行case2,dump exec文件到path1路径,生成报告,查看覆盖率 结果是 case1+case2

说明:结合上面几组实验,说明,只要重启就是一次全新的,覆盖也是因为文件存在直接追加

4组实验:

杀死程序,执行case2,dump exec文件到path2路径,生成报告,查看覆盖率 结果是 case2

结论:3组实验和4组实验结合,说明,只要重启服务,就是一次全新的统计和之前的无关,3组实验结果覆盖也是因为exec文件已存在直接追加,这个append =false也没起到作用,综合来看,当不重启服务这个append =false没起到覆盖作用,重启了是一次全新统计,也没


官网的这个,和我实验和使用后的结果是不符合的。如果官方是权威的话。那么这个参数肯定是有用的。可能只是我的使用场景,并不是人家官方解释的 参数的使用场景

或者我的实验做的是有问题的。但是不知道我的实验有问题在哪里?

jacoco的白色背景代表啥?

发现这种白色背景的,还不少,我是集成Jenkins jacoco插件的。

我的理解是那个append是针对file模式的,不适用于tcp模式

1 个赞