导语:

Yuanhao Ji 同学是《暑期 2021 - API 模块 UT 测试问题解决》项目负责人,本文记录了他是如何排查和定位问题。

1. 背景

问题:在部分 UT 中使用 PowerMock 后,导致 Sonar 不能获取对应的测试报告。

大概原因PowerMock 模拟 JDK 的静态方法、构造方法、final 方法、私有方法时,需要把使用这些方法的类加入到 @PrepareForTest 注解中,从而导致单元测试覆盖率不被统计。

2. 思路

2.1 明确问题出处,缩小定位范围

DolphinScheduler UT 中使用了 PowerMock 作为单元测试模拟框架,由 JaCoCo 统计各项覆盖率指标,最后由 Sonar 存储和管理覆盖率数据。而问题表现为 —— Sonar 中的某些 UT 覆盖率为 0,但是 Sonar 只是一个代码质量管理平台,覆盖率数值并不是由它得出的,Sonar 只是读取了 JaCoCo 生成的测试报告。那么,很容易看出,这个问题一定与 JaCoCo 脱不了干系。

进一步观察发现,并非所有 UT 的覆盖率都有问题,只用到 JUnit 的 UT 就可以正常获取覆盖率,而所有出现覆盖率问题的 UT 都少不了 PowerMock 的影子。

因此,覆盖率问题一定与 PowerMockJaCoCo 有关。

2.2 搜集资料,寻找相似问题

分析问题之后,我们首先可以借助搜索引擎找到与之相似或相同的问题,通过了解这些问题的背景和解决方案也许可以找到我们问题的关键点。

基于以上分析,以 JaCoCoPowerMock覆盖率 这三个关键字在 Google、Baidu 等搜索引擎上搜索资料。幸运的是,网上有大量同类问题,并且都与 JaCoCoPowerMock 有关。

其中,正如 Code-coverage-with-JaCoCo[1] 中所说 —— There is NO WAY TO USE PowerMock with JaCoCo On-the-fly instrumentation。PowerMockJaCoCoOn-the-fly instrumentation 之间存在问题。经验证发现,DolphinScheduler 目前正是使用的这两者结合的方式,因此这应该就是问题的关键所在。

2.3 分析问题出现原因

基于搜索结果和官方文档,分析问题出现原因。

首先,如 JaCoCo Class Ids[2] 中的描述,JaCoCo 基于 CRC64 算法计算得到 64 位的 Class Id,用它来标识 Java 类,在运行时为每个加载的类采样执行数据并存储到 *.exec 文件中,在分析时(例如生成报告),Class Id 用于将分析的类与执行数据相关联。

而出现覆盖率为 0% ,就是因为待测试的类与 JaCoCo 实际采样的类不一致,也即通过 CRC64 算法计算的 Class Id 改变,从而导致待测试类的测试报告中覆盖率始终为 0。

那么,为何会出现这种 Class Id 改变的情况呢?上述页面中也给出了答复 —— 这种情况通常发生在配置 JaCoCo 代理之前配置了另一个 Java Agent,或者特殊的类加载器预处理了这些类文件,例如:Mocking frameworks、Application servers、Persistence frameworks。而 PowerMock 就是一种 Mock 框架,进一步了解其原理得知,JaCoCo 在加载 class 时会事先把统计代码插入到 class 中(即插桩),当执行到某个测试类时,PowerMock 检测到该类使用了@PrepareForTest 注解,就会在加载该类时使用 Javassist 直接从 class 文件中重新读取字节码,导致 JaCoCo 的修改丢失,稍后 JaCoCo 统计的 class 是被修改之后的,而被修改之后的 class 中并没有 JaCoCo 所插入的统计代码,并且 class 文件发生变化后 Class Id 也与加载时不一致。在分析时,测试结果无法关联到待测试类,最终导致覆盖率始终为 0。

如下图所示,Demo 类后面还跟有 MockitoMock 的字样,说明这是一个由 PowerMock 模拟的对象,而 JaCoCo 却错把它以为是最开始时所加载的 Demo 类。

2.4 制定解决方案

JaCoCooffline instrumentation 可以解决此类问题,它的原理是这样的:在测试前先对 class 文件进行插桩,然后生成插过桩的 class 文件或 jar 包,测试插过桩的 class 和 jar 包后,生成动态覆盖信息到文件,最后统一对覆盖信息进行处理,并生成报告。

On-the-fly 模式进行代码覆盖分析更方便和简单,无需提前进行字节码插桩,无需考虑 classpath 的设置。

但存在如下情况则不适合 On-the-fly,需要采用 offline 提前对字节码插桩:

(1)运行环境不支持 java agent。

(2)部署环境不允许设置 JVM 参数。

(3)字节码需要被转换成其他的虚拟机如 Android Dalvik VM。

(4)动态修改字节码过程中和其他 agent 冲突。

(5)无法自定义用户加载类。

而目前问题就是因为动态修改字节码过程中与 PowerMock 冲突,因此必须使用 offline 模式。

[1] https://github.com/powermock/powermock/wiki/Code-coverage-with-JaCoCo

[2] https://www.eclemma.org/jacoco/trunk/doc/classids.html

