基于 Jacoco 的二次开发【解决不同版本 exec 数据合并问题】

概述

  对于 Jacoco 理想的使用场景:在测试阶段,能够实时统计手工测试的代码覆盖率情况

了解了 jacoco 的一些基本使用方法后,发现要满足这个使用场景,至少需要解决 2 个问题。

  • 类修改,带来的探针数据合并问题
  • 方法的修改,对探针数据造成的影响

下面讲讲具体问题以及解决思路

重点说明:以下实践使用普通 java 类测试,并且我所使用的是 JDK8。大于 JDK8 版本的插桩逻辑并不相同,如果是 JDK9 及以上版本,可能并不适用

问题一

  类修改,带来的探针数据合并问题

图 1


如图 1 所示,修改前的 Hello.java 文件,包含 3 个方法:A/B/C,修改后包含 4 个方法:A/B/C/D。
收集修改前 Hello 类的探针数据 (假设 A/B 方法已执行):dump1.exec
修改 Hello 中的 B 方法,然后重新收集探针数据 (假设 C/D 方法已执行):dump2.exec
dump1.exec 和 dump2.exec 的数据合并,想要合并后的覆盖率数据中包括:已被执行方法【A/C/D】,未被执行方法:【B】
合并 exec 数据使用 jacoco 的 merge 指令,merge 对于同一个类文件数据是否能合并的主要判断逻辑代码如下:

public void assertCompatibility(final long id, final String name,
            final int probecount) throws IllegalStateException {
 /**
 这里是我加的注释
同一个java文件,每次修改后对应生成的classId都是不一致的,
所以在这个地方就会被判断不通过,无法合并同一个java文件的统计数据
假设这里注释掉id的判断逻辑,继续往下执行
 */
        if (this.id != id) { 
            throw new IllegalStateException(
                    format("Different ids (%016x and %016x).",
                            Long.valueOf(this.id), Long.valueOf(id)));
        }
        if (!this.name.equals(name)) {
            throw new IllegalStateException(
                    format("Different class names %s and %s for id %016x.",
                            this.name, name, Long.valueOf(id)));
        }
/**
还是我加的注释
如果上面的id判断逻辑注释掉,在这里面探针数组长度的时候还是会校验失败,
Hello.java文件修改后,新增了D方法,导致Hello类文件的探针数据长度是发生了变化,这里长度校验会失败;
假设没有新增D方法,同时假设数组长度刚好一致能够合并。但同时无法过滤掉修改前(dump1.exec)B方法的统计数据
所以仅仅注释掉id的判断逻辑是行不通的
*/
        if (this.probes.length != probecount) {
            throw new IllegalStateException(format(
                    "Incompatib
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值