研发效能 精准测试实践

大佬喝可乐 · 2025年03月16日 · 最后由 向上 回复于 2025年03月20日 · 5588 次阅读

项目背景

日常工作中测试常被灵魂追问

你怎么证明自己的测试案例已经覆盖了业务逻辑?

你都已经测试完了,为什么上线后还有 BUG?

准备一下复盘资料。。。。。。

是啊,我们怎么才能证明本次迭代变动的代码已经被完全覆盖了呢。

我们明明已经和产品,开发对齐过测试案例了,为什么上线的时候还有业务逻辑没有覆盖呢?

每次发版都心惊胆战,生怕发版当天就要毕业了。

基础知识

jacoco 是一个开源的 Java 代码覆盖率工具,其工作原理主要通过字节码插桩来实现。

JaCoCo 通过在 Java 字节码中插入额外的字节码指令来收集覆盖率数据,这些指令用于记录代码的执行情况。

JaCoCo 的工作原理

‌字节码插桩‌:JaCoCo 通过在字节码级别修改 Java 类文件,添加额外的字节码指令来收集覆盖率数据。插桩分为静态插桩和动态插桩:

静态插桩‌:在编译后的.class 文件中插入覆盖率收集代码,通常在构建过程中进行。

‌动态插桩‌:在应用程序运行时通过 Java Agent 动态地对类进行插桩,不修改原始字节码的情况下实现覆盖率收集。

‌生成覆盖率数据文件‌:JaCoCo 在方法入口、分支点(如 if、switch 语句)、循环结构等重要代码路径上插入代码,记录这些路径是否被执行。

生成覆盖率报告:收集到的数据通过数据处理器结合程序执行轨迹信息和代码结构信息生成代码覆盖率报告,报告可以图形化展示为 HTML、XML 等格式。

以上是 AI 生成的,不是很好理解,说人话就是:
在你 java 应用启动的时候,插入了一个数据,这个数据用来记录你的 java 代码有没有被执行,如果被执行了,那么这个字段就会被标记执行,如果没有执行,那就不会被标记,最后,可以通过这个字段的数据来生成项目的覆盖率,得到一个覆盖率报告

方案设计

官方提供的 jacoco 的覆盖报告,是项目的全量覆盖率报告。而现实工作中,我们会更加关注当前版本的覆盖率报告,而不是整个项目的。这我们就需要对官方的报告进行二开,改造为更符合日常的增量报告。

得益于目前公司规范化的 CICD 系统,我们能获取到整个部署流程需要的一切数据比如:部署的版本,版本号,部署容器的 ip,项目的 git 信息等。

我们能将覆盖率收集的环境轻松的结合在持续集成的流程中,以下是整体获取覆盖率的流程

流程说明:

  • 1、系统部署时,主动上传应用的部署信息,后续精准平台会通过上传的 ip 进行请求
  • 2、精准测试平台主动发起请求业务系统,判断是否有配置 jacoco 服务,如果有服务,则下载对应服务的全量覆盖率数据
  • 3、精准平台根据 CICD 系统提供的业务代码的部署信息,版本信息,分支代码等信息,主动去 git 仓库中获取代码
  • 4、编译对应版本信息的代码,同时 diff 获取改动的代码详情与全量覆盖率数据,生成对应版本的增量覆盖率代码
  • 5、测试周期内,会有多次部署,每次部署重复上述过程,只需要将每次测试的覆盖率进行合并即可。

效果

这里无法提供现实项目的数据,理解一下意思即可。

全量数据就是整个项目的覆盖率数据,包含了历史代码的覆盖率,

增量数据就是本次迭代代码的覆盖率数据,版本周期内,更多的关注增量数据。

全量报告数据

增量报告数据

图片来源https://blog.csdn.net/tushuping/article/details/112613528

精准 2.0 展望

目前该项目已在公司运行约半年时间,对接了大部分 java 应用, 有效的协助研发团队对版本质量的把控,取得了研发测试的一致好评。