Apache DolphinScheduler 项目笔记 — 1. 问题定位和排查问题的更多相关文章

  1. 感谢有你!Apache DolphinScheduler 项目 GitHub star 突破 8k

    本周伊始,Apache DolphinScheduler 项目在 GitHub 上的 Github Star 总数首次突破 8K.目前,Apache DolphinScheduler 社区已经拥有 C ...

  2. Apache DolphinScheduler(海豚调度) - 1.3 系列核心表结构剖析

    Apache DolphinScheduler 是一个分布式去中心化,易扩展的可视化 DAG 工作流任务调度系统.致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用. 近日 ...

  3. 金灿灿的季节 - Apache DolphinScheduler收获5位新Committer

    在这个金灿灿的收获季节,经过 Apache DolphinScheduler PPMC 们的推荐和投票,Apache DolphinScheduler 收获了 5 位新Committer .他们是:n ...

  4. 金秋十月 - Apache DolphinScheduler 收获 2 位新 Committer

    点击上方蓝字关注 Apache DolphinScheduler Apache DolphinScheduler(incubating),简称"DS", 中文名 "海豚调 ...

  5. 新一代大数据任务调度 - Apache DolphinScheduler喜提十大开源新锐项目 & 最具人气项目

    经 10000+ 开发者公开票选,20+专家评审. 10+ 主编团打分,历经数月打磨,11 月 19 日,由InfoQ 发起并组织的[2020中国技术力量年度榜单评选]结果正式揭晓. 2020 年度十 ...

  6. 【喜讯】Apache DolphinScheduler 荣获 “2020 年度十大开源新锐项目”

    经 10000+ 开发者公开票选,20+专家评审. 10+ 主编团打分,历经数月打磨,11 月 19 日,由InfoQ 发起并组织的[2020中国技术力量年度榜单评选]结果正式揭晓. 2020 年度十 ...

  7. 大数据平台迁移实践 | Apache DolphinScheduler 在当贝大数据环境中的应用

    大家下午好,我是来自当贝网络科技大数据平台的基础开发工程师 王昱翔,感谢社区的邀请来参与这次分享,关于 Apache DolphinScheduler 在当贝网络科技大数据环境中的应用. 本次演讲主要 ...

  8. Apache DolphinScheduler 2.X保姆级源码解析,中国移动工程师揭秘服务调度启动全流程

    2022年1月,科学技术部高新技术司副司长梅建平在"第六届中国新金融高峰论坛"上表示,当前数据量已经大大超过了处理能力的上限,若信息技术仍然是渐进式发展,则数据处理能力的提升将远远 ...

  9. Apache DolphinScheduler 3.0.0 正式版发布!

    ​  点亮 ️ Star · 照亮开源之路 GitHub:https://github.com/apache/dolphinscheduler   ​ 版本发布 2022/8/10 2022 年 8 ...

随机推荐

  1. vision transformer

    VIT 总览 Step1 Step2

  2. Machine Learning With Go 第4章:回归

    4 回归 之前有转载过一篇文章:容量推荐引擎:基于吞吐量和利用率的预测缩放,里面用到了基本的线性回归来预测容器的资源利用情况.后面打算学一下相关的知识,译自:Machine Learning With ...

  3. springboot+layui 整合百度富文本编辑器ueditor入门使用教程(踩过的坑)

    springboot+layui 整合百度富文本编辑器ueditor入门使用教程(踩过的坑) 写在前面: ​ 富文本编辑器,Multi-function Text Editor, 简称 MTE, 是一 ...

  4. 一文搞懂Kafka的基本原理及使用

    Kafka的基本原理及使用 一.基本概念及原理 1.Kafka特点 Kafka 是一个分布式的流式平台,流式平台包括以下三个特点: 发布和订阅消息(流),类似于一个消息队列或企业消息系统 持久化收到的 ...

  5. SSH和SCP的使用方法

    1.SSH使用方法 ssh 用户名@IP 例: ssh ubuntu@192.168.1.190 最近因为项目需求,需要通过ssh来登录Windows,但是一开始一直无法登录,参考下面这个帖子解决了, ...

  6. House of apple 一种新的glibc中IO攻击方法

    目录 House of apple 一种新的glibc中IO攻击方法 前言 利用条件 利用原理 利用思路 思路一:修改tcache线程变量 思路二:修改mp_结构体 思路三:修改pointer_gua ...

  7. 使用vue实现排序算法演示动画

    缘起 最近做的一个小需求涉及到排序,界面如下所示: 因为项目是使用vue的,所以实现方式很简单,视图部分不用管,本质上就是操作数组,代码如下: { // 上移 moveUp (i) { // 把位置i ...

  8. freeswitch拨打分机号

    概述 电话语音服务中,有一种稍微复杂的场景,就是总机分机的落地场景,客户拨打总机号码之后,需要再拨打分机号转接到指定的话机. 分机号的拨打一般在总机接通之后,会有语音提示,总机收号之后转接分机. 分机 ...

  9. POI 给单元格添加批注

    图中红框框是处理单元格内容和批注的地方. 参考:https://blog.csdn.net/qq_38974638/article/details/114837631 //SXSSFWorkbook ...

  10. 查询效率提升10倍!3种优化方案,帮你解决MySQL深分页问题

    开发经常遇到分页查询的需求,但是当翻页过多的时候,就会产生深分页,导致查询效率急剧下降. 有没有什么办法,能解决深分页的问题呢? 本文总结了三种优化方案,查询效率直接提升10倍,一起学习一下. 1. ...