单元测试覆盖率

什么是单元测试覆盖率

关于其定义,先来看一下维基百科上的一段描述:

代码覆盖(Code coverage)是软件测试中的一种度量,描述程序中源代码被测试的比例和程度,所得比例称为代码覆盖率。

简单来理解,就是单元测试中代码执行量与代码总量之间的比率。

以一个最简单的例子来直观感受一下:

Service服务类:

public class NumToStringServiceImpl implements NumToStringService {@Overridepublic String num2Str(Integer i) {String str = "";switch (i) {case 1:str = "one";break;case 2:str = "two";break;default:str = "none";}return str;}
}

单元测试类:

public class NumToStringServiceTest {@AutowiredNumToStringService numToStringService;@Testvoid testNum2Str() {String str1 = numToStringService.num2Str(1);assertThat(str1, is("one"));String str2 = numToStringService.num2Str(2);assertThat(str2, is("two"));}
}

从上面的代码中能看出,单元测试方法testNum2Str能够覆盖到服务类num2Str方法的case 1case 2两个分支,覆盖不到default分支。那么覆盖率就是num2Str方法case 1case 2分支的代码量除以方法的总代码量。

单元测试覆盖率框架

单元测试覆盖率常用的框架有JaCoCoEMMACobertura。我们目前(在Jenkins中)使用的是JaCoCo。

JaCoCo可以统计的指标有:

  1. 指令(C0 Coverage):JaCoCo计数的最小单元是单一的Java字节码指令。指令覆盖率提供了关于字节码执行数量、未执行数量的信息。
  2. 分支(C1 Coverage):对所有的ifswitch语句计算分支覆盖率。统计在方法中分支执行数量、未执行数量的信息。但要注意,异常处理不在此计算范围内。
  3. 圈复杂度(Cyclomatic Complexity):对非抽象方法计算圈复杂度,并汇总类、包和组的(圈)复杂度。这个值可以做为单元测试用例是否完全覆盖的参考。
  4. 行(Lines):一行可能包含一条或多条指令,如果至少有一条指令被执行了,那么该行就算作是被执行了。
  5. 方法(Methods):每个非抽象方法至少包含一条指令。如果至少有一条指令被执行了,那么该方法就算作是被执行了。
  6. 类(Classes):如果类中至少有一个方法被执行了,那么该类就算作是被执行了。

注:个人认为,最需要关注的指标是(Lines)和分支(C1 Coverage),其次是方法(Methods)和(Classes),指令(C0 Coverage)和圈复杂度(Cyclomatic Complexity)可以不用关注,因为跟(Lines)和分支(C1 Coverage)其实是差不多的,只不过多了一种参考维度。

查看单元测试覆盖率

在IntelliJ IDEA中已经内置了JaCoCo插件,因此研发可以在本机运行单元测试来查看覆盖率:

1、点击IDE右上侧的"Edit Configurations...":

2、在"Choose coverage runner"中选择JaCoCo:

 

3、点击"Run ... with Coverage"运行:

 

 4、运行完成后会展示分支(C1 Coverage)、(Lines)、方法(Methods)、(Classes)这四个指标:

 5、点击"Generate Coverage Report"可以生成一份html版的所有指标的报告:

 

JaCoCo与持续集成

1、需要在项目的<plugins>中加入JaCoCo插件:

<plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artifactId><version>0.8.5</version><executions><execution><id>default-prepare-agent</id><goals><goal>prepare-agent</goal></goals></execution><execution><id>default-report</id><goals><goal>report</goal></goals></execution></executions>
</plugin>

目前发现如果项目中不加以上配置,而是在Jenkinsfile中

 以命令的方式去应用JaCoCo,会导致不能生成jacoco.exec,进而无法运行覆盖率测试。

2、在Jenkinsfile中加入

 

exclusionPattern: '**/controller/*.class', sourceExclusionPattern: '**/controller/*.java'

可以过滤掉controller层的检测。因为目前我们的单元测试主要是针对service层的,如果把controller层的类引入进来,会使单元测试覆盖率的值变低。

