当前位置:首页 > 科技  > 软件

你们单测覆盖率是如何统计的?原理是什么?

来源: 责编: 时间:2024-04-02 17:23:05 260观看
导读高手回答我们在进行单元测试时,经常需要关注一个覆盖率的指标,许多发布流程甚至要求达到特定的百分比。那么,单元测试覆盖率是如何统计的呢?其底层实现原理又是怎样的呢?单元测试覆盖率的统计原理实际上是通过字节码插桩实

高手回答

我们在进行单元测试时,经常需要关注一个覆盖率的指标,许多发布流程甚至要求达到特定的百分比。wLt28资讯网——每日最新资讯28at.com

那么,单元测试覆盖率是如何统计的呢?其底层实现原理又是怎样的呢?wLt28资讯网——每日最新资讯28at.com

单元测试覆盖率的统计原理实际上是通过字节码插桩实现的。也就是说,在编译期间会向代码中注入一些特殊的监控代码,以记录测试执行过程中代码的执行情况,从而推断代码的覆盖情况。这些监控代码能在运行时记录代码的执行情况,也能在编译时生成代码覆盖率报告。wLt28资讯网——每日最新资讯28at.com

常见的单元测试覆盖率统计工具包括JaCoCo、Emma、Cobertura等,这些工具能够在编译或运行时对代码进行插桩,并记录代码的执行情况,最终生成覆盖率报告。wLt28资讯网——每日最新资讯28at.com

具体见下表:wLt28资讯网——每日最新资讯28at.com

工具
wLt28资讯网——每日最新资讯28at.com

Jacoco
wLt28资讯网——每日最新资讯28at.com

Emma
wLt28资讯网——每日最新资讯28at.com

Cobertura
wLt28资讯网——每日最新资讯28at.com

原理
wLt28资讯网——每日最新资讯28at.com

使用 ASM 修改字节码
wLt28资讯网——每日最新资讯28at.com

修改 jar 文件,class 文件字节码文件
wLt28资讯网——每日最新资讯28at.com

基于 jcoverage,基于 asm 框架对 class 文件插桩
wLt28资讯网——每日最新资讯28at.com

覆盖粒度
wLt28资讯网——每日最新资讯28at.com

行,类,方法,指令,分支
wLt28资讯网——每日最新资讯28at.com

行,类,方法,基本块,指令,无分支覆盖
wLt28资讯网——每日最新资讯28at.com

项目,包,类,方法的语句覆盖/分支覆盖
wLt28资讯网——每日最新资讯28at.com

插桩
wLt28资讯网——每日最新资讯28at.com

on the fly、offline
wLt28资讯网——每日最新资讯28at.com

on the fly、offline
wLt28资讯网——每日最新资讯28at.com

offline,把统计代码插入编译好的class文件中
wLt28资讯网——每日最新资讯28at.com

生成结果
wLt28资讯网——每日最新资讯28at.com

在 Tomcat 的 catalina.sh 配置 javaangent 参数,指出需要收集覆盖率的文件,shutdown 时才收集,只能使用 kill 命令关闭 Tomcat,不要使用 kill -9
wLt28资讯网——每日最新资讯28at.com

html、xml、txt,二进制格式报表
wLt28资讯网——每日最新资讯28at.com

html,xml
wLt28资讯网——每日最新资讯28at.com

缺点
wLt28资讯网——每日最新资讯28at.com

需要源代码
wLt28资讯网——每日最新资讯28at.com

1、需要 debug 版本,并打来 build.xml 中的 debug 编译项;2、需要源代码,且必须与插桩的代码完全一致
wLt28资讯网——每日最新资讯28at.com

