Junit5基础教程

Junit5的构成:

  • Junit Platform+Junit Jupiter+Junit Vintage
  • Junit Platform:是Junit向测试平台演进,提供平台功能的模块,通过这个其他的自动化引擎可以接入Junit,实现对接和执行
  • Junit Jupiter:核心,承载Juint4原有功能+丰富的新特性
  • Junit Vintage:主要功能是对Juint旧版本进行兼容

一,导入依赖

 <properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><junit-platform.version>1.8.1</junit-platform.version><junit-jupiter.version>5.8.1</junit-jupiter.version></properties><build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.0.0-M5</version><dependencies><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.8.1</version></dependency></dependencies><configuration><includes><include>**/*Test.java</include></includes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></pluginManagement></build><!--核心依赖--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.8.1</version></dependency><!--套件测试使用--><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-runner</artifactId><version>1.8.1</version></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-runner</artifactId><version>1.8.1</version></dependency>

二,基本功能

一、常用断言

在这里插入图片描述

二、执行顺序和常用注解

1、通过BeforeAll类的注解来保证顺序
// 执行顺序:beforeAll-beforeEach-afterEach-afterAll
@DisplayName("常用注解测试")
public class TestCase {/*** @BeforeAll和@AfterAll 必须静态修饰,在所有方法执行前后只执行一次* @Test 一个方法* @AfterEach和@BeforeEach 每次方法执行前都会执行一次* @DisplayName() 类似注解的功能* @RepeatedTest(5) 重复5次* @Disabled 不执行该方法* @Tags 打标签*/@BeforeAllpublic static void beforeAll() {System.out.println("BeforeAll再每个类中只执行一次,且是在开头执行");}@BeforeEachpublic void beforeEach() {System.out.println("BeforeEach在每个方法执行前都会执行一次");}// junit5不需要访问修饰符//  @Disabled表示不执行@Test@Disabled@DisplayName("方法1")void fun1() {System.out.println("---fun1---");}@Test@DisplayName("方法2")@RepeatedTest(5)void fun2() {System.out.println("---fun2---");}@Test@Tag("tag1")void tagTest(){System.out.println("tag1");}@AfterEachpublic void afterEach() {System.out.println("AfterEach在每个方法执行前都会执行一次");}@AfterAllpublic static void afterAll() {System.out.println("afterAll再每个类中只执行一次,且是在结尾执行");}
}
2、通过order注解来保证执行顺序
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;@TestMethodOrder(OrderAnnotation.class)
class OrderedTestsDemo {@Test@Order(1)void nullValues() {// perform assertions against null values}@Test@Order(2)void emptyValues() {// perform assertions against empty values}@Test@Order(3)void validValues() {// perform assertions against valid values}
}
  • allure注解
    在这里插入图片描述

三、依赖测试

/*** @Nested:* 功能类似于suite测试套件* 从下往上执行*/public class NestedTest {private static HashMap<String, Object> dataMap = new HashMap<String, Object>();@Testvoid login() {dataMap.put("login", "登录成功");}@Nestedclass Shopping{@Testvoid shopping(){if (null!=dataMap.get("buy")){System.out.println("购买成功啦!");}else {System.out.println("购买失败");}}}@Nestedclass Buy {@Testvoid buyTest() {if (dataMap.get("login").equals("登录成功")) {System.out.println("登录成功");dataMap.put("buy", "登录成功,快去购物吧!");} else {System.out.println("登录失败");}}}
}

四、参数化测试

写过一篇,点这里!!

五、测试套件

SelectPackages、IncludePackages、SelectClasses、IncludeTags等注解的使用
/*** SelectPackages 选择需要执行的包*/
@RunWith(JUnitPlatform.class)
@SelectPackages({"com.testCase2"})
public class SelectPackagesTest {}
/*** @IncludePackages需要和@SelectPackages搭配使用* @IncludePackages是在@SelectPackages的基础上再做一层筛选* ps:一定要注意,包下的类名一定要Test开头或者结尾,否则就不执行了!!!*/
@RunWith(JUnitPlatform.class)
@SelectPackages({"com.testCase2"})
// 只执行com.testCase2.demo1
@IncludePackages({"com.testCase2.demo1"})
public class IncludePackagesTest {
}
/*** @SelectClasses和@IncludeTags组合使用,在方法里选出对应的标签* 还有@ExcludeTag*/
@RunWith(JUnitPlatform.class)
@SelectClasses({TestCase.class})
//@IncludeTags("tag1")
@ExcludeTags("tag1")
public class SelectClassesTest {
}

六、软断言

