jacoco 代码覆盖率统计不上问题破解之谜

      最近在搞jacoco代码覆盖率,已经集成在公司现有的devops平台里,但是在实际的使用过程中发现测试人员明明已经执行过的测试用例,有些class覆盖率统计却为0、有些能正常统计出来,到底是怎么回事呢?接下来分享下解决这个问题的排查过程。

前提:代码没有任何变更,相同的代码、jdk8版本一样、mvn版本一样

第一步:jacoco本身是否支持类修改后,已经执行过的测试用例是否已经支持合并到最新统计中?

jacoco的源码本身是不支持同类修改后的再次合并统计的,因为数组探针不一样导致,因为我们是在jacoco多版本exec合并_jacoco合并exec-CSDN博客的基础上做的,也就解决了多版本合并不上的问题,因此不存在统计不上的问题,继续找原因

第二步:把被代理的应用代码本地部署、本地收集覆盖率

可以正常统计到,说明jacoco工具本身没问题,那么有点纳闷了,为什么部署在服务器统计不到?继续找原因

第三步:公司的CICD流程环节是否有问题?

从公司的CICD上入手考虑,先解释几个名词、简单交代下背景哈

a:devops-公司自主研发的交付流平台

b:工单-指一个需求对应的所需开发应用的代码工单号

c:部署平台-专门用于部署应用的自动化平台

d:开发模式:90%业务线基于分支上线,10%基于主干上线(gitlab的CICD),为什么是这样?原因很复杂,这样就不展开说了,现状如此。

CICD主流程:

1、在devops平台上创建需求关联开发工单、下拉分支

2、开发完成后,在devops上编译打包,实际调用的jenkins实现的代码编译打包,打出的jar/war包ftp到文件服务器

3、提测到测试阶段开始测试,测试人员根据包所在地址在部署平台上手动选择服务器部署;

4、测试人员测试完成后,开发根据测试过的版本去上线

5、上线验证没问题后,合并分支代码到主干

从整个CICD流程上来看,我们是把触发代码覆盖率应用初始化的步骤放在了部署这一步,当测试人员在部署平台部署的时候触发覆盖率服务,过程中需要下载代码、然后编译;而这时候编译出的class和从jenkins上编译出的包部署在服务器上的应用做代理通信,最后通过定时任务xxl-job收集覆盖率。即使代码没有任何变更,有些类的覆盖率统计也统计不到,问题大概就出在这里,顺着这个思路继续往下找原因。

第四步:会不会是两次编译的class不一样?

把从jenkins编译出的class(即应用打包的class)复制到覆盖率收集服务下,然后做代理通信,发现测试用例被统计到了,问题终于快找到了,应该是两次编译生成的class不一样。于是我把两次编译的class都搞到本地,做对比,我发现有些class完全一样,有些class却有差异,而有差异的都有个共同特点:使用了lambda表达式,如下图:

查资料解决lambda表达式?

Lambda 表达式在 Java 中被转换为一种叫做 "匿名内部类" 的特殊类型,这个过程发生在编译阶段。编译器会为每个 Lambda 表达式生成一个唯一的、匿名的类文件,这个类文件通常以 $ 符号和一些数字结尾来确保其唯一性。这样做的原因有几个方面:

  1. 匿名性:由于这些类没有显式的类名,所以被称为匿名类。Lambda 表达式的本质就是简洁地表示匿名函数,因此由它们生成的类也是匿名的。

  2. 实例化要求:Lambda 表达式可能捕获上下文中的局部变量和参数,这要求必须为每个不同的 Lambda 表达式实例化一个新的类,因为每个类都可能有不同的捕获需求。

  3. 唯一性:为了防止命名冲突,并确保在类加载器中不会出现重复的类名,编译器生成的类名是自动生成的,并且是唯一的。

  4. 实现细节:Java 语言规范并不规定具体的类名生成策略,这是 JVM 的具体实现细节。不同的 JVM 供应商或不同版本的同一供应商可能会采用不同的策略来生成类名。

  5. 避免冲突:如果每次编译都生成相同的类名,那么当多个类加载器加载了相同代码的不同版本时,可能会导致类名冲突,进而导致类加载错误或不可预期的行为。

  6. 字节码层面:Lambda 表达式编译后的类包含实现了对应接口方法的字节码,以及与 Lambda 表达式相关的其他信息,如捕获的变量等。

综上所述,Lambda 表达式编译时每次都不一样,它会动态生成calss,是因为需要确保每个 Lambda 表达式的唯一性、匿名性和上下文的正确捕获,同时防止潜在的类名冲突

第五步:结论-保证编译部署的class、应用包一致性

至此问题圆满解决!!!

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值