单元测试JUnit

news2024/9/23 3:32:49

  前言👀~

上一章我们介绍了自动化测试工具Selenium,今天讲解单元测试工具JUnit

JUnit

JUnit的使用

JUnit注解

BeforeAll和AfterAll注解

BeforeEach和AfterEach注解

参数化

方法获取参数(动态参数)

断言

用例执行顺序

测试套件


如果各位对文章的内容感兴趣的话,请点点小赞,关注一手不迷路,讲解的内容我会搭配我的理解用我自己的话去解释如果有什么问题的话,欢迎各位评论纠正 🤞🤞🤞

12b46cd836b7495695ce3560ea45749c.jpeg

个人主页:N_0050-CSDN博客

相关专栏:java SE_N_0050的博客-CSDN博客  java数据结构_N_0050的博客-CSDN博客  java EE_N_0050的博客-CSDN博客


JUnit

JUnit 是针对 Java 语言的单元测试框架,前面讲的selenium3,我们通过这个工具写出来的一个个自动化测试用例会发现有很多冗余的内容代码看起来不雅观且不好管理,所以就引出了JUnit相当于我们拿着一个技术来对已经编写好的测试用例进行管理

JUnit的使用

首先添加依赖,去中央存储库中搜索

找到对应的依赖,我这边选择的是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>

JUnit注解

下面对JUnit中的注解进行演示,默认使用public修饰

首先导入注解的依赖,代码如下

        <dependency>
            <!--注解用到的API-->
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.8.2</version>
            <scope>compile</scope>
        </dependency>

@Test:表示当前的这个方法是一个测试用例

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }
}

@Disabled:表示忽略当前这个测试用例,直接跳过测试。方便修改这个测试用例

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @Disabled
        //表示忽略当前这个测试用例,直接跳过测试
    void test2() {
        System.out.println("我是Disabled注解");
    }
}

输出结果,只输出了上面test1方法的内容


BeforeAll和AfterAll注解

下面两者注意使用static修饰!

@BeforeAll:表示所有测试用例在跑之前,先去执行BeforeAll注解里的代码。所以做UI自动化通常情况把创建驱动打开网页放在BeforeAll里

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @Test
    void test2() {
        System.out.println("我是test2注解");
    }

    @BeforeAll
    //所有测试用例执行之前 先执行BeforeAll里的代码
    static void test3() {
        System.out.println("我是BeforeAll注解");
    }
}

输出结果

@AfterAll:表示所有测试用例跑完之后,再去跑AfterAll注解里的代码。关闭浏览器放在BeforeAll

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @Test
    void test2() {
        System.out.println("我是test2注解");
    }

    @BeforeAll
    //所有测试用例执行之前 先执行BeforeAll里的代码
    static void test3() {
        System.out.println("我是BeforeAll注解");
    }

    @AfterAll
    //所有测试用例执行之后 再去执行AfterAll里的代码
    static void test4() {
        System.out.println("我是AfterAll注解");
    }
}

输出结果

BeforeEach和AfterEach注解

@BeforeEach:表示每一个测试用例执行之前BeforeEach里面的代码都要执行一遍

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @Test
    void test2() {
        System.out.println("我是test2注解");
    }

    @BeforeEach
        //表示每一个方法执行前都会执行一遍BeforeEach里的内容
    void test3() {
        System.out.println("我是BeforeEach注解");
    }
}

输出结果

@AfterEach:表示每一个测试用例执行之后AfterEach里面的代码都要执行一遍

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @Test
    void test2() {
        System.out.println("我是test2注解");
    }

    @AfterEach
        //表示每一个方法执行后都会执行一遍BeforeEach里的内容
    void test4() {
        System.out.println("我是AfterEach注解");
    }
}

输出结果


参数化

使用@ParameterizedTest标注方法类型为参数化,然后搭配下面讲解的注解使用

使用@ParameterizedTest注解前也需要导入对应的依赖,代码如下

        <dependency>
            <!--参数化用到的API-->
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.8.2</version>
        </dependency>

注意使用了这个注解就不要再添加@Test注解,加了的话执行的时候会抛异常!

单参数: @ValueSource(类型={参数1,参数2等}})

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @ParameterizedTest
    @ValueSource(strings = "我是ValueSource注解")
    void test2(String s) {
        System.out.println(s);
    }
}

输出结果

使用CSV注解获取参数:注意和单参数一样只能传同种类型的参数!

@CsvFileSource:如果参数非常的多我们可以通过这个注解借助文件注入的方式来添加,路径可以指定为当前项目下resource文件中的csv文件(内容使用逗号分割),也可以指定为本地任意文件夹下的csv文件

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @ParameterizedTest
    @CsvFileSource(resources = "test.csv")
    void test2(String s) {
        System.out.println(s);
    }
}