  • assertAll断言方法,会在执行完所有断言后统⼀输出结果,⼀次性暴露所有问题,提高了测试脚本的健壮性。
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;import java.util.ArrayList;
import java.util.List;import static org.junit.jupiter.api.Assertions.assertAll;public class AssertAllDemo {// 普通方法,第一个执行失败以后后面都不执行@Testvoid assertTest1() {Assertions.assertTrue(2 == 1);}void assertTest2() {Assertions.assertTrue(3 == 1);}void assertTest3() {Assertions.assertTrue(1 == 1);}// 用了assertAll之后,所有方法都执行@Testvoid assertAllTest() {assertAll("多次结果校验",() -> {Assertions.assertTrue(2 == 1);},() -> {Assertions.assertTrue(3 == 1);});}@Testvoid assertAllTtest02() {List<Executable> assertList = new ArrayList<>();for (int i = 0; i < 10; i++) {int result = i;System.out.println(result);assertList.add(() -> {Assertions.assertEquals(10, result);});}assertAll("多次结果校验", assertList.stream());}}

七、并发测试

  • 测试环境基本上都是单线程操作,而线上存在分布式的并发场景,所以并不能暴露所有问题,这里就需要用到并发
  • junit测试是在⼀个线程中串行执行的,从5.3开始⽀持并行测试。⾸先需要在配置⽂件junit-platform.properties 中配置。
#是否允许并行执行true/false
junit.jupiter.execution.parallel.enabled = true
#是否支持方法级别多线程same_thread/concurrent
junit.jupiter.execution.parallel.mode.default = concurrent
#是否支持类级别多线程same_thread/concurrent
junit.jupiter.execution.parallel.mode.classes.default = concurrent
# the maximum pool size can be configured using a ParallelExecutionConfigurationStrategy
junit.jupiter.execution.parallel.config.strategy=fixed
junit.jupiter.execution.parallel.config.fixed.parallelism=4

import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;/*** 并发测试*/
public class ParallelTest {static   int result = 0;// 加synchronized可以保证其原子性,但是如果是分布式系统是不适合的,需要用如redis分布式锁public static  int cal(int x) throws InterruptedException {int i = result;Thread.sleep(1000);result = i + x;return result;}public static int add(int x,int y) throws InterruptedException {Thread.sleep(1000);result = y + x;return result;}@RepeatedTest(10)public void testCal() throws InterruptedException {long id = Thread.currentThread().getId();System.out.println("线程" + id + "为你服务:" + cal(1));}@RepeatedTest(10)public void testAdd() throws InterruptedException {long id = Thread.currentThread().getId();System.out.println("加法计算:线程" + id + "为你服务:" + add(1,2));}
}

八、动态测试解决硬编码问题

  • 传统自动化测试思路中,我们的测试逻辑是在以硬编码的形式组织到代码里的,当遇到用例迁移或结果整合时,会产生大量的逻辑重写
  • JUnit5提供了动态测试方案,让测试人员可以在脚本Runtime时动态的批量生成用例
  • 现在我们有一个需求,要把yaml文件内容转为测试用例,解决思路如下:
    在这里插入图片描述
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;/*** 动态测试demo* 需求:把result.yaml脚本变成测试用例* 首先把它通过反序列化变成对象* 然后把它添加到dynamicTestList*/
public class ShellTestResult {@TestFactoryCollection<DynamicTest> shellTestResult() throws IOException {// 新建一个列表来存储数据(不是结果)List<DynamicTest> dynamicTestList = new ArrayList<>();ObjectMapper mapper = new ObjectMapper(new YAMLFactory());// 反序列化方式把yaml文件转换为对象列表ResultList resultList = mapper.readValue(new File("D:\\interface_auto\\src\\main\\resources\\result.yaml"), ResultList.class);System.out.println("done");// 动态遍历生成测试方法for (Result result : resultList.getResultList()) {// 把数据收集起来dynamicTestList.add(// 动态生成测试方法DynamicTest.dynamicTest(result.getCaseName(), () -> {Assertions.assertTrue(result.isResult());}));}return dynamicTestList;}
}
import lombok.Data;@Data
public class Result {private String caseName;private boolean result;public boolean isResult() {return result;}public void setResult(boolean result) {this.result = result;}
}
@Data
public class ResultList {private List<Result> resultList;
}

九、Junit5启动类(适用于持续集成)

import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;import static org.junit.platform.engine.discovery.ClassNameFilter.includeClassNamePatterns;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;/*** junit5启动类(适用于持续集成这种点不了执行的)*/
public class LauncherDemo {public static void main(String[] args) {LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request().selectors(// 2个过滤条件是or不是and:selectPackage("com.learn.junit5"),selectClass(TestExecutionOrder.class)).filters(
//                includeClassNamePatterns("Test.*")).build();Launcher launcher = LauncherFactory.create();TestExecutionListener listener = new SummaryGeneratingListener();launcher.registerTestExecutionListeners(listener);launcher.execute(request);}
}

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

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

相关文章

C语言printf函数详解..

1.printf函数解析 前面我们有讲过printf函数的格式为&#xff1a; printf(“占位1 占位2 占位3……”, 替代1, 替代2, 替代3……); 今天我们进一步深入的解析一下这个函数 2.printf函数的特点 1.printf函数是一个变参函数(即参数的数量和类型都不确定) 2.printf函数的第一个…

【MySQL】——数值函数的学习

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Z1fAnfrxGD7I5gqp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

bugku 1

Flask_FileUpload 文件上传 先随便传个一句话木马 看看回显 果然不符合规定 而且发现改成图片什么的都不行 查看页面源代码&#xff0c;发现提示 那应该就要用python命令才行 试试ls 类型要改成图片 cat /flag 好像需要密码 bp爆破 根据提示&#xff0c;我们先抓包 爆破 …

ChatGPT高效提问—prompt常见用法(续篇九)

ChatGPT高效提问—prompt常见用法(续篇九) ​ 如何准确地向大型语言模型提出问题,使其更好地理解我们的意图,从而得到期望的答案呢?编写有效的prompt的技巧,精心设计的prompt,获得期望的的答案。 1.1 增加条件 ​ 在各种prompt技巧中,增加条件是最常用的。在prompt中…

MOMENTUM: 1

攻击机 192.168.223.128 目标机 192.168.223.146 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.146 开启了22 80端口 看一下web界面 随便打开看看 发现这里有个参数id&#xff0c;sql尝试无果&#xff0c;发现写入什么&#xff0c;网页显示…

【数据结构】11 堆栈(顺序存储和链式存储)

定义 可认为是具有一定约束的线性表&#xff0c;插入和删除操作都在一个称为栈顶的端点位置。也叫后入先出表&#xff08;LIFO&#xff09; 类型名称&#xff1a;堆栈&#xff08;STACK&#xff09; 数据对象集&#xff1a; 一个有0个或者多个元素的有穷线性表。 操作集&#…

Obsidian Publish的开源替代品Perlite

前几天就有网友跟我说&#xff0c;freenom 的免费域名不可用了&#xff0c;10 号的时候老苏进后台看了一下&#xff0c;还有一半的域名显示为 ACTIVE&#xff0c;似乎是以 2024年6月 为限。但到 11 号&#xff0c;老苏发现博客 (https://laosu.cf) 已经访问不了了&#xff0c;这…

【Linux】信号保存与信号捕捉处理

信号保存与信号捕捉 一、信号保存1. 信号的发送2. 理解信号保存&#xff08;1&#xff09;信号保存原因&#xff08;2&#xff09;信号保存概念 3. 信号保存系统接口&#xff08;1&#xff09;sigset_t&#xff08;2&#xff09;sigprocmask()&#xff08;3&#xff09;sigpend…

GraphicsMagick 的 OpenCL 开发记录(三十七)

文章目录 如何写ScaleImage()的硬件加速函数&#xff08;十一&#xff09; <2022-05-06 周五> 如何写ScaleImage()的硬件加速函数&#xff08;十一&#xff09; “如何写ScaleImage()的硬件加速函数&#xff08;十&#xff09;”这里的代码写得比较随意&#xff0c;其中…

vscode远程连接失败

目录 解决方案尝试1解决方案尝试2 解决方案尝试1 最近通过vscode一直使用腾讯云的服务器作为远程开发环境&#xff0c;以前一直很好用。 直到最近重装了系统之后&#xff0c;发现vscode没法对云服务器进行连接了&#xff0c;即使在远程主机添加了本地的公钥也不行。直接报错:…

python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui

文章目录 用GUI自动控制键盘和鼠标pyautogui 模块鼠标屏幕位置——移动地图——pyautogui.size鼠标位置——自身定位——pyautogui.position()移动鼠标——pyautogui.moveTo拖动鼠标滚动鼠标 键盘按下键盘释放键盘 开始与结束通过注销关闭所有程序 用GUI自动控制键盘和鼠标 在…

springboot178智能学习平台系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

正则可视化工具:学习和编写正则表达式的利器

引言 正则表达式是一种强大的文本匹配和处理工具&#xff0c;但对于初学者和非专业开发者来说&#xff0c;编写和理解正则表达式可能是一项具有挑战性的任务。为了帮助人们更好地学习和编写正则表达式&#xff0c;正则可视化工具应运而生。本文将探讨正则可视化工具的优点&…

Infuse通过Alist添加115网盘资源

说明 通过Alist代理管理115网盘&#xff0c;Infuse再添加Alist代理的115网盘的WebDAV 准备一台Linux服务器安装Alist 我这里用的华为云CentOS7&#xff0c;使用Docker容器 安装Alist docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 -e PUID0 …

Javaweb之SpringBootWeb案例之事务进阶的详细解析

1.3 事务进阶 前面我们通过spring事务管理注解Transactional已经控制了业务层方法的事务。接下来我们要来详细的介绍一下Transactional事务管理注解的使用细节。我们这里主要介绍Transactional注解当中的两个常见的属性&#xff1a; 异常回滚的属性&#xff1a;rollbackFor 事…

Days28 ElfBoard 板]修改开机动画

1.可能需要安装的库 elfubuntu:~/work/psplash$ sudo apt-get install build-essential libncurses5-dev elfubuntu:~/work/psplash$ sudo apt-get install libtool elfubuntu:~/work/psplash$ sudo apt-get install gettext elfubuntu:~/work/psplash$ sudo apt-get install l…

Tied Block Convolution: 具有共享较薄滤波器的更简洁、更出色的CNN

摘要 https://arxiv.org/pdf/2009.12021.pdf 卷积是卷积神经网络&#xff08;CNN&#xff09;的主要构建块。我们观察到&#xff0c;随着通道数的增加&#xff0c;优化后的CNN通常具有高度相关的滤波器&#xff0c;这降低了特征表示的表达力。我们提出了Tied Block Convolutio…

服务器解析漏洞及任意文件下载

1.服务器文件解析漏洞 文件解析漏洞,是指Web容器&#xff08;Apache、nginx、iis等&#xff09;在解析文件时出现了漏洞,以其他格式执行出脚本格式的效果。从而,黑客可以利用该漏洞实现非法文件的解析。 &#xff08;1) Apache linux系统中的apache的php配置文件在/etc/apac…

电气器件系列四十九:室内加热器(取暖器)

这个的注意事项有好大一堆&#xff0c;有几个地方挺有意思的&#xff0c;可以了解一下。 第2条&#xff0c;查了一下&#xff0c;小太阳是真的可以把旁边的东西烤到很高的温度并起火 4、可能造成开关的损坏和发热管的损坏&#xff0c;插入异物可能吧加热管搞坏 5、小太阳是发…

【数据结构】哈希表的开散列和闭散列模拟实现

哈希思想 在顺序和树状结构中&#xff0c;元素的存储与其存储位置之间是没有对应关系&#xff0c;因此在查找一个元素时&#xff0c;必须要经过多次的比较。 顺序查找的时间复杂度为0(N)&#xff0c;树的查找时间复杂度为log(N)。 我们最希望的搜索方式&#xff1a;通过元素…