上面这只是精准测试的一部分,今年对于精准测试的规划是实现对测试流量的染色,让日常的测试精准的定位到业务代码,形成代码和案例的知识库,当后续改动到这个代码片段时,就能从知识库中,获取到对应的案例,精准的进行案例推荐。

参考项目:

https://github.com/rayduan/code-diff

https://gitee.com/chen_zai_xing/jacoco

共收到 22 条回复 时间 点赞

“你都已经测试完了,为什么上线后还有 BUG?” 经典提问,我觉得 jacoco 解决不了这个问题😂

这只是实现了覆盖率测试,离精准测试还差的远着呢,算不上是 1.0。

【目前该项目已在公司运行约半年时间,对接了大部分 java 应用】
运行半年后,还有人问【你都已经测试完了,为什么上线后还有 BUG?】的问题吗? 你咋回答

开始上线的项目做得大部分是功能测试,后期优化的时候,考虑的多是场景测试,就容易遗漏,或者出现上线的版本影响了之前的功能

爱偷懒的QA 回复


这里的精准只做到了 识别到改动代码,并进行测试。个人认为算是一定意义上的精准

我去催饭 回复

确实,只能证明测试了对应的代码,具体的业务场景如果有缺陷,还是会有 bug

目前没有人问过,但是项目宣导的时候其实已经说明了,只能证明测试验证到了变动的代码,但是无法证明业务功能没有缺陷

陈小晓 回复

这个是我们今年要做的,就是通过 caseid 关联到执行的代码块,然后后续的版本如果变动到了代码块,就会将对应的 caseid 关联出来,进行 回归案例的推荐

陈小晓 回复

所以精准测试要做链路分析,评估新需求影响的范围,推荐受影响的用例来进行回归,以达到用最小的测试用例集覆盖最多的功能

这是大多数人的下一步,然后往往会掉进如何二开 jacoco 才能关联 caseId 这个坑上,没别的意思,就是友情提醒一下😂

小狄子 回复

谢谢大佬的提醒,这个目前已经识别出来了,进入清洗阶段了。获取到很多 get,set 方法还有匿名方法,框架的方法,又是个麻烦事

很多时候我理解得是卷别个~卷自己的指标没有意义,既然都插装了单测覆盖率不比功能测试覆盖率更好弄

爱偷懒的QA 回复

有个疑问, 如果采用了推荐的用例回归, 但回归的部分还有缺陷上线 (非新增功能, 假设是回归覆盖的范围不足/遗漏), 谁对这个结果负责?

小狄子 回复

我们公司自己写了个 java 项目的覆盖率工具,能够对流量进行打标,可以精确到用例级别,实现用例与代码的关联。之前考虑过二开 jacoco 实现,有点难

吼猴 回复

感觉还是测试背锅的。精准只是提供变更范围,以及对应的接口及用例。至于未改动的接口是否受到了影响并不知道的,需要测试人员自己识别

yc9721 回复

确实,二开 jacoco 有一定难度,我也是自己写的工具,没用 jacoco

小狄子 回复

看了你的 2023 年终总结,你们是用 jvm-sandbox 来实现覆盖率的?能说下大概思路吗?之前我们其实也考虑过用 jvm_sandbox 实现,但是好像有点没法实现

大佬,如何学习这块啊?可有偿

Test-zhou 回复

可以关注一下 git : https://github.com/dalaohekele ,后续会写一些细节方面的文章

yc9721 回复

jvm-sandbox 本身有 lineEvent 了这个可以用作行覆盖,参考 jacoco 的字节码关于分支的插桩逻辑,我自己扩展了 branchEvent,实现了分支的跟踪,而且能跟踪到分支表达式的 true false,这样就有了分支覆盖,大概思路就是这样

有大佬用 python 进行精准化测试验证的吗

python 可以用 javalang 模块去做

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册