jacoco的多次代码提交merge分析

2024-04-27 16:18

本文主要是介绍jacoco的多次代码提交merge分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

jacoco的merge命令主要用来合并dump生成的exec文件,具体实施场景为分布式集群环境时由于覆盖请求负载到不同的机器上产生多个exec文件后我们再做merge操作,从而获取到代码的整体覆盖率,具体操作如下图所示:

命令如下:

java -jar jacococli.jar merge [<execfiles> ...] --destfile <path> [--help] [--quiet]

示例:

java -jar jacococli.jar merge 1.exec 2.exec --destfile /var/merged.exec

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

但是官方明确了,只有相同代码生成的exec文件才能做merge操作,那么如下场景我们需要怎么做呢?

这里先插一句:其实jacoco的report命令本身支持传入多个exec文件,他会将其进行合并,所以可以省略merge这个步骤

比如说:

项目发测了,第一轮测试dump生成了exec文件

后面又进行了两轮测试,从而生成了三份exec文件,而我想查看本次整体测试的代码覆盖率怎么办呢,jacoco官方不知道这样搞,那我们只能自己搞搞了,我们需要找出为啥不能合并,一层层剥开它的壳

1.下载jacoco官网源码,找到merge的测试类,加一个测试方法,简单指定了合并后文件目录,需要合并的exec文件目录

2.debug模式运行,前面解析命令的可以不用看,我们直接看核心方法

解析完命令后,这里加载我们需要合并的exec文件,大体逻辑器,先加载一个文件解析文件里面的类id,类名和探针,存放在一个map里面,然后将后面的类和探针进行合并,最终生成合并后的数据集合

这里是逐个类进行解析,这里获取到了类的id,类的全限定名和类里面的探针,核心逻辑就在这里了

我们看看最后合并操作

合并前会classid,类全限定名以及探针数量的对比,其中一项失败就会导致整个类合并失败,看到这里想必大家有所了解了

那么classId是什么呢?classid讲解  Currently ids are created with a CRC64 checksum of the raw class file,我们修改类里面的代码这个id肯定是不同的

如果我们去掉这个id的对比,如果类发生了变化,探针对应的顺序就会错乱,导致A方法的探针跑到B方法

盗图可耻图片来源如果有侵权请大佬联系我删除

所以这种方案是行不通的,是否有新的方案,我再思考下。



分割

最近和群里的小伙伴们讨论了很多方案,有些小伙伴们按照了自己的想法也实现了多个代码版本合并。这里我整理下我最近的一些想法。

首选我们如果要合并覆盖率就不能以原生的方式去合并class id。我们需要修改源码,按照类名去做合并,同时我们需要把原来的覆盖率转换为方法的覆盖行。我们肯定不能用新的类无脑覆盖旧的类,这样准确率就相差比较大了,我们看下面具体的思路

 

 上图所示,我们假设有四个类,我们的变动都是在第一次变动后的第二次变动,interface可以理解成一个接口,使我们一个业务逻辑的起始方法,我们按照变动的范围逐一分析。

  • 假设变动的是interface1,因为interface1的变动我们要重新覆盖,我们在覆盖interface1的时候可能对其所调用的方法methodA等做了其他分支的覆盖,所以现在的策略应该是,interface1使用新的覆盖,interface1所调用的方法合并两次的覆盖
  • 假设我们变动的methodA,显然我们的methodA需要使用新的覆盖,旧的覆盖作废,而其调用的方法需要合并两次的覆盖,而调用其的方法interface1同样需要合并两次的覆盖
  • 假设我们变动的是methodC,则其覆盖使用新的数据,所有调用其的调用链所涉及的方法,都需要合并两次的覆盖,
  • 假设我们变动的是methodB,这里的策略依旧是methodB使用新的,其调用和被其调用的方法链上的覆盖都都需要合并两次的,这里有一个涉及点,因为methodB的变动,可能会影响methodC的变动情况,或者说methodA的重新覆盖,也会影响其所有调用方法的覆盖情况,所以这里的methodC我们也需要做两次覆盖的情况

整体流程大体如上所述,我们需要考虑方法的变动而引起的覆盖变化,合并的时候部分直接使用旧的覆盖,部分使用新的覆盖,部分合并两次的覆盖,我们要明确好具体的合并策略。

无论是否使用上述方案合并,我们最基础的都是需要拿到方法的调用链,调用链又分为静态调用链和动态调用链,动态调用链更准确,但是不合适我们这边的使用场景,我们需要使用静态代码分析出变更方法的调用链

总结下:合并代码多次变更覆盖的方案

  1. 修改jacoco的merge源码,将覆盖的行转换成方法覆盖的行,修改原本按照classId合并的方案,按照类名去合并
  2. 分析变更代码的调用链,确定其影响范围,明确方法的覆盖策略(code-diff已经支持分析静态调用链的源码可以参考)

以上就是针对多次提交代码覆盖率合并的设想,可能存在问题,欢迎大家一起讨论。

这篇关于jacoco的多次代码提交merge分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/940961

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

SpringBoot+Redis防止接口重复提交问题

《SpringBoot+Redis防止接口重复提交问题》:本文主要介绍SpringBoot+Redis防止接口重复提交问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录前言实现思路代码示例测试总结前言在项目的使用使用过程中,经常会出现某些操作在短时间内频繁提交。例