3、可以在Jenkins(http://${ip}:${port}/job/${your_project}/lastBuild/jacoco/)中查看生成的单元测试覆盖率报告:

 

该报告与IntelliJ IDEA中的报告都是JaCoCo原生的,是准确的。

目前发现SonarQube中的报告一是不准,二是指标不全,建议不要查看SonarQube的报告。

题外话

覆盖率作为衡量单元测试质量的唯一标准是不合理的。比如下面这个例子:

public double cal(double a, double b) {if (b != 0) {return a / b;}
}


仅一个测试用例就可以做到100%的覆盖率,比如cal(10.0, 2.0),但并不代表测试足够全面了,还需要考虑当除数等于0的情况下,代码执行是否符合预期。


---------------------
作者:谷隐凡二
来源:CSDN
原文:https://blog.csdn.net/m0_37570494/article/details/125440949
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/24301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言实现map数据结构 key—value对应

1.首先43行 createKeyValuePair(char*key ,int value)这个函数就是给一个keyValuePair *pair的指针来通过内存分配将数据key和value存入这个pair指针所对应的内存空间 2.52行freeKeyValuePair这个函数是释放内存空间 3.头文件 struct结构体KeyValuePair就是一个指针一个值 4…

GO语言 服务发现概述

https://zhuanlan.zhihu.com/p/32027014 明明白白的聊一下什么是服务发现-CSDN博客 一、服务发现 是什么 在传统的系统部署中&#xff0c;服务运行在一个固定的已知的 IP 和端口上&#xff0c;如果一个服务需要调用另外一个服务&#xff0c;可以通过地址直接调用。 但是&…

软件巨头SAP裁员优厚条件,吸引5300名员工争相离职

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 在科技行业的大潮中&#xff0c;SAP公司近日因一项颇具争议的裁员计划而备受瞩目。但这次裁员风波并未如往常般引发员工的强烈抗议&#xff0c;反…

D365 子窗体调用父窗体方法

文章目录 一、在子窗体中调用父窗体公共方法二、刷新 CallerForm 数据源 一、在子窗体中调用父窗体公共方法 Object callerForm element.args().caller(); if(callerForm is FormRun && formHasMethod(callerForm, identifierStr(parentMethod))) {callerForm.parent…

知网-数学学习与研究-收稿邮箱

知网-数学学习与研究-收稿邮箱 《数学学习与研究》杂志是由东北师范大学主管&#xff0c;吉林省数学会与东北师范大学出版社联合主办的省级优秀数学类期刊杂志。 主管单位&#xff1a;东北师范大学 主办单位&#xff1a;吉林省数学会;东北师范大学数学与统计学院 创刊时间1983…

AI学习指南机器学习篇-决策树基本原理

AI学习指南机器学习篇-决策树基本原理 在机器学习领域&#xff0c;决策树是一种常见且十分重要的算法。它不仅在分类任务中被广泛应用&#xff0c;还可以用于回归任务。本篇博客将详细介绍决策树的基本原理&#xff0c;包括节点、分裂准则、信息增益、基尼不纯度等概念&#x…

msvcr120.dll丢失怎样修复?为什么msvcr120.dll文件很重要

msvcr120.dll​ 是一个属于 Microsoft Visual C 2013 Redistributable package 的动态链接库文件。这个文件对于运行使用 Visual Studio 2013 开发的应用程序是必要的&#xff0c;因为它包含了C运行时库的一部分功能&#xff0c;这些功能是标准C库中与输入/输出操作、字符串操作…

OpenCV中的圆形标靶检测——斑点检测算法(二)

前面的章节中我们已经大致介绍了算法流程,也对一些算法中用到的相关概念做了简要介绍,同时给出了算法调用的API,现在我们开始算法检测接口实现源码的分析。 1. 斑点的分组与加权 这里我们选择后者,先了解算法的处理流程,再分析各个模块的实现。算法流程图如下图所示,上一…

android中调用onnxruntime框架

创建空白项目 安装Android Studio及创建空白项目参考&#xff1a;【安卓Java原生开发学习记录】一、安卓开发环境的搭建与HelloWorld&#xff08;详细图文解释&#xff09;_安卓原生开发-CSDN博客 切记&#xff1a;build configuration language 一定选择Groovy&#xff01;官…

51单片机-LCD液晶显示

目录 前言: 一. LCD1602模块简介 二. 代码功能实现 三.总结 前言: 本文主要是51单片机的LCD液晶显示,使用的是LCD1602.下面是详细介绍和完整代码,欢迎大家的点赞,评论和关注.感谢. 一. LCD1602模块简介 LCD1602 模块具有以下特点&#xff1a; 显示特点&#xff1a; 可以…

MySQL 将null转0 ifnull() coalesce()

做统计报表的时候&#xff0c;有时候不希望查出来的值是null&#xff0c;因为在代码中需要做大量的判空&#xff0c;最后转换成0来处理。既然如此&#xff0c;那在sql中查出来就是0&#xff0c;就不用为空而去判空了。 1.IFNULL() ifnull()只能放2个值。 select IFNULL(null,0…

[240608] Zig 发布 v0.13.0 |AMD 新处理器不支持 Win 10 |DuckDuckgo 发布AI匿名聊天服务

目录 Zig 发布 0.13.0 版本AMD 下一代锐龙处理器不支持 Windows 10DuckDuckgo 发布 AI 匿名聊天服务 Zig 发布 0.13.0 版本 Zig 发布 0.13.0 版本&#xff0c;此次发布的主要目的是升级 zig 工具链&#xff0c;发布重点如下&#xff1a; 工具链升级&#xff1a; LLVM&#xf…

DevOps的原理及应用详解(六)

本系列文章简介&#xff1a; 在当今快速变化的商业环境中&#xff0c;企业对于软件交付的速度、质量和安全性要求日益提高。传统的软件开发和运维模式已经难以满足这些需求&#xff0c;因此&#xff0c;DevOps&#xff08;Development和Operations的组合&#xff09;应运而生&a…

企业建站响应式网站建设平台版源码系统 海量模版可选择 带完整的安装代码以及搭建教程

系统概述 企业建站响应式网站建设平台版源码系统是一款集创新性、实用性和便捷性于一体的建站解决方案。它旨在为用户提供一站式的网站建设服务&#xff0c;无论你是新手还是经验丰富的开发者&#xff0c;都能通过该系统轻松实现网站的构建与部署。 该系统采用先进的技术架构…

单链表复习 (C语言版)

目录 一.顺序表与链表的区别 二.链表概念 三.单链表 1.单链表的开始与初始化 2.单链表的打印 3.单链表的尾插 重难点&#xff1a;单链表实现时的指针详解 4.单链表的头插 5.单链表的尾删 6.单链表的头删 小结&#xff1a; 7.单链表的查找 8.在指定位置前插入数据 …

mingw64,clang,gcc

MinGW-w64、Clang 和 GCC 都是编译器&#xff0c;但它们在功能和设计上有一些区别&#xff1a; MinGW-w64 是一个在 Windows 平台上的开发工具集&#xff0c;它提供了一组 GNU 工具和库&#xff0c;可以用于编译和构建本地的 Windows 应用程序。MinGW-w64 的主要目标是提供类似…

GitHub工程获取第三方PR操作

GitHub工程获取第三方PR操作 1. 源由2. 获取第三方PRStep 1&#xff1a;安装ghStep 2&#xff1a;获取个人TokenStep 3&#xff1a;通过git协议获取代码Step 4&#xff1a;获取第三方PR分支 3. 总结 1. 源由 通常来说&#xff0c;GitHub上通常有三种场景&#xff1a; 工程管理…

STM32 UART 错误代码 HAL_UART_ERROR_PE

HAL_UART_ERROR_PE 是STM32 HAL库&#xff08;硬件抽象层库&#xff09;中UART&#xff08;通用异步收发传输器&#xff09;模块定义的一个错误码&#xff0c;表示“Parity Error”&#xff08;奇偶校验错误&#xff09;。当UART通信过程中检测到奇偶校验不匹配时&#xff0c;会…

自动化喷涂生产线方案三

本文介绍自动化喷涂生产线的另外一种方案&#xff0c;单工作站方案&#xff0c;单工作站配置一台机械臂和一套除尘柜&#xff0c;代替一个工位完成喷涂工艺&#xff0c;其工作原理简要介绍如下。 一套单工作站的主要组成设备有&#xff0c;10kg负载机械臂一台主要负责喷涂工艺&…

源码讲解kafka 如何使用零拷贝技术(zero-copy)

前言 kafka 作为一个高吞吐量的分布式消息系统,广泛应用与实时应用场景中。为了实现高效的数据传输,kafka使用了零拷贝技术(zero-copy)显著提高了性能。本文将详细讲解 Kafka 如何利用零拷贝技术优化数据传输。 什么是零拷贝 零拷贝技术目的是减少数据传输的效率。在传统…