Junit5简介

By | 2018年6月26日

Junit5架构

junit5是一个platform,其引入的新API叫做junit-jupiter,所以有时junit5也被叫做junit platform或junit jupiter。

junit5-platform

junit-jupiter-engine:是一个TestEngine接口,用于发现和执行matching tests,默认有两个实现:

  • junit-vintage-engine:发现和执行junit3和junit4的test cases,其依赖于junit-4.12(junit4目前最新版本)。
  • junit-jupiter-engine:发现和执行junit5的test cases。
  • 企业或个人通过实现junit-platform-engine,开发自己的TestEngine和Test API。

junit3和junit4被大量的公司和企业使用,不能够直接放弃它们,junit5使用junit-vintage-engine来兼容老老代码。vintage是指特定年份的美酒(葡萄酒),这里用来指代junit3和junit4,足见其地位还是比较高的。

junit-platform-launcher:使用(调用)junit-platform-engine,通过ServiceLoader找到不同的实现,来执行不同的unit test。IDE和maven,gradle等都需要junit-platform-launcher来调用执行unit test。

Junit5 package diagram

点击下载-SVG格式的package diagram

Open4j的用途[1]

支持 JUnit 的测试框架在如何处理测试执行期间抛出的异常方面有所不同。JVM 上的测试没有统一标准,这是 JUnit 团队一直要面对的问题。除了 java.lang.AssertionError,测试框架还必须定义自己的异常分层结构,或者将自身与 JUnit 支持的异常结合起来(或者在某些情况下同时采取两种方法)

为了解决一致性问题,JUnit 团队提议建立一个开源项目,该项目目前称为 Open Test Alliance for the JVM(JVM 开放测试联盟)。该联盟在此阶段仅是一个提案,它仅定义了初步的异常分层结构。

Maven dependency

<dependency>
  <groupId>org.junit.platform</groupId>
  <artifactId>junit-platform-launcher</artifactId>
  <version>1.2.0</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>5.2.0</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.junit.vintage</groupId>
  <artifactId>junit-vintage-engine</artifactId>
  <version>5.2.0</version>
  <scope>test</scope>
</dependency>

junit-vintage-engine依赖于junit4,所以项目中可以删去对junit4的直接依赖。对于新项目,不需要考虑兼容老的test case,就不用依赖junit-vintage-engine,全都用jupiter-api来写test case。

Junit4中运行junit5

是指unit test的语法标签是junit5的,但是使用junit4来执行。在测试类上加@RunWith(JUnitPlatform.class)注解,就可以使那些执行junit4但还不支持junit5的IDE和工具来执行junit5语法的unit test。

<dependency>
  <groupId>org.junit.platform</groupId>
  <artifactId>junit-platform-runner</artifactId>
  <version>1.2.0</version>
  <scope>test</scope>
</dependency>

测试代码

import static org.junit.Assert.assertEquals;

import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

@RunWith(JUnitPlatform.class)
public class PeopleTest {

  @Test
  public void test() {
       assertEquals(12, 5);
  }

}

Eclipse中运行junit5

自从Eclipse Oxygen.1a(4.7.1a – Mon, 9 Oct 2017)版本就开始支持Junit5了,在junit5的test文件上,右键Run As –> Junit Test,它自动会选择junit 5 test runner。

如果在test source folder或test packge上,右键Run As –> Junit test,Eclipse会根据test文件内容自动选择哪个test runner来分别执行每个test class。

image

Maven中运行junit5

告诉surefire plugin,使用junit platform(junit5)来运行。方法是在surefire的<dependencies/>中加入surefire-junit-platform,注意surefire需是2.21.0或更高版本

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.22.0</version>
      <dependencies>
        <dependency>
          <groupId>org.apache.maven.surefire</groupId>
          <artifactId>surefire-junit-platform</artifactId>
          <version>2.22.0</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

此时在执行mvn test,所有的unit test都会在junit platform上执行。如果项目同时有junit3,junit4和junit5的test case,它们都会被执行。

备注

surefire-junit-platform是maven提供的,我们也可以是用junit自己提供的junit-platform-surefire-provider。

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-surefire-provider</artifactId>
    <version>1.2.0</version>
</dependency>

总结:兼容老代码升级到junit5

我们可以不用修改老的unit test,直接升级到junit5,junit platform会同时执行junit3, junit4和junit5的test case。

  • junit-vintage-engine负责发现和执行junit3、junit4的test case。
  • junit-jupiter-engine负责发现和执行junit5的test case。

完整的pom sample:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.22.0</version>
      <dependencies>
        <dependency>
          <groupId>org.apache.maven.surefire</groupId>
          <artifactId>surefire-junit-platform</artifactId>
          <version>2.22.0</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

<dependencies>
  <dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-launcher</artifactId>
    <version>1.2.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.2.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.2.0</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-runner</artifactId>
    <version>1.2.0</version>
    <scope>test</scope>
  </dependency>
</dependencies>

引用

[1]:对opentest4j的介绍源自于Junit 5 Jupiter API

其它参考

Junit 5 Vintage和Junit Jupiter扩展模型

Junit 5用户指南(中文)