当前位置: 首页 > news >正文

JUnit 单元自动化

一、Junit 是什么?

Junit 是 Java 中用于单元测试的框架。使用 Junit 能让我们快速高效的完成单元测试。

  • 自动化测试:JUnit提供了自动化测试的能力,开发人员可以编写一次测试用例,然后通过简单的命令或集成到持续集成工具中进行反复运行,大大减少了重复性的测试工作量。
  • 注解和断言:JUnit使用注解对测试方法进行标记,使用断言进行结果验证,让测试用例编写更为简洁、直观,同时减少了手动编写测试代码的出错概率。

传统模式下,我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,然后编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个 main() 方法里面。这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。

二、配置 Junit 环境

配置 Junit 只需要在单元测试中导入相关依赖即可,我们这里使用的是 Junit5。maven 地址:https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api/5.8.2

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.8.2</version><scope>test</scope>
</dependency>

下面我们写个demo测试一下是否导入成功:

import org.junit.jupiter.api.Test;
public class JunitTest {@Testvoid testDemo() {System.out.println("这是第一个单元测试!");}
}

1、常用注解

  • @Test 注解用于标记测试方法。JUnit 将会执行所有被 @Test 注解标记的方法作为测试用例。

  • @Disabled 注解用于标记测试方法并禁用它,这在你暂时不想执行某个测试方法时非常有用。

  • @BeforeAll 注解用于标记在所有测试方法执行之前只需执行一次的方法。且被该注解修饰的方法必须为静态方法。通常用于初始化静态资源。

  • @AfterAll 注解用于标记在所有测试方法执行之后只需执行一次的方法。且被该注解修饰的方法必须为静态方法。通常用于释放静态资源。

  • @BeforeEach 注解用于标记在每个测试方法之前需要执行的方法。通常用于初始化测试环境。

  • @AfterEach 注解用于标记在每个测试方法之后需要执行的方法。通常用于清理测试环境。

public class JunitTest {@BeforeAllstatic void setUp() {System.out.println("所有测试方法执行之前执行BeforeAll");}@AfterAllstatic void tearDown() {System.out.println("所有测试方法执行结束后执行AfterAll");}@BeforeEachvoid setUpEach() {System.out.println("在每个测试方法执行前执行BeforeEach");}@AfterEachvoid tearDownEach() {System.out.println("在每个测试方法执行之后执行AfterEach");}@Testvoid testDemo1() {System.out.println("testDemo1()");}@Testvoid testDemo2() {System.out.println("testDemo2()");}@Disabledvoid testDemo3() {System.out.println("testDemo3()");}
}

2、断言

在 JUnit 中,断言是用于验证测试结果是否符合预期的工具,以下是一些常用的 JUnit 断言方法:

  • assertEquals(expected, actual):验证两个值是否相等。适用于比较基本数据类型或对象。
  • assertNotEquals(unexpected, actual):验证两个值是否不相等。
  • assertTrue(condition):验证条件是否为 true。
  • assertFalse(condition):验证条件是否为 false。
  • assertNull(object):验证对象是否为 null。
  • assertNotNull(object):验证对象是否不为 null。
  • assertArrayEquals(expectedArray, resultArray):验证两个数组是否相等。
  • assertSame(expected, actual):验证两个引用是否指向同一个对象。
  • assertNotSame(unexpected, actual):验证两个引用是否指向不同的对象。
  • assertThrows(expectedException, executable):验证方法是否抛出了预期的异常。

下面写一个简单的使用示例:

public class JunitTest {@Testvoid testDemo1() {Assertions.assertEquals("aaa","aaa");Assertions.assertTrue(true);}@Testvoid testDemo2() {Assertions.assertTrue(false);}
}

3、参数化

参数化用例可以帮我们更好的管理测试用例,将测试数据与测试用例分离,实现测试用例的重用。JUnit 5 提供了 @ParameterizedTest 注解来支持参数化测试,使用前需要先导入相关依赖。maven仓库地址:https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params/5.8.2