输出结果


多参数:上面的只能传同种类型的参数,使用多参数注解就可以传递多个不同的参数

@CsvSource:可以传递多个不同类型的参数,参数之间默认的分隔符是逗号,还能手动指定分隔符

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @ParameterizedTest
    @CsvSource(value = {"1,老六", "2,老八"})
    void test2(int n, String name) {
        System.out.println(n + " " + name);
    }
}

输出结果

还能传入空的字符串!

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    @ParameterizedTest
    @CsvSource(value = {"1,老六", "2,老八","3,''"})
    void test2(int n, String name) {
        System.out.println(n + " " + name);
    }
}

输出结果

方法获取参数(动态参数)

使用@MethodSource注解,如果没有指定数据来源,则默认找跟用例同名的静态方法

单参数:可以就传同种类型的参数,将方法返回类型改为对应的类型即可

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    public static Stream<String> method() {
        return Stream.of("坤坤", "坤舞", "坤");
    }

    @ParameterizedTest
    @MethodSource("method")
    void test2(String name) {
        System.out.println(name);
    }
}

输出结果

多参数:可以传不同种类型的参数

public class JUnitTest {
    @Test
        //表示当前的这个方法是一个测试用例
    void test1() {
        System.out.println("我是Test注解");
    }

    public static Stream<Arguments> method() {
        return Stream.of(Arguments.arguments(1, "签哥"), Arguments.arguments(2, "坤哥"));
    }

    @ParameterizedTest
    @MethodSource("method")
    void test2(int n, String name) {
        System.out.println(n + " " + name);
    }
}

输出结果

断言

写自动化测试,测试的结果就两种要么成功要么失败,我们可以使用断言进行判断,省去那种ifelse语句

使用Assertions类调用assertEquals方法:判断预期值和实际值相等

public class JUnitTest {
    @ParameterizedTest
    @ValueSource(ints = 1)
    void test2(int n) {
        Assertions.assertEquals(2, n);
    }
}

输出结果,如果不相等就会报错

使用Assertions类调用assertNotEquals方法:判断预期值和实际值不相等

public class JUnitTest {
    @ParameterizedTest
    @ValueSource(ints = 1)
    void test2(int n) {
        Assertions.assertNotEquals(1, n);
    }
}

输出结果,如果相等就会报错

使用Assertions类调用assertNull方法:判断为空

public class JUnitTest {
    @Test
    void test2() {
        String s = "s";
        Assertions.assertNull(s);
    }
}

输出结果,如果不空就会报错

使用Assertions类调用assertNotNull方法:判断不为空

public class JUnitTest {
    @Test
    void test2() {
        String s = null;
        Assertions.assertNotNull(s);
    }
}

输出结果,如果为空就会报错


用例执行顺序

junit的默认执行顺序是不确定的 采用的是自己执行顺序对应的算法,但用例执行顺序是固定的。什么意思呢?你可以试试第一次运行的结果和后面运行的结果对比一下,下面进行演示

下面这段代码按道理应该先输出test1方法的内容,再输出A方法的内容,再输出test2方法的内容

public class JUnitTest {
    @Test
    void test1() {
        System.out.println("这是junit测试1");
    }

    @Test
    void A() {
        System.out.println("这是junit测试A");
    }

    @Test
    void test2() {
        System.out.println("这是junit测试2");
    }
}

输出结果

再运行一次输出的结果,还是一样

指定方法执行顺序:使用@TestMethodOrder(MethodOrderer.OrderAnnotation.class)注解搭配@Order注解

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JUnitTest {
    @Order(1)
    @Test
    void test1() {
        System.out.println("这是junit测试1");
    }

    @Order(2)
    @Test
    void A() {
        System.out.println("这是junit测试A");
    }

    @Order(3)
    @Test
    void test2() {
        System.out.println("这是junit测试2");
    }
}

输出结果

方法随机执行顺序:使用@TestMethodOrder(MethodOrderer.Random.class)注解

@TestMethodOrder(MethodOrderer.Random.class)
public class JUnitTest {
    @Test
    void test1() {
        System.out.println("这是junit测试1");
    }

    @Test
    void A() {
        System.out.println("这是junit测试A");
    }

    @Test
    void test2() {
        System.out.println("这是junit测试2");
    }
}

输出结果

为什么需要用到junit里的排序方法呢?

如果用例之间存在关联关系的话就需要手动指定用例的执行顺序


测试套件

