0


JUnit5-单元测试操作详解

1、JUnit5-单元测试框架

JUnit 5是JUnit测试框架的下一个主要版本,用于编写和运行单元测试。

与以前版本的 JUnit 不同,JUnit 5 由来自三个不同子项目的多个不同模块组成。

JUnit 5 = JUnit 平台+ JUnit Jupiter + JUnit Vintage

JUnit平台是在 JVM 上启动测试框架的基础。它还定义了

  1. TestEngine

用于开发在平台上运行的测试框架的API。此外,该平台还提供了一个 控制台启动器,用于从命令行启动平台,还提供JUnit 平台套件引擎,用于使用平台上的一个或多个测试引擎来运行自定义测试套件。对 JUnit 平台的一流支持也存在于流行的 IDE(请参阅IntelliJ IDEA、 Eclipse、NetBeans和 Visual Studio Code)和构建工具(请参阅Gradle、 Maven和Ant)中。

JUnit Jupiter是编程模型和 扩展模型的组合,用于在 JUnit 5 中编写测试和扩展。Jupiter 子项目提供了

  1. TestEngine

在平台上运行基于 Jupiter 的测试的功能。

JUnit Vintage提供了一个

  1. TestEngine

用于在平台上运行基于 JUnit 3 和 JUnit 4 的测试。它要求类路径或模块路径上存在 JUnit 4.12 或更高版本。

2、支持的 Java 版本

JUnit 5 在运行时需要 Java 8(或更高版本)。

3、寻求帮助

在Stack Overflow上询问 JUnit 5 相关问题或在Gitter上与社区聊天。

4、下载JUnit5依赖

(1)、进入springboot官网 复制依赖:Core Features

(2)、粘贴到pom.xml文件中,点击maven刷新按钮,刷新成功后就新增成功了

5、JUnit Jupiter 支持以下注释来配置测试和扩展框架。

除非另有说明,所有核心注解均位于模块

  1. org.junit.jupiter.api

中的包中

  1. junit-jupiter-api

注解描述

  1. @Test

表示方法是测试方法。与 JUnit 4 的

  1. @Test

注释不同,此注释不声明任何属性,因为 JUnit Jupiter 中的测试扩展基于其自己的专用注释进行操作。此类方法将被继承,除非它们被重写

  1. @ParameterizedTest

表示方法是参数化测试。此类方法将被继承,除非它们被重写

  1. @RepeatedTest

表示方法是重复测试的测试模板。此类方法将被继承,除非它们被重写

  1. @TestFactory

表示方法是动态测试的测试工厂。此类方法将被继承,除非它们被重写

  1. @TestTemplate

表示方法是测试用例的模板,设计为根据注册提供者返回的调用上下文的数量多次调用。此类方法将被继承,除非它们被重写

  1. @TestClassOrder

用于配置带注释的测试类中测试类的测试类执行顺序

  1. @Nested

。此类注释是继承的

  1. @TestMethodOrder

用于配置被注解的测试类的测试方法执行顺序;类似于 JUnit 4 的

  1. @FixMethodOrder

. 此类注释是继承的

  1. @TestInstance

用于配置带注释的测试类的测试实例生命周期。此类注释是继承的

  1. @DisplayName

声明测试类或测试方法的自定义显示名称。此类注释不会被继承

  1. @DisplayNameGeneration

为测试类声明一个自定义显示名称生成器。此类注释是继承的

  1. @BeforeEach

表示被注解的方法应该在当前类中的每个, , , 或方法之前执行; 类似于 JUnit 4 的. 此类方法是继承的,除非它们被覆盖取代(即仅基于签名进行替换,而不考虑 Java 的可见性规则)。

  1. @Test
  1. @RepeatedTest
  1. @ParameterizedTest
  1. @TestFactory
  1. @Before
  1. @AfterEach

表示被注解的方法应该在当前类中的每个、、、 或方法之后执行; 类似于 JUnit 4 的. 此类方法是继承的,除非它们被覆盖取代(即仅基于签名进行替换,而不考虑 Java 的可见性规则)。

  1. @Test
  1. @RepeatedTest
  1. @ParameterizedTest
  1. @TestFactory
  1. @After
  1. @BeforeAll

表示被注解的方法应该在当前类中的所有、、、方法之前执行; 类似于 JUnit 4 的. 此类方法是继承的,除非它们被隐藏重写取代(即,仅根据签名进行替换,而不考虑 Java 的可见性规则),而且必须如此,除非使用“每类”测试实例生命周期。

  1. @Test
  1. @RepeatedTest
  1. @ParameterizedTest
  1. @TestFactory
  1. @BeforeClass
  1. static
  1. @AfterAll

表示被注解的方法应该在当前类中的所有、、、方法之后执行; 类似于 JUnit 4 的. 此类方法是继承的,除非它们被隐藏重写取代(即,仅根据签名进行替换,而不考虑 Java 的可见性规则),而且必须如此,除非使用“每类”测试实例生命周期。

  1. @Test
  1. @RepeatedTest
  1. @ParameterizedTest
  1. @TestFactory
  1. @AfterClass
  1. static
  1. @Nested

表示被注解的类是一个非静态嵌套测试类。在 Java 8 到 Java 15 上,

  1. @BeforeAll

除非使用“每类”测试实例生命周期

  1. @AfterAll

,否则不能直接在测试类中使用方法。从 Java 16 开始,可以使用任一测试实例生命周期模式在测试类中声明方法。此类注释不会被继承

  1. @Nested
  1. @BeforeAll
  1. @AfterAll
  1. static
  1. @Nested
  1. @Tag

用于在类或方法级别声明用于过滤测试的标签;类似于 TestNG 中的测试组或 JUnit 4 中的类别。此类注释在类级别继承,但不在方法级别继承。

  1. @Disabled

用于禁用测试类或测试方法;类似于 JUnit 4 的

  1. @Ignore

. 此类注释不会被继承

  1. @Timeout

用于在测试、测试工厂、测试模板或生命周期方法的执行超过给定持续时间时失败。此类注释是继承的

  1. @ExtendWith

用于以声明方式注册扩展。此类注释是继承的

  1. @RegisterExtension

用于通过字段以编程方式注册扩展。这些字段是继承的,除非它们被遮蔽

  1. @TempDir

用于在生命周期方法或测试方法中通过字段注入或参数注入提供临时目录;位于

  1. org.junit.jupiter.api.io

包装内。

6、首个示例用法如下

判断括号里 2个值是否相等

  1. package com.example.demo;
  2. import static org.junit.jupiter.api.Assertions.assertEquals;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. @SpringBootTest
  6. class Demo5ApplicationTests {
  7. private Integer number=1+1;
  8. @Test
  9. void addition() {
  10. assertEquals(2,number);
  11. }
  12. }

断言失败展示

7、显示名称

  1. package com.example.demo;
  2. import org.junit.jupiter.api.DisplayName;
  3. import org.junit.jupiter.api.Test;
  4. @DisplayName("A special test case")
  5. @SpringBootTest
  6. class NameTests {
  7. @Test
  8. @DisplayName("Custom test name containing spaces")
  9. void testWithDisplayNameContainingSpaces() {
  10. System.out.println("1");
  11. }
  12. @Test
  13. @DisplayName("╯°□°)╯")
  14. void testWithDisplayNameContainingSpecialCharacters() {
  15. System.out.println("2");
  16. }
  17. @Test
  18. @DisplayName("😱")
  19. void testWithDisplayNameContainingEmoji() {
  20. System.out.println("3");
  21. }
  22. }

8、断言示例展示

  1. package com.example.demo;
  2. import org.junit.jupiter.api.Test;
  3. import org.springframework.boot.test.context.SpringBootTest;
  4. import static org.junit.jupiter.api.Assertions.*;
  5. @SpringBootTest
  6. class KotlinAssertionsDemo {
  7. @Test
  8. void asserts(){
  9. // 判断两个对象或两个原始类型是否相等
  10. assertEquals(3, 1 + 2, "2个结果相等");
  11. // 判断两个对象或两个原始类型是否不相等
  12. assertNotEquals(3, 1 + 1);
  13. // 判断两个对象引用是否指向不同的对象
  14. assertNotSame(new Object(), new Object());
  15. Object obj = new Object();
  16. // 判断两个对象引用是否指向相同的对象
  17. assertSame(obj, obj);
  18. //判断给定的布尔值是否为 false
  19. assertFalse(1 > 2);
  20. //判断给定的布尔值是否为 true
  21. assertTrue(1 < 2);
  22. //判断给定的布尔值是否为空
  23. assertNull(null);
  24. // 判断给定的布尔值是否不为空
  25. assertNotNull("hello");
  26. }
  27. }

9、数组断言

通过 assertArrayEquals 方法来判断两个对象或原始类型的数组是否相等

  1. @Test
  2. @DisplayName("数组测试")
  3. public void array() {
  4. assertArrayEquals(new String[]{"a","b"}, new String[]{"a","b"});
  5. }

10、异常断言

在JUnit4时期,想要测试方法的异常情况时,需要用@Rule注解的ExpectedException变量还是比较麻烦的。而JUnit5提供了一种新的断言 方式Assertions.assertThrows() ,配合函数式编程就可以进行使用。

  1. @Test
  2. @DisplayName("异常测试")
  3. public void exceptionTest() {
  4. ArithmeticException exception = Assertions.assertThrows(
  5. //扔出断言异常
  6. ArithmeticException.class, () -> System.out.println(1 % 0));
  7. }

11、超时断言

Junit5还提供了Assertions.assertTimeout() 为测试方法设置了超时时间为1ms

  1. @DisplayName("超时测试")
  2. @Test
  3. public void timeoutTest() {
  4. //如果测试方法时间超过1s将会异常
  5. Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(1001));
  6. }
  7. }

12、@BeforeEach用法

在执行每个用例之前,都会执行BeforeEach下的函数

  1. @SpringBootTest
  2. class WhenNew {
  3. @BeforeEach
  4. void init() {
  5. System.out.println("testcase");
  6. }
  7. @Test
  8. void succeedingTest() {
  9. System.out.println("test01");
  10. }
  11. @Test
  12. void succeedingTest1() {
  13. System.out.println("test02");
  14. }
  15. @Test
  16. void succeedingTest2() {
  17. System.out.println("test03");
  18. }
  19. }

13、参数化测试

参数化测试是JUnit5很重要的一个新特性,它使得用不同的参数多次运行测试成为了可能,也为我们的单元测试带来许多便利。 利用@ValueSource等注解,指定入参,我们将可以使用不同的参数进行多次单元测试,而不需要每新增一个参数就新增一个单元测试, 省去了很多冗余代码。

如下:测试用例会分别执行集合类的四个参数

  1. @ParameterizedTest
  2. @ValueSource(strings = {"one", "two", "three","five"})
  3. @DisplayName("参数化测试1")
  4. public void parameterizedTest1(String string)
  5. {
  6. System.out.println(string);
  7. Assertions.assertTrue(StringUtils.isNotBlank(string));
  8. }


本文转载自: https://blog.csdn.net/2401_83441752/article/details/136612252
版权归原作者 逸云-测试 所有, 如有侵权,请联系我们删除。

“JUnit5-单元测试操作详解”的评论:

还没有评论