Junit5和Junit4有什么不一样

2,224 阅读5分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

最近看SpringBoot单元测试内容的时候,发现许多博文内容讲解时将JUnit4和JUnit5混淆在了一起,实际使用时导致代码频繁报错,在此整理一下JUnit4和JUnit5的区别,以便能够更清晰的认识和使用单元测试。

1. JUnit5

JUnit是Java使用广泛的测试框架,而JUnit5是单元测试模块的最新版本,其中增加了许多基于Java8编码风格的功能增强,如Lambda表达式的使用等,因此在如果项目中使用了Java8及以上的jdk版本,建议使用JUnit5进行测试。

1.1 JUnit5三大模块

JUnit5相对JUnit4来讲,JUnit5主要由三个模块组成:JUnit Platform、JUnit JUpiter和JUnit Vintage。

  • JUnit Platform:JUnit提供的平台功能模块,其他测试引擎可以基于平台接入JUnit
  • JUnit JUpiter:JUnit5的核心模块,基于JUnit Platform的引擎实现,增强自动化测试功能
  • JUnit Vintage:用来兼容JUnit3、JUnit4版本的测试引擎 JUnit5是易于兼容JUnit4内容的,如果实际使用时不想使用旧版本内容,可以在引入依赖时排除JUnit Vintage部分。
<dependency>    
    <groupId>org.springframework.boot</groupId>    
    <artifactId>spring-boot-starter-test</artifactId>    
    <scope>test</scope>    
    <exclusions>        
        <exclusion>            
            <groupId>org.junit.vintage</groupId>            
            <artifactId>junit-vintage-engine</artifactId>        
        </exclusion>    
    </exclusions>
</dependency>

1.2 JUnit5新特性

JUnit5不仅可以兼容JUnit4的测试功能,还带来了一些新的特性:

  • JUnit5中增加了对lambda表达式的支持,使用时代码更简练
  • JUnit5中提供了新的断言机制、参数化测试、重复性测试等,扩展性更强
  • JUnit5被组织为多个模块,在实际使用时可以根据需要单独引入
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>${junit.jupiter.version}</version>
</dependency>
<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-runner</artifactId>
    <version>${junit.platform.version}</version>
    <scope>test</scope>
</dependency>

2. 单元测试

2.1 一般流程

无论是JUnit4还是JUnit5,都是用于程序的单元测试,实际单元测试的一般流程可以描述为:

  1. 引入单元测试依赖信息,为使用做准备
  2. 创建功能测试类,并为类标注@SpringBoot注解表示当前类作为单元测试
  3. 创建具体功能的测试方法并使用@Test注解
  4. 针对程序功能逻辑使用断言机制测试功能正确性
  5. 执行单元测试方法,查看测试结果 对于由JUnit4升级到JUnit5,整个流程并没有太大变化,但是在流程中对应的注解使用和断言定义却有一定的变化。

2.2 导入包变化

由于依赖信息不同,因此在引入依赖后,JUnit4和JUnit5两者注解等功能使用的类对应的包发生了变化

  • JUnit4中使用测试类位于org.junit.Test包中
  • JUnit5中使用的测试类根据模块划分在org.junit.jupiter包中

2.3 常用注解变化

JUnit4版本中的注解有:

  • @RunWith:org.junit.runner.RunWith包中的注解,属于JUnit4,使用Spring对测试的支持,
    • 注解值SpringRunner.class,SpringRunner是SpringJUnit4ClassRunner的新名字
  • @Test:注解标注一个方法为测试方法,注解中可以设置时间参数,代表方法测试超时时间
    • JUnit4中@Test注解存在于org.junit.Test包
  • @Before:在单元测试方法执行前执行,每个单元测试方法都会执行一次
  • @BeforeClass:在单元测试类方法执行前执行,每次运行只执行一次
  • @After:在单元测试方法执行之后执行,每个方法都会执行一次
  • @AfterClass:在所有单元测试类方法执行之后执行,每次运行只执行一次
  • @Ingore:执行时跳过对应的测试内容

对应JUnit5中的注解变化

  • @SpringBootTest:标注一个类作为测试类,为SpringApplication创建上下文名支持SpringBoot
    • JUnit5中可以不再使用@RunWith注解,直接使用@SpringBootTest就可以定义测试类
  • @Test:注解标注一个方法为测试方法
    • 注意,Junit5中虽然也是@Test注解,但是该注解存在于org.junit.jupiter.api包
  • @BeforeEach:在单元测试方法执行前执行,每个单元测试方法都会执行一次
  • @BeforeAll:在单元测试方法执行前执行,静态方法,每次运行只执行一次
  • @AfterEach:在单元测试方法执行之后执行,每个方法都会执行一次
  • @AfterAll:在所有单元测试类方法执行之后执行,静态方法,每次运行只执行一次
  • @DisplayName:用来指定单元测试的名称,如@DisplayName("单元测试")
  • @Disabled:设置单元测试无效,跳过执行

2.4 测试方法断言变化

JUnit4中提供了断言方法用来验证单元测试方法中的结果,其位于org.junit.Assert类中,作为Assert的静态方法直接调用;而JUnit5中的断言内容位于org.junit.jupiter.api.Assertions类,其中提供的断言方法是当前类的静态方法,使用Assertions类调用。

  • Assert.assertEquals():验证目标参数值和实际参数是否相等,如果不相等则报错并输出内容(如果指定),JUnit5中使用Assertions.assertNotEquals()。
  • Assert.assertTrue()/assertFalse():验证参数条件为true/false,JUnit5中使用Assertions.assumeTrue()/Assertions.assumeFalse()。
  • Assert.assertNull()/assertNotNull():验证参数为null/notNull,JUnit5中使用Assertions.assertNull()/Assertions.assertNotNull()。
  • Assert.assertThrow():验证程序抛出异常是否和指定异常类一致,JUnit5中使用了 Assertions.assertThrows()方法。
  • assertTimeOut():验证程序执行时间是否超过指定时长,JUnit5中为Assertions.assertTimeout()。
  • assertAll():组合断言,内部可以使用多种断言组合,当内部所有断言通过后才会完成。JUnit5中使用了Assertions.assertAll()方法。 除了方法名称的改变之外,具体方法的参数也有所改变,整个方法实现的功能不变。