@ParameterizedTest 需要搭配数据源用于为参数化测试提供测试数据,以下是一些常用的数据源及其用法:

(1)@ValueSource 注解:用于提供基本类型的单一值作为参数,例如整型、字符串、布尔等。

    @ParameterizedTest@ValueSource(ints = {1,2,3})void test(int num) {System.out.println(num);}

(2)@EnumSource 注解:用于提供枚举类型作为参数,可以指定包含的枚举类型。

    // 定义一个枚举enum Season {a,b,c}@ParameterizedTest@EnumSource(Season.class)void test2(Season season) {System.out.println(season);}

(3)@CsvSource 注解:允许你直接内联定义CSV格式的数据,作为参数传递给测试方法。

    @ParameterizedTest@CsvSource({"apple, 1","banana, 2","orange, 3"})void testWithCsvSource(String fruit, int count) {// 测试代码System.out.println("fruit = "+fruit+", count = "+count);}

(4)@CsvFileSource 注解:允许你从外部CSV文件中读取数据作为参数传递给测试方法。

    @ParameterizedTest@CsvFileSource(resources = "test-data.csv", numLinesToSkip = 1)void testWithCsvFileSource(String name, String gender ,int age) {// 测试代码System.out.println("name = "+name+", gender = "+gender+", age = "+age);}

:通常情况下,CSV文件的第一行会包含列标题或者字段名,描述了每一列数据的含义。当使用@CsvFileSource进行参数化测试时,使用 numLinesToSkip = 1 跳过第一行可以避免将列标题作为测试数据传递给测试方法。

(5)@MethodSource 注解:用于指定一个方法作为数据源,该方法必须返回一个Stream、Iterable、Iterator或者数组。

    public static Stream<Arguments> generateData() {return Stream.of(Arguments.arguments("张三",18,"男"),Arguments.arguments("张三",19,"女"),Arguments.arguments("李四",20,"女"));}@ParameterizedTest@MethodSource("generateData")void testWithSimpleMethodSource(String name,int age,String gender) {// 测试代码System.out.println("name = "+name+", age = "+age+", gender = "+gender);}

4、测试用例的执行顺序

在 JUnit 中,测试方法的执行顺序本身是不保证的,并不像我们想的一样是从上至下依次执行的,为例反证这一点,我们可以写个Demo演示一下:

但是在实际测试中,我们需要完成连贯的多个步骤的测试,是需要规定测试用例执行的顺序的。JUnit 5 中的 @TestMethodOrder 注解可用于指定测试方法的执行顺序。

@TestMethodOrder 注解可以与实现了 MethodOrderer 接口的自定义顺序器一起使用,以便根据特定的排序策略执行测试方法。JUnit 5提供的主要测试方法排序器:

  • MethodNameOrderer:按照方法名的字典顺序执行测试方法。
  • Random:随机执行测试方法。
  • OrderAnnotation:根据@Order注解中指定的顺序执行测试方法。

MethodNameOrderer 测试

Random测试

OrderAnnotation 测试

5、测试套件

当我们一个类中有多个测试用例时,我们不可能挨个去运行,那样将会很耗费时间,这时我们就需要 测试套件 来指定类或者指定包名来运行类下或者包下的所有测试用例。在Junit中可以使用@Suite标记测试套件,使用时需要导入依赖。maven 地址:https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite/1.9.1

另外使用 suite 需要引入 引擎engine 依赖。maven 地址:https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine/5.8.2

(1)指定 Class 执行测试用例

使用注解:@SelectClasses({指定类, 指定类, 指定类})

(2)指定包执行测试用例

使用注解:@SelectPackages(value = {"包1", "包2","..."})

PS:如果使用包名来指定运行的范围,那么该包下的所有的测试类的命名需要以 Test 或者 Tests结尾(T必须大写);

相关文章:

JUnit 单元自动化

一、Junit 是什么&#xff1f; Junit 是 Java 中用于单元测试的框架。使用 Junit 能让我们快速高效的完成单元测试。 自动化测试&#xff1a;JUnit提供了自动化测试的能力&#xff0c;开发人员可以编写一次测试用例&#xff0c;然后通过简单的命令或集成到持续集成工具中进行…...

Vue3 源码解读系列(十一)——插槽 slot

slot 插槽的实现实际上就是一种 延时渲染&#xff0c;把父组件中编写的插槽内容保存到一个对象上&#xff0c;并且把具体渲染 DOM 的代码用函数的方式封装&#xff0c;然后在子组件渲染的时候&#xff0c;根据插槽名在对象中找到对应的函数&#xff0c;然后执行这些函数做真正的…...

[github初学者教程] 分支管理-以及问题解决

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于新西兰奥克兰大学攻读IT硕士学位。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。跨领域…...

见面礼——图论

给定一个 n 个点 n 条边的无向图&#xff0c;你需要求有多少种选择图上的一个点 p 和一条边 (x,y) 的方案&#xff0c;使得删去 (x,y) 后图变成一棵树&#xff0c;且这棵树以 p 为根时每个节点的儿子个数均不超过 3。保证至少存在一种这样的方案。 Input 输入的第一行一个整数…...

【论文阅读】SPARK:针对视觉跟踪的空间感知在线增量攻击

SPARK: Spatial-Aware Online Incremental Attack Against Visual Tracking introduction 在本文中&#xff0c;我们确定了视觉跟踪对抗性攻击的一个新任务&#xff1a;在线生成难以察觉的扰动&#xff0c;误导跟踪器沿着不正确的&#xff08;无目标攻击&#xff0c;UA&#x…...

MR混合现实教学系统在汽车检修与维护课堂教学中的应用

传统的汽车检修与维护课堂教学主要依赖教师口头讲解和黑板演示&#xff0c;这种方式存在一定的局限性。首先&#xff0c;对于一些复杂的机械结构和操作过程&#xff0c;教师难以生动形象地展示给学生。其次&#xff0c;学生无法直接观察到实际操作中的细节和注意事项&#xff0…...

CentOS7安装xvfb,解决服务器没有X-Server的问题

Linux服务器上一般没有图形界面,但是有时候有些软件又需要图形界面.比如oracle,自动化测试(puppeteer).运行的时候会提示没有没有X服务. 这时候一般不会去特地装图形界面.这个时候就要用xvfb来创建虚拟图形窗口. xvfb介绍 Xvfb(X Virtual Frame Buffer)是基于X Window的虚拟服…...

快速集成Skywalking 9(Windows系统、JavaAgent、Logback)

目录 一、Skywalking简介二、下载Skywalking服务端三、安装Skywalking服务端3.1 解压安装包3.2 启动Skywalking 四、关于Skywalking服务端更多配置五、Java应用集成skywalking-agent.jar5.1 下载SkyWalking Java Agent5.2 集成JavaAgent5.3 Logback集成Skywalking5.4 集成效果 …...

起立科技(起鸿)在第25届高交会上展示透明OLED技术创新

第二十五届中国国际高新技术成果交易会 日期&#xff1a;2023年11月15日 地点&#xff1a;福田会展中心7号馆 深圳&#xff0c;2023年11月15日 — 起鸿科技&#xff0c;作为透明OLED领域的引领者&#xff0c;于今日参展了第二十五届中国国际高新技术成果交易会。这一展会将汇…...

大模型LLM 在线量化;GPTQ\AWQ量化

1、大模型LLM 在线量化 参考:https://www.cnblogs.com/bruceleely/p/17348782.html ##8bit model = AutoModel.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True).quantize(8).half(...

记一次线上bug排查-----SpringCloud Gateway组件 请求头accept-encoding导致响应结果乱码

基于公司的业务需求&#xff0c;在SpringCloud Gateway组件的基础上&#xff0c;写了一个转发服务&#xff0c;测试开发阶段运行正常&#xff0c;并实现初步使用。但三个月后&#xff0c;PostMan请求接口&#xff0c;返回异常&#xff0c;经排查&#xff0c;从日志中获取到转发…...

复杂数据统计与R语言程序设计实验一

1.下载并安装R语言软件&#xff0c;熟悉基本操作的命令及操作界面&#xff0c;掌握软件的使用方法&#xff08;提供学号加姓名的截图&#xff09;。 2.下载并安装Rstudio&#xff0c; &#xff08;提供运行代码及运行结果的截图&#xff09;。 3.下载并安装R包DT&#xff0c;…...

UEFI实战——键盘操作

一、键盘操作 UEFI下如何获取键盘键值,用户输入按键方式分两种:一种是单个按键,另外一种是组合按键。两种方式对应两个Protocol服务,接下来分步讲解。 二、单个按键 单个按键使用Protocol服务是EFI_SIMPLE_TEXT_INPUT_PROTOCOL,它定义在MdePkg/Include/Protocol/Simple…...

苹果CMS首涂第30套可装修DIY主题模板免授权版

这是一款可以装修的主题&#xff0c;类似淘宝店装修一样&#xff0c;可以针对首页、栏目页、详情页、播放页进行自定义装修&#xff0c;内置10个模块自由选择、添加、修改、删除、排序操作&#xff0c;后续升级还会增加更多实用和个性模块供选择&#xff0c;主题内包含的导航、…...

C#每天复习一个重要小知识day2:有参与无参构造函数

using System;public class MyClass {private int value;// 有参构造函数public MyClass(int v){this.value v;}// 无参构造函数public MyClass(){this.value 0;}public static void Main(string[] args){// 使用有参构造函数实例化对象MyClass obj1 new MyClass(10);Consol…...

大语言模型的三阶段训练

为了训练专有领域模型&#xff0c;选择LLaMA2-7B作为基座模型&#xff0c;由于LLaMA模型中文词表有限&#xff0c;因此首先进行中文词表的扩展&#xff0c;然后进行三阶段训练&#xff08;增量预训练&#xff0c;有监督微调&#xff0c;强化学习&#xff09;。 代码将全部上传…...

面试题c/c++ --STL 算法与数据结构

1.6 STL 模板 模板底层实现&#xff1a;编译器会对函数模板进行两次编译&#xff0c; 在声明的地方对模板代码本身进行编译&#xff0c; 在调用的地方对参数替换后的代码进行编译。 模板传参分析 模板重载 vector 是动态空间&#xff0c; 随着元素的加入&#xff0c; 它的内…...

云原生微服务-理论篇

文章目录 分布式应用的需求分布式架构治理模式演进ESB 是什么&#xff1f;微服务架构 MSA微服务实践细节微服务治理框架sidercar 什么是service mesh&#xff1f;康威定律微服务的扩展性什么是MSA 架构&#xff1f;中台战略和微服务微服务总体架构组件微服务网关服务发现与路由…...

Unity模拟薄膜干涉效果

Unity制作薄膜干涉效果&#xff0c;色彩斑斓的黑色石头 大家好&#xff0c;我是阿赵。   这次来做一个模拟薄膜干涉的彩色效果&#xff0c;Shader是使用ASE来连接&#xff0c;也算是ASE做复杂一点的效果的一个例子吧。 一、什么是薄膜干涉 以下解释来源于百度百科&#xff1…...

AIGC ChatGPT4对Gbase数据库进行总结

ChatGPT4 用一个Prompt完成Gbase数据库的总结。 AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 数据库Mysql 8.0 54集 数据库Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 Excel 2021实操 …...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

SQL Server 触发器调用存储过程实现发送 HTTP 请求

文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...