1、不能捕获测试用例中未考虑的异常;2、关闭服务器才能输出覆盖率信息(已有修改源代码的解决方案,定时输出结果;输出结果之前设置了 hook,会与某些服务器的 hook 冲突,web 测试中需要将 cobertura.ser 文件来回 copy
wLt28资讯网——每日最新资讯28at.com

性能
wLt28资讯网——每日最新资讯28at.com


wLt28资讯网——每日最新资讯28at.com

小巧
wLt28资讯网——每日最新资讯28at.com

插入的字节码信息更多
wLt28资讯网——每日最新资讯28at.com

执行方式
wLt28资讯网——每日最新资讯28at.com

maven,ant,命令行
wLt28资讯网——每日最新资讯28at.com

命令行
wLt28资讯网——每日最新资讯28at.com

maven,ant
wLt28资讯网——每日最新资讯28at.com

Jenkins 集成
wLt28资讯网——每日最新资讯28at.com

生成 html 报告,直接与 hudson 集成,展示报告,无趋势图
wLt28资讯网——每日最新资讯28at.com

无法与 hudson 集成
wLt28资讯网——每日最新资讯28at.com

有集成的插件,美观的报告,有趋势图
wLt28资讯网——每日最新资讯28at.com

报告实时性
wLt28资讯网——每日最新资讯28at.com

默认关闭,可以动态从 jvm dump 出数据
wLt28资讯网——每日最新资讯28at.com

可以不关闭服务器
wLt28资讯网——每日最新资讯28at.com

默认是在关闭服务器时才写结果
wLt28资讯网——每日最新资讯28at.com

维护状态
wLt28资讯网——每日最新资讯28at.com

持续更新中
wLt28资讯网——每日最新资讯28at.com

停止维护
wLt28资讯网——每日最新资讯28at.com

停止维护,不支持java1.8的lamda表达式
wLt28资讯网——每日最新资讯28at.com

什么是字节码插桩

Java字节码插桩技术是指在编译期或运行期,通过修改Java字节码的方式,在代码中插入额外的代码。这种技术可以在不改变Java源代码的情况下,对Java应用程序的运行时行为进行监控、调试、分析和优化等操作。举例来说,它可以用于实现性能监控、代码覆盖率检测、代码安全扫描等功能。wLt28资讯网——每日最新资讯28at.com

字节码插桩技术通常包括以下几个步骤:wLt28资讯网——每日最新资讯28at.com

  1. 生成目标类的字节码,这一步可以通过Java编译器(如javac)或其他工具(如AspectJ)来完成。
  2. 解析字节码,识别需要进行插桩的代码区域(如方法、循环、异常处理等)。
  3. 插入额外的字节码,通常通过编写Java代码来实现这一步,然后利用字节码生成库(如ASM、Javassist等)生成相应的字节码。
  4. 将修改后的字节码重新写回到磁盘或内存中,以供后续使用。

假设我们希望对一个Java方法进行性能监控,我们可以在方法的入口和出口处分别插入计时器,以统计方法的执行时间。以下代码展示了如何实现这一功能:wLt28资讯网——每日最新资讯28at.com

public class Monitor {    public static void start() {        long startTime = System.nanoTime();        // 将起始时间记录到ThreadLocal中,以便在方法返回时进行计算        ThreadLocalHolder.set("startTime", startTime);    }    public static void end() {        long endTime = System.nanoTime();        // 获取起始时间        long startTime = (long) ThreadLocalHolder.get("startTime");        // 计算方法执行时间        long elapsedTime = endTime - startTime;        System.out.println("Method execution time: " + elapsedTime + "ns");    }}public class Example {    public void method() {        Monitor.start();        // 执行方法逻辑        Monitor.end();    }}

然而,若需监控多个方法的性能,分别在每个方法中插入Monitor.start()和Monitor.end()将导致代码重复、可读性下降,并存在遗漏的风险。在这种情况下,可以借助字节码插桩技术,在编译期或运行期间自动向每个方法的入口和出口处插入Monitor.start()和Monitor.end(),以确保代码的统一性和可维护性。wLt28资讯网——每日最新资讯28at.com

具体实现可借助字节码生成库ASM或Javassist来实现,此处以ASM为例。以下代码展示了如何使用ASM对Example类进行字节码插桩:wLt28资讯网——每日最新资讯28at.com

import org.objectweb.asm.ClassReader;import org.objectweb.asm.ClassVisitor;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;import java.io.IOException;public class MonitorTransformer implements Opcodes {    public static byte[] transform(byte[] classBytes) throws IOException {        ClassReader reader = new ClassReader(classBytes);        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);        ClassVisitor visitor = new ClassVisitor(Opcodes.ASM5, writer) {            @Override            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {                MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);                // 只为指定方法添加字节码插桩                if ("method".equals(name) && "()V".equals(desc)) {                    mv = new MethodVisitor(Opcodes.ASM5, mv) {                        @Override                        public void visitCode() {                            super.visitCode();                            // 在方法执行之前插入字节码                            mv.visitMethodInsn(INVOKESTATIC, "Monitor", "start", "()V", false);                        }                        @Override                        public void visitInsn(int opcode) {                            // 在方法返回之前插入字节码                            if (opcode == RETURN) {                                mv.visitMethodInsn(INVOKESTATIC, "Monitor", "end", "()V", false);                            }                            super.visitInsn(opcode);                        }                    };                }                return mv;            }        };        reader.accept(visitor, ClassReader.EXPAND_FRAMES);        return writer.toByteArray();    }}


wLt28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-80882-0.html你们单测覆盖率是如何统计的?原理是什么?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 深度解析Git核心机理,你学会了吗?

下一篇: 代码是如何被被编译的?

标签:
  • 热门焦点
  • 卢伟冰长文解析K60至尊版 对Redmi有着里程碑式的意义

    在今天的Redmi后性能时代战略发布会结束之后,Redmi总经理卢伟冰又带来了一篇长文,详解了为什么 Redmi 要开启后性能时代?为什么选择和 MediaTek、Pixelworks 深度合作?以及后性
  • 官方承诺:K60至尊版将会首批升级MIUI 15

    全新的MIUI 15今天也有了消息,在官宣了K60至尊版将会搭载天玑9200+处理器和独显芯片X7的同时,Redmi给出了官方承诺,K60至尊重大更新首批升级,会首批推送MIUI 15。也就是说虽然
  • K8S | Service服务发现

    一、背景在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;图片对于测试「Tes」环境或者
  • 分享六款相见恨晚的PPT模版网站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS网站旨在为全球Office用户提供丰富的高品质原创PPT模板、实用文档、数据图表及个性化定制服务。优点:OfficePLUS是微软官方网站,囊括PPT模板、Word模
  • 三分钟白话RocketMQ系列—— 如何发送消息

    我们知道RocketMQ主要分为消息 生产、存储(消息堆积)、消费 三大块领域。那接下来,我们白话一下,RocketMQ是如何发送消息的,揭秘消息生产全过程。注意,如果白话中不小心提到相关代
  • 网红炒股不为了赚钱,那就是耍流氓!

    来源:首席商业评论6月26日高调宣布入市,网络名嘴大v胡锡进居然进军了股市。在一次财经媒体峰会上,几个财经圈媒体大佬就“胡锡进炒股是否知道认真报道”展开讨论。有
  • 华为HarmonyOS 4升级计划公布:首批34款机型今日开启公测

    8月4日消息,今天下午华为正式发布了HarmonyOS 4系统,在更流畅的前提下,还带来了不少新功能,UI设计也有变化,会让手机焕然一新。华为宣布,首批机型将会在
  • 利用职权私自解除被封帐号 Meta开除20多名员工

    11月18日消息,据外媒援引知情人士表示,过去一年时间内,Facebook母公司Meta解雇或处罚了20多名员工以及合同工,指控这些人通过内部系统以不当方式重置用户帐号,其
  • 荣耀Magic4 至臻版 首创智慧隐私通话 强劲影音系统

    2022年第一季度临近尾声,在该季度内,许多品牌陆续发布自己的最新产品,让大家从全新的角度来了解当今的手机技术。手机是电子设备中,更新迭代十分迅速的一款产品,基
Top