文章目录
概要
所有代码已经上传到gitee,仓库地址:https://gitee.com/chen_zai_xing/jacoco。最新版本支持自定义数据结构,如请求者IP,以IP划分探针数据,此版本暂时不考虑开源,需付费支持。
方法指令合并参考ray大佬的https://blog.csdn.net/tushuping/article/details/131640959?spm=1001.2014.3001.5502,大佬在文中未提及指令签名带上指令相对于方法中的序号,这里补充说明下。(序号是为了区分操作码和值一样的指令)。
上述方案解决了方法级别报告覆盖率合并的问题,但是不能完美解决不同时间点合并多个版本覆盖率。比如A->B->C测试节点,A->C是个完整节点,但是有些测试是在B节点完成的,整个测试流程不能直接合并A和C的覆盖率,需要同时合并A->B->C的覆盖率,这也是本文主要解决的问题。
官方提供的merge方法只能支持合并同个class内容的exec数据,只要class内容变更,那么根据class字节流计算出来的classId势必不同,所以无法满足使用场景:一个版本测试周期内,开发多次修改class并部署测试环境,生成覆盖率报告后不能展示完整的测试覆盖率。
基于上述的场景需要改造jacoco以支持合并不同的class覆盖率,实现同一个全类名的类,方法没有变更的覆盖率合并到新的同一个全类名的覆盖率。改造合并的逻辑是合并探针的数据,在report.java增加一个参数控制是否生成报告还是生成exec文件,在多个版本合并的时候每次合并的时候选择生成exec文件,这样就解决A->B->C的问题,先合并AB,把A的方法未变更的覆盖率合并到B,产生新的exec文件,然后使用新的exec文件再次和C的进行合并,得到最终的exec文件,根据最终的exec文件再生成最终的覆盖率报告。
现在需要解决的问题就是怎么才能合并同个方法探针的数据。具体方法在Instruction类增加一个probeIndex变量,在report调用MethodAnalyzer的时候记录方法指令的探针probeId,probeId是probes中的探针的顺序,如果我们可以知道方法中的指令对应的探针probeId,那么在合并方法指令的时候就可以同时更新探针的数据。jacoco插桩时候的探针顺序是ClassProbesAdapter中的counter控制的,也就是说我们只需要拿到这个counter的值就可以知道当前的探针顺序。在IProbeIdGenerator接口类增加一个getId方法,返回当前的probeId.
在调用MethodAnalyzer的时候去获取当前的探针probeId,builder.addInstruction(currentNode, sign, currentProbeId)传入当前的探针顺序,这样子就可以记录方法中指令的探针probeId了,在后面进行方法的指令合并时候,同时合并探针。
如有任何疑问可以加微信群交流下,备注效能交流,已建立效能交流