测试覆盖率 基于 jacoco 实现 class 多版本覆盖率合并

陈先生 · 2024年01月12日 · 最后由 陈先生 回复于 2024年12月11日 · 4776 次阅读

https://gitee.com/chen_zai_xing/jacocogit 上去了,开源多版本合并的代码,放到
代码覆盖率还是测试侧关注的东西,从网上也没找到类似的方案。第一次发布在 CSDN 上,从 CSDN 搬了过来,希望对大家有所帮助。
回到正文,基于 jacoco 二开,不同版本 class 的方法指令合并参考 ray 大佬的https://blog.csdn.net/tushuping/article/details/131640959?spm=1001.2014.3001.5502,大佬在文中未提及指令签名带上指令相对于方法中的序号,这里补充说明下。上面方案解决了同个方法就合并覆盖率,取有覆盖率的指令行数据合并。
需要理解的是 jacoco 指令的概念,jacoco 最小的统计单位就是指令。不了解的话可以百度下 java 字节码,想要弄清楚 jacoco 的插桩逻辑和报告生成逻辑这块必须要懂。CSDN 博文链接:https://blog.csdn.net/qq_34418450/article/details/135386280?spm=1001.2014.3001.5501

上述方案解决了方法级别报告覆盖率合并的问题,但是不能完美解决不同时间点合并多个版本覆盖率。比如 A->B->C 测试节点,A->B>C 是个完整的测试节点,但是有些测试是在 B 节点完成的,整个测试流程不能直接合并 A 和 C 的覆盖率,直接合并 A 和 C 的覆盖率会丢失 B 节点的覆盖率,需要同时合并 A->B->C 的覆盖率,这也是本文主要解决的问题。
本方案是合并探针的数据,在 report.java 增加一个参数控制是否生成报告还是生成 exec 文件,在多个版本合并的时候每次合并的时候选择生成 exec 文件,这样就解决 A->B->C 的问题,先合并 AB,产生新的 exec 文件,然后使用新的 exec 文件再次和 C 的进行合并,得到最终的 exec 文件,根据最终的 exec 文件再生成最终的覆盖率报告。

现在需要解决的问题就是怎么才能合并方法探针的数据。具体方法在 Instruction 类增加一个 probeIndex 变量,在 report 调用 MethodAnalyzer 的时候记录方法指令的探针 probeId,probeId 是 probes 中的探针的顺序,如果我们可以知道方法中的指令对应的探针 probeId,那么在合并方法指令的时候就可以同时更新探针的数据。jacoco 插桩时候的探针顺序是 ClassProbesAdapter 中的 counter 控制的,也就是说我们只需要拿到这个 counter 的值就可以知道当前的探针顺序。在 IProbeIdGenerator 接口类增加一个 getId 方法,返回当前的 probeId。在 IProbeIdGenerator 接口类增加一个 getId 方法,ClassProbesAdapter 中实现 getId 方法,返回当前的 probeId。


在调用 MethodAnalyzer 的时候去获取当前的探针 probeId,builder.addInstruction(currentNode, sign, currentProbeId) 传入当前的探针顺序,这样子就可以记录方法中指令的探针 probeId 了,在后面进行方法的指令合并时候,同时合并探针。

合并方法指令和探针

增量覆盖率集成到了自动化测试平台,支持多个不同 class 版本报告合并,改造了报告生成,加了 svn 提交人和相关 bug、需求提交信息列,正在落地推广使用

目前楼主测试开发岗位,专注效能这块,有感兴趣的同行可以加微信交流下,ray 大佬的群满了,考虑新建个小群,备注效能交流

共收到 2 条回复 时间 点赞
陈先生 关闭了讨论 01月12日 16:07
陈先生 重新开启了讨论 01月12日 16:08

你好,用了你发布的版本试了下不同版本 class 合并 exec 文件,依然对于 class 文件有变更的合并,跟 jacoco 官方的 merge 出来的结果一样

你好,参数传入对了吗,可以参考下仓库的例子

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册