首先也要导入对应的依赖,代码如下

        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>

使用@Suite注解:表示当前类是个测试套件,搭配下面的注解使用

 使用@SelectClasses可以通过指定类的方式 添加到套件中并执行里面的所有测试用例

@Suite
@SelectClasses({Test01.class, Test02.class})
public class JUnitTest {

}

输出结果

使用@SelectPackages可以通过指定包的方式 添加到套件中并执行测试用例

@Suite
@SelectPackages(value = {"Test1", "Test2"})
public class JUnitTest {

}

输出结果

以上便是本章内容关于JUnit一些概念和使用,在自动化测试中还是尤为重要的一部分,我们下一章再见💕

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

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

相关文章

詹妮弗洛佩兹度过一个单身的季节!知情人:双方无法达成妥协,可能几日内将递交离婚申请!

对于詹妮弗洛佩兹来说&#xff0c;这是一个单身的季节&#xff0c;但这似乎并不是她希望从分居的丈夫本阿弗莱克那里得到的。当她在东海岸的汉普顿度过夏天时&#xff0c;这位 51 岁的演员正忙着在西海岸购买价值 2050 万美元的房产。洛佩兹显然认为&#xff0c;尽管他们已经分…

常见的CMS漏洞解析!

PhPMyadmin&#xff1a; 姿势⼀&#xff1a;通过日志文件拿Shell 利用mysql日志文件写shell&#xff0c;这个日志可以在mysql里改变它的存放位置&#xff0c;登录phpmyadmin可以修改 这个存放位置&#xff0c;并且可以修改它的后缀名。所以可以修改成php的后缀名就能获取⼀个…

通讯协议原始指令日志Python脚本分析

一.通讯协议格式&#xff1a; 二.通讯协议原始日志 [2024-04-18 14:58:59.659 D] 99 99 0E 00 01 0A 04 00 01 00 00 00 1E FN FN [2024-04-18 14:58:59.959 D] 99 99 0E 00 01 0C 03 03 01 00 BC FN FN 三.通讯协议原始指令日志Python脚本分析&#xff08;仅解析指令的PC版和…

反制攻击者-蚁剑低版本

目录 安装 攻击者获取防守方的权限 防守方反制攻击者 防守方获取攻击者的shell权限 安装 安装蚁剑2.0.7版本 链接&#xff1a;https://pan.baidu.com/s/1t40UxkZ2XuSWG6VCdGzvDw?pwd8888 提取码&#xff1a;8888 下载好后先打开Loader文件夹下的.exe文件&#xff0c;打…

常见cms漏洞之dedecms

DedeCMS是织梦团队开发PHP 网站管理系统&#xff0c;它以简单、易用、高效为特色&#xff0c;组建出各种各样各具特色的网站&#xff0c;如地方门户、行业门户、政府及企事业站点等。 下载地址请网上自行寻找 搭建方式选择php study 首先搭建环境 #前台http://localhost/dedecm…

医院患者押金原路退回系统源码,一键操作秒到账,无需设备收银设备 押金+身份证+电子押金单 解决方案

科技之力赋能医院押金原路退回&#xff0c;安全可靠账目清晰 一、医院押金管理必要性 以下是一些可用于销售软件、突出医院管理方便的优点总结&#xff1a; 1. 高效便捷的押金原路退回流程&#xff1a;利用科技之力&#xff0c;简化操作&#xff0c;节省时间和人力成本&#…

使用WPF调用Python进行图像灰度处理

1. 前言 在本文中&#xff0c;我们将通过WPF应用程序调用Python脚本进行图像灰度处理。我们将使用Python的OpenCV库来处理图像&#xff0c;并将其转换为灰度图像&#xff0c;然后通过WPF界面来启动Python进程并展示结果。 2. 准备工作 在开始之前&#xff0c;请确保系统已经…

PDF隐写思路

文章目录 使用工具技术细节小结 使用工具 工具&#xff1a;WPS、010Editor、WbStego 技术细节 步骤&#xff1a; 使用 WPS 查看文件&#xff0c;看是否能打开。 若不能打开则使用 010Editor 查看是否少了头文件等。 正常的 PDF 缺少头文件的 PDF 如果缺少头文件则使用 010…

【初阶数据结构题目】9. 链表分割

链表分割 点击链接做题 例如&#xff1a; 排序前&#xff1a;1->6->2->3->5 X&#xff1a;X 3 排序后&#xff1a;1->2->6->3->5 思路&#xff1a; 排序前&#xff1a;1->6->2->3->5 小链表&#xff1a;malloc->1->2 大链表&#…

一文看懂STL标准模板中的set用法(C++)详细源码与例题

在 C 中&#xff0c;集合通常指的是标准模板库&#xff08;STL&#xff09;中的 std::set 或 std::unordered_set。这两个都是用来存储不重复元素的容器&#xff0c;但在实现和使用方式上有一些区别。 集合&#xff08;set&#xff09;是一个内部自动有序且不含重复元素的容器…

C++的STL简介(三)

目录 1.vector的模拟实现 1.1begin&#xff08;&#xff09; 1.2end&#xff08;&#xff09; 1.3打印信息 1.4 reserve&#xff08;&#xff09; 1.5 size&#xff08;&#xff09; 1.6 capacity&#xff08;&#xff09; 1.7 push_back() 1.8[ ] 1.9 pop_back() 1.10 insert&…

扑克游戏(函数规范化,拆分事件)

前言&#xff1a; 题目链接 进入链接后&#xff0c;点击实践项目&#xff0c;以下两道题分别为6.8.15和6.8.16, 这两道题算不上难&#xff0c;特别是第二道在之前某个比赛中遇到过一次&#xff0c;当时没做出来&#xff0c;想着去找的&#xff0c;没找着&#xff0c;现在又看…

Midjourney小技巧-提升出图质量的常用公式

一个公式让你的Midjourney生成更具韵味的人像身影图 step1-测试&#xff1a;输入提示词 - 一个面容精致的亚洲女性 - An Asian woman with a delicate face 生成的图片还是挺唯美的&#xff0c;就是过于单调&#xff0c;稀疏平常 step2-使用公式&#xff1a; 谁谁&#xff0…

Windows调大虚拟内存来代替升级物理运行内存(RAM)真的有用吗?

前言 前段时间有个粉丝突发奇想说&#xff1a;电脑运行内存不足&#xff0c;调大虚拟内存来代替升级物理运行内存&#xff08;内存条&#xff09;不就可以了&#xff1f;剩下的大几百块钱吃香的喝辣的不好吗&#xff1f; 嗯。。。直到2024年的今天&#xff0c;估计还有很多小…

微信VX多开 免扫码 登录 互斥体 可视化 Exui v1.1 易语言源码附成品软件

UI设计&#xff1a; 1. EXUI界面库20240204 调用的模块&#xff1a; 1. wow64_hook_3.02.ec&#xff08;压缩包内含&#xff09; 2. 精易模块[v11.1.0].ec&#xff08;自行下载&#xff09; 更新日志&#xff1a; v1.1 2024年7月25日13:28:43 { 1. 有人反馈 设置了V…

“论数据湖技术及其应用”写作框架,软考高级论文系统架构设计师论文

论文真题 近年来&#xff0c;随着移动互联网、物联网、工业互联网等技术的不断发展&#xff0c;企业级应用面临的数据规模不断增大&#xff0c;数据类型异常复杂。针对这一问题&#xff0c;业界提出“数据湖&#xff08;Data Lake)”这一新型的企业数据管理技术。数据湖是一个…

YOLOv1-v5总结

文章目录 1、yolov11.2、预测阶段1.3、后处理阶段1.4、模型训练阶段1.5、损失函数1.6、yolov1网络1.7、为什么使用1*1的卷积&#xff1f; 2、yolov22.1、添加BN层2.2、高分辨力分类器&#xff08;仅仅使用分类而不是目标检测&#xff09;2.3、anchor机制2.4、关于anchor boxes&…

Python 爬虫项目实战(二):爬取微博热搜榜

前言 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;也称为网页蜘蛛&#xff08;Web Spider&#xff09;或网页机器人&#xff08;Web Bot&#xff09;&#xff0c;是一种按照既定规则自动浏览网络并提取信息的程序。爬虫的主要用途包括数据采集、网络索引、内容抓…

iPhone苹果密码解锁工具专业版_不限制电脑

iPhone苹果密码解锁工具专业版_不限制电脑 Aiseesoft iPhone Unlocker&#xff1a;轻松解锁iPhone。功能强大&#xff1a;一键移除4位、6位密码、Touch ID和Face ID。 隐私保护&#xff1a;创建密码&#xff0c;安全无忧。数据提醒&#xff1a;解锁时&#xff0c;注意数据和设…

自制安卓车机软件(含APP)

本软件使用APPinventor2编程软件&#xff0c;耗时5天和3天调试&#xff0c;具有高德导航&#xff0c;视频播放&#xff0c;网易云音乐&#xff0c;酷狗&#xff0c;抖音&#xff0c;&#xff08;需下载车机版软件&#xff09;和自定义添加软件&#xff0c;网页有哔哩哔哩&#…