Junit5架构
junit5是一个platform,其引入的新API叫做junit-jupiter,所以有时junit5也被叫做junit platform或junit jupiter。
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
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。
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
其它参考