JUnit 5 快速上手(从 JUnit 4 到 JUnit 5)

一直在关注 JUnit 5 的演进,自两年前首个 ALPHA 版后,经历了 6 的 Milestone, 3 个 RC 终于在 2017/09/10 正式发布了。其实还从未对其深究过,今天算是正式开始体验。

不像以往的版本,JUnit 5 现在是三个模块的合体 JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

  1. JUnit Platform: 运行测试的基础平台。还定义了开发测试框架的 TestEngine API。并提供了命令行执行测试以及与 Gradle, Maven, JUnit4 Runner 的集成
  2. JUnit Jupiter: 包含了新的编程和扩展模型。它还提供了一个运行新型测试的 TestEngine 实现
  3. JUnit Vintage: 提供了一个让 JUnit Platform 运行 JUnit 3 和 JUnit 4 的 TestEngine 实现

以上三个模块分工还是很明确,因此

  1. 从现有的 JUnit 4 项目步入到 JUnit 5 至少两 JUnit Platform 和  JUnit Vintage 两个
  2. 建立全新项目可以只引入  JUnit Platform 和 JUnit Jupiter
  3. 混合型当然是三个全部引入

但是由于 jar 包之间本身存在某种依赖关系,所以实际上 pom.xml 可以比想像的更简单

JUnit 5 要求 Java 8 及以上的版本,甚至与 Java 9 也有所展望,这个对于怕出乱子的领导是很难的。

关于 Maven 中如何使用 JUnit 5,可以参考 junit5-maven-consumer 这个 pom.xml 配置; 还可以酌情对该配置进行裁剪。

举例说明:

  1. 全新项目,只有 JUnit 5 新型编程/扩展模型,pom.xml 中只需要依赖
  2. 只需让原来的 JUnit 4 在 JUnit 5 平台上运行的话,pom.xml 中只需要依赖

    junit-vintage-engine 会自动引入相应版本的 JUnit。当然,如果只是这种需求话,真是吃饱了撑着

  3. 从 JUnit 4 迁移到 JUnit 5, 这是最贴合实际的需求,此时 pom.xml 只的依赖就是同时需要以上两个

依赖配置好了,在目前最新的 IntelliJ IDEA 2017.2.4 中可以正常同时执行 JUnit 4 和 JUnit 5 的测试用例了。但目前为止 mvn test 命令只会测试 JUnit 4 的测试用例,若要让 Maven 识别出所有的测试用例还得加上一个构建插件配置

关键是 junit-platform-surefire-provider 的配置,其他部分只需注意 JUnit 5 可用  @Tag 来标识,包含或排除测试用例。现在 Maven 上也没问题了。

现在可以来个兼具 JUnit 4 和 JUnit 5 具体来个例子,pom.xml 中需要加上前面提到了三块配置。下面开始列出代码

待测试类 Calculation

JUnit 4 测试类

JUnit 5 测试类

注意:是 JUnit 4 测试类还是 JUnit 5 测试类,关键看注解 @Test 是来自于哪个包,比如说

  1. @Test 是 org.junit.Test,那么它是老的 JUnit 4 的测试类(也可能是 JUnit 3 的)
  2. @Test 是 org.junit.jpiter.api.Test, 那么它是 JUnit 5 的测试类

@Test 注解的出处会影响其他标签的行为,例如用 @org.junit.Test 搭配 JUnit 5 特有注解(像 @DisplayName) 就是来到捣乱的,那么这时候 @DisplayName 不会有任何效果。但 JUnit 4  的 @Test 与新的断言方法是可以工作的。

如果我们不得不在一个项目中混合 JUnit 4 和  JUnit 5 的话,我们必须保持使用的  API 是版本一致的。

现在我们可以开始运行测试用例了,分别是在 IDE 和控制台下

Intellij IDEA 2017.2.4

IDEA 可以正确处理 @DisplayName 标签,但是对 @Tag 视而不见

Maven 控制台

Maven 能够根据 @Tag 进行排除用例,但是它在一切正常时原本就不会显示测试用类名,所以也就不知道 @DisplayName 是什么,除非自定义 RunListener.

那么 Maven 在有用例失败时,以往都是显示失败的方法名称,那么 JUnit 5 是怎么显示失败的测试用例呢?还是照旧

或许 JUnit 5 还是认为显示失败的实际方法名更有助于定位错误。因此,基本上认为 @DisplayName 是给 IDE 用的。要不就自定义 RunListener 吧。

本来想在此了解一下 JUnit 5 的新特性,思考之后还是觉得目前最紧要的可能是如何从 JUnit 4 迁移到  JUnit 5, 所以才有了上面的内容。我们完全可以先让两个版本的 JUnit 测试用例并行,然后逐步替换掉  JUnit 4 测试用例。官方的迁移文档是 Migrating from JUnit 4. 迁移不光是 API 的替换,还有 JUnit 5 不再支持 Rule 了,还要验证 JUnit 5 是否能与 Mock 框架 Mockito, JMockit 等正常工作。

类别: Java/JEE. 标签: . 阅读(103). 订阅评论. TrackBack.

Leave a Reply

Be the First to Comment!

avatar