JUnit 单元自动化

news2024/9/24 11:30:55

一、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 {
    @Test
    void testDemo() {
        System.out.println("这是第一个单元测试!");
    }
}

1、常用注解

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

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

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

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

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

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

public class JunitTest {

    @BeforeAll
    static void setUp() {
        System.out.println("所有测试方法执行之前执行BeforeAll");
    }

    @AfterAll
    static void tearDown() {
        System.out.println("所有测试方法执行结束后执行AfterAll");
    }

    @BeforeEach
    void setUpEach() {
        System.out.println("在每个测试方法执行前执行BeforeEach");
    }

    @AfterEach
    void tearDownEach() {
        System.out.println("在每个测试方法执行之后执行AfterEach");
    }

    @Test
    void testDemo1() {
        System.out.println("testDemo1()");
    }

    @Test
    void testDemo2() {
        System.out.println("testDemo2()");
    }

    @Disabled
    void 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 {

    @Test
    void testDemo1() {
        Assertions.assertEquals("aaa","aaa");
        Assertions.assertTrue(true);
    }

    @Test
    void 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必须大写);

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

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

相关文章

OpenHarmony源码下载

OpenHarmony源码下载 现在的 OpenHarmony 4.0 源码已经有了&#xff0c;在 https://gitee.com/openharmony 地址中&#xff0c;描述了源码获取的方式&#xff0c;但那是基于 ubuntu 或者说是 Linux 的下载方式。在 windows 平台下的下载方式没有做出介绍。 我自己尝试了 wind…

力扣 hot100 最长连续序列 哈希去重 双指针

128. 最长连续序列 ⭐ AC code class Solution {public int longestConsecutive(int[] nums) {if (nums.length 0)// 特判为空的数组&#xff0c;返回0return 0; // set实现去重HashSet<Integer> set new HashSet<>();for (int x : nums)set.add(x);Object[] a…

基于springboot实现家政服务管理平台项目【项目源码+论文说明】计算机毕业设计

摘要 随着家政服务行业的不断发展&#xff0c;家政服务在现实生活中的使用和普及&#xff0c;家政服务行业成为近年内出现的一个新行业&#xff0c;并且能够成为大众广为认可和接受的行为和选择。设计家政服务管理平台的目的就是借助计算机让复杂的销售操作变简单&#xff0c;…

【MySQL--->视图】

文章目录 [TOC](文章目录) 一、概念二、操作三、视图特性 一、概念 视图是一个由插叙结果组成的虚拟表,基于表查询结果得到的表叫做视图,被查询的表叫做基表.基表和视图进行更新操作会互相影响. 二、操作 创建视图 将dept和emp两个基表的查询结果作为视图 更新基表会影响视…

FileNotFoundError: Could not find module ‘XXX\lib\site-packages\llvmlite

https://aka.ms/vs/17/release/vc_redist.x64.exe 解决方法:安装c环境 FileNotFoundError: Could not find module xxx\workenv\lib\site-packages\llvmlite\binding\llvmlite.dll (or one of its dependencies). Try using the full path with constructor syntax. 装了个新…

【装机】第一次装机记录

本篇文章记录第一次装机的过程。 配置 部件型号CPUAMD 锐龙 R5 7500F主板华硕 TUF GAMING A620M-PLUS显卡耕升 RTX4070 踏雪内存金百达 黑刃 DDR5 16G/32G 6000硬盘铠侠 2TB EXCERIA Pro SE10 极至超速系列电源微星 MAG A650BN散热利民 AX120 R SE AGHP逆重力热管支持LGA1700…

计算机视觉与机器学习D1

计算机视觉简介 技术背景 了解人工智能方向、热点 目前人工智能的技术方向有&#xff1a; 1、计算机视觉——计算机视觉(CV)是指机器感知环境的能力&#xff1b;这一技术类别中的经典任务有图像形成、图像处理、图像提取和图像的三维推理。物体检测和人脸识别是其比较成功…

基于java web个人财务管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux之进程概念(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、冯诺依曼体系结构二、操作系统(Operator System)1、概念2、设计OS的目的3、定位4、如何理…

5.Java中的注释及Javadoc文档

本文讲解 Java 中的注释以及 Javadoc 文档 ~ 文章目录 1. 注释1.1 引言1.1.1 何为注释&#xff1f;1.1.2 注释有何用&#xff1f;1.1.2.1 方便阅读1.1.2.2 调试程序 1.1.3 单行注释和多行注释 1.2 方法注释1.2.1 什么是方法注释&#xff1f;1.2.2 如何写方法注释&#xff1f;1.…

Spring面试题:(八)Spring事务

Spring事务概述 Spring事务基于数据库&#xff0c;基于数据库的事务封装了统一的接口。 编程式事务和声明式事务。 声明式事务分为Xml声明式或者注解声明式 实现事务相关的三个类 事务管理器 事务定义 事务状态 XML声明式事务的使用方法 导入坐标配置目标类配置切面 导入…

一个C语言程序的分析:运行速度和文件大小以及变量初始值

环境 Ubuntu 22.04gcc 11.4.0Window 11Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.6.2 运行速度 一个C程序 test1.c 如下&#xff1a; int array[30000][30000];int main() {for (int i 0; i < 30000; i)for (int j 0; j < 30000; j) …

ChatGPT最强?文心一言与ChatGPT对比

对于同一个问题我们分别对文心一言3.5和ChatGPT3.5输出回答&#xff0c;结果如下图&#xff0c;可以看到文心一言的回答更好&#xff0c;文心一言是由百度开发的人工智能语言模型&#xff0c;它的中文理解能力主要是基于百度强大的搜索引擎和自然语言处理技术。文心一言更加注重…

深入理解栈与队列:从基本概念到高级实现

&#x1f493; 博客主页&#xff1a;江池俊的博客⏩ 收录专栏&#xff1a;数据结构探索&#x1f449;专栏推荐&#xff1a;✅cpolar ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f525;编译环境&#xff1a;Visual Studio 2022&#x1f389;欢迎大…

算法设计与分析复习--贪心(二)

文章目录 上一篇哈夫曼编码单源最短路最小生成树Kruskal算法Prim算法 多机调度问题下一篇 上一篇 算法设计与分析复习–贪心&#xff08;一&#xff09; 哈夫曼编码 产生这种前缀码的方式称为哈夫曼树 哈夫曼树相关习题AcWing 148. 合并果子 #include <iostream> #inc…

Network(三)动态路由与ACL配置

一 三层交换机 1 三层交换机概述 三层交换二层交换三层转发 2 虚拟接口概述 在三层交换机上配置的VLAN接口为虚拟接口&#xff0c;使用Vlanif&#xff08;VLAN虚拟接口&#xff09;实现VLAN间路由&#xff0c;VLAN接口的引入使得应用更加灵活 三层交换机VLAN间通信的转发…

基于Qt QList和QMap容器类示例

## QList<T> QList<T>容器是一个数组列表,特点如下: 1.大多数情况下可以用QList。像prepend()、append()和insert()这种操作,通常QList比QVector快的多。这是因为QList是基于index标签存储它的元素项在内存中(虽然内存不连续,这点与STL的list 是一样的),比…

EDA实验-----4*4矩阵键盘与数码管显示测试(Quartus ‖)

目录 一、实验目的 二、实验仪器设备 三、实验原理 四、实验要求 五、实验步骤 六、实验报告 七、实验过程 1.矩阵键盘按键原理 2.数码管原理 3.分频器代码 4.电路图连接 5.文件烧录 一、实验目的 了解数码管的工作原理&#xff1b;掌握4*4矩阵键盘和数码管显示的编…

gradle8.0或者其他版本下载太慢或者time out超时(完美解决方法)

官网镜像地址 如果其他软件除了android studio可以在下面完整直接下载 地址&#xff1a;https://mirrors.cloud.tencent.com/gradle/ Android Stuiod如何配置更换 项目名称\gradle\wrapper\gradle-wrapper.properties 下面是我已经更改后的了&#xff0c;大家如果跟这个不一样换…

解决WPF项目xaml出现“正在等待IntelliSense完成”的问题

在WPF项目xaml里经常出现“正在等待IntelliSense完成”的场景&#xff0c;如下图&#xff1a; 解决办法 工具–选项