Junit5简介和常用测试注解
SpringBoot从2.2.0版本开始就引入JUnit5作为单元测试的默认库。但是,从2.4以上的版本开始,移除了默认对Vintage的依赖(就是兼容JUnit4和JUnit3的模块)。如果需要兼容我们的JUnit4,那么我们就需要手动加入Junit4的依赖。
下面,我们就来介绍一下Junit5,并说一下他常用的测试注解。
1、Junit5简介
Junit5与之前版本有很大的不同,主要由三个不同子项目的几个不同模块组成。来个公式:
Junit5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
- JUnit Platform:Junit Platform是在JVM上启动测试框架的基础,不仅支持JUnit自制的测试引擎,还可以接入其他测试引擎。
- JUnit Jupiter:JUnit Jupiter提供了JUnit5新的编程模型,是JUnit5新特性的核心。内部包含了一个测试引擎,用于在JUnit Platform上运行。
- JUnit Vintage:由于JUnit已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4和JUnit3的测试引擎。
要想引入JUnit5的相关依赖,我们只需要导入他的starter(场景即可)。
<!--测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
如果我们使用的SpringBoot2.4及其之后的版本,要兼容Junit4和Junit3的话,我们就得再加一段依赖如下:
<!--SpringBoot2.4开始,兼容Junit4需要手动导入Vintage-->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
SpringBoot整合Junit5后:
1、编写测试方法:只需要使用@Test标注(注意这个@Test的包的路径是org.junit.jupiter.api.Test)
2、Junit类具有Spring和Java的功能,可以使用@Autowired和@Resource自动注入。
3、对于部分需要回滚的测试方法,我们可以通过添加@Transactional注解让该测试方法执行完毕后自动回滚。
2、Junit5常用测试注解
注解 | 描述 |
---|---|
@Test | 表示方法是测试方法,和Junit4不同,他不能声明任何属性 |
@ParameterizedTest | 表示方法是参数化测试 |
@RepeatedTest | 表示方法可重复执行 |
@DisplayName | 为测试类或方法设置展示名称 |
@BeforeEach | 表示在每个单元测试之前执行(有几个测试就执行几次) |
@AfterEach | 表示在每个单元测试之后执行(有几个测试就执行几次) |
@BeforeAll | 表示在所有单元测试之前执行(无论有几个测试都只执行一次) |
@AfterAll | 表示在所有单元测试之后执行(无论有几个测试都只执行一次) |
@Tag | 表示单元测试类别,类似于Junit4的@Categories |
@Disabled | 表示测试类或测试方法不执行,类似于Junit4中的@Ignore |
@Timeout | 表示测试方法如果超过了指定时间将会返回错误 |
@ExtendWith | 为测试类或测试方法提供扩展类引用 |
1、DispalyName注解:
案例:给测试类和方法取名。
package com.example.boot;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("只是个有名字的测试类")
public class MyTest {
@DisplayName("这是个有名字的方法")
@Test
public void testDisplayName(){
System.out.println("测试DisplayName");
}
}
结果:
2、BeforeEach和AfterEach注解
案例:给每个测试方法前后输出一句话。
package com.example.boot;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("只是个有名字的测试类")
public class MyTest {
@DisplayName("这是个有名字的方法")
@Test
public void testDisplayName(){
System.out.println("测试DisplayName");
}
@BeforeEach
public void testBeforeEach(){
System.out.println("BeforeEach-------------");
}
@AfterEach
public void testAfterEach(){
System.out.println("AfterEach--------------");
}
}
结果:
3、BeforeAll和AfterAll注解
注意:BeforeAll和AfterAll是在所有的测试方法执行前执行,意思是总的只执行一次。所以,使用BeforeAll和AfterAll直接的方法要么是静态方法(static)要么,就得加回滚的注解@Transactional。否则会报错。
运行下面方法的类,也就是执行所有的测试方法。
package com.example.boot;
import org.junit.jupiter.api.*;
@DisplayName("只是个有名字的测试类")
public class MyTest {
@DisplayName("这是个有名字的方法")
@Test
public void testDisplayName(){
System.out.println("测试DisplayName");
}
@DisplayName("这是第二个有名字的方法")
@Test
public void testDisplayName_2(){
System.out.println("爱上了给方法取名");
}
@BeforeEach
public void testBeforeEach(){
System.out.println("BeforeEach-------------");
}
@AfterEach
public void testAfterEach(){
System.out.println("AfterEach--------------");
}
@BeforeAll
public static void testBeforeAll(){
System.out.println("BeforeAll---------------------");
}
@AfterAll
public static void testAfterAll(){
System.out.println("AfterAll----------------------");
}
}
结果:(BeforeEach和AfterEach在每个测试方法前后执行,BeforeAll和AfterAll只在最前面和最后面执行一次)
4、@Disable注解
现在,我们不想跑第二个测试方法了,那么,我们可以通过在第二个测试方法上面加@Disable注解,如此,我们运行我们的测试类的时候,就不会运行那个测试方法啦。
结果:(还告诉了我们那个方法有@Disable注解,够人性化!!!!)
5、@TimeOut注解
程序运行超过指定的时间的话,就会自动报错。
第一个参数是数值,第二个参数是单位。(有天、小时、分钟、秒、毫秒等等)
@Timeout(value = 500,unit = TimeUnit.MILLISECONDS)
@Test
public void testTimeout() throws InterruptedException {
Thread.sleep(600);
}
结果:
第二个参数的单位:
6、@ExtendWith注解
这个注解就厉害了。我们常规如果不使用@SpringBootTest注解的话,我们在该测试类中是无法使用我们的@AutoWired等注解的。之所以可以用呢,主要是@SpringBootTest注解中扩展了关于Spring的一系列注解(当然啦,上面那句@BootstrapWith也是有用的):
7、@RepeatedTest注解*
@RepeatedTest注解的作用是重复执行该测试。
@RepeatedTest(3)
@Test
public void testRepeated(){
System.out.println("跑起来!!!");
}
试了一下,他好像会先跑一次,然后再重复跑3次。
结果如下:(上面一次,下面三次)