【问题标题】:Tests run under JUnit 4 but not JUnit 5 — Compiles clean, but 0 tests execute测试在 JUnit 4 下运行,但不是在 JUnit 5 下运行——编译干净,但执行了 0 个测试
【发布时间】:2019-06-16 15:29:28
【问题描述】:

任何人都可以在几分钟内轻松重现此问题。

基础 Maven quickstart 项目

借助 IntelliJ 2018.3 和 Maven 3.6.0,我使用 Maven 原型 maven-archetype-quickstart 1.4 版创建了一个全新的项目。

Java 11

在新项目的 POM 文件中,我将 maven.compiler.sourcemaven.compiler.target 的属性从 1.7 更改为 11,对于我当前使用的 Java 11.0.2,ZuluAzul Systems

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>11</maven.compiler.source>
  <maven.compiler.target>11</maven.compiler.target>
</properties>

在 IntelliJ 的 Maven 面板上,我运行 cleaninstall 生命周期事件。

在 JUnit 4 中运行测试

作为install 的一部分,运行测试。这个quickstart 原型带有一个断言true 的单一测试。

结果显示在 IntelliJ 的 Run 面板中。

[INFO] 运行 work.basil.example.AppTest

[INFO] 测试运行:1,失败:0,错误:0,跳过:0,经过时间:0.026 秒 - 在 work.basil.example.AppTest 中

所以我知道执行的测试。

JUnit 5,而不是 4

这一切都很好。现在让我们升级到 JUnit 5,看看问题所在。

在 POM 中,我从这里更改了 JUnit 依赖项:

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
</dependencies>

……到这个:

<dependencies>
  <!--JUnit 5-->
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.3.2</version>
    <scope>test</scope>
  </dependency>
</dependencies>

木星导入(无老式测试)

编译器抱怨我的AppTest.java 文件。因此,我将那里的 import 语句更改为使用 jupiter 包。我只想在我的新 greedfield 项目中运行 JUnit 5 测试,而不需要老式的 JUnit 4 测试。所以进口从这个改变:

import static org.junit.Assert.assertTrue;
import org.junit.Test;

……到这个:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;

然后我执行Maven > Lifecycle > clean & install

...瞧,问题是:我们的测试没有执行。在 IntelliJ 的Run 面板中看到的报告:

[INFO] 运行 work.basil.example.AppTest

[INFO] 测试运行:0,失败:0,错误:0,跳过:0,经过时间:0.003 秒 - 在 work.basil.example.AppTest 中

➥ 为什么 JUnit 5 无法运行 JUnit 4 愉快运行的测试?

更新surefire插件

我怀疑Maven Surefire Plugin 需要更新。所以在 POM 中我改变了这个:

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.1</version>
</plugin>

……到这个:

<plugin>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>3.0.0-M3</version>
</plugin>

另一个clean & install。但没有更好,仍然运行 0 次测试。

[INFO] 运行 work.basil.example.AppTest

[INFO] 测试运行:0,失败:0,错误:0,跳过:0,经过时间:0.004 秒 - 在 work.basil.example.AppTest 中

整个 POM

这是我的整个 POM 文件。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>work.basil.example</groupId>
  <artifactId>tester</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>tester</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>

  <dependencies>
    <!--JUnit 5-->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.3.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.0.0-M3</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

JUnit 库

在做了一个 Maven clean & install 之后,出现了两个 JUnit 库:junit-jupiter-apijunit-platform-commons

其他版本的 JUnit 5

我在 junit-jupiter-api 依赖项中尝试了以下版本:

  • 5.0.0-M1
  • 5.1.1
  • 5.3.0
  • 5.3.2
  • 5.4.0-M1

每次尝试时,我都会运行一个 Maven cleaninstall。没有更好的。这些版本中的每一个都报告了Tests run: 0

不怪maven-archetype-quickstart

我实际上是在使用完全不同的 Maven 原型的一个完全不同的项目中发现了这个问题。

为了确定这个错误的 JUnit 5 行为,我使用非常简单的 maven-archetype-quickstart 尝试了一个新的新项目。我发现了同样的行为:一切都编译了,测试工具正在运行,但在 JUnit 5 下没有执行任何测试。

【问题讨论】:

  • 你知道 junit-vintage-engine maven artefact 吗?根据我的经验,要么添加它以运行未修改的旧测试,要么投入一些工作来遵循他们的迁移文档 (junit.org/junit5/docs/current/user-guide/#migrating-from-junit4)。
  • @JensDibbern 我没有运行老式测试。在我的问题中,我解释说我将import 语句更改为jupiter。在我的新新建项目中,我只需要 JUnit 5。
  • 您是否尝试过其他版本,例如。 5.3.0,或者可能是 5.0.0-M1,看看是否有效?由于不是来自同一个地方,可能仍然存在与 4 个版本测试的兼容性问题,但在简单的测试中它应该可以工作。
  • @TraianGEICU 版本 5.0.0-M1、5.1.1、5.3.0、5.3.2 和 5.4.0-M1 的 junit-jupiter-api 依赖项都无法运行测试。在问题中添加了部分。
  • @TraianGEICU 谢谢!这似乎解决了我的问题,添加了这两个依赖项中的一个:junit-jupiter-engine。我发布了an Answer 的详细信息。我遵循了其他地方的指示,说只需要一个 junit-jupiter-api 依赖项,但显然这些指示是错误的。

标签: java intellij-idea junit junit5 junit-jupiter


【解决方案1】:

tl;博士

对于 JUnit 5 版本 5.4.0-M1 或更高版本,在您的 POM 中指定新的单个 Maven 工件 junit-jupiter“Aggregator”。

<!--JUnit 5-->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.4.0-M1</version>
</dependency>

对于早期版本,请至少指定以下两个工件:junit-jupiter-api & junit-jupiter-engine

JUnit 5 控制多个测试框架

据我所知,JUnit 5 已重新设计为多个测试框架的枷锁。这些测试系统包括 JUnit 4 “老式”测试、新的 JUnit 5 测试(新的测试语法,带有新的注释和方法),以及其他如 SpecsySpekCucumber、Drools Scenario、@987654327 @ 和 more that implement TestEngine 接口。

显然junit-jupiter-api 工件只是外轭。您还必须指定一个或多个 TestEngine 实现才能实际运行测试。例如,要运行老式 JUnit 4 测试,您需要 VintageTestEngine 实现,或者要运行 JUNit 5 测试,您需要 JupiterTestEngine 实现。

因此,要运行 JUnit 5 测试,您必须在 Maven POM 中使用 junit-jupiter-engine 工件指定 JupiterTestEngine 实现。

请参阅 JUnit 5 手册,特别是 Configuring Test Engines 部分。

请参阅 Marc Philipp 的 this presentation,其图表显示 JUnit 5 作为一个平台,具有 (A) IDE/构建工具核心和 (B) 程序员编写测试的可插入测试编写框架。

junit-jupiter-engine

this sample 所示,为JUNit Jupiter Engine 添加第二个与JUnit 相关的依赖项。 documentation for this artifact 简单地说:“JUnit Jupiter 测试引擎实现,仅在运行时需要。”。

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.4.0-M1</version>
    <scope>test</scope>
</dependency>

只需将一个依赖项添加到您的问题中显示的项目中,您的测试就会运行。

[INFO] 运行 work.basil.example.AppTest

[INFO] 测试运行:1,失败:0,错误:0,跳过:0,经过时间:0.004 秒 - 在 work.basil.example.AppTest 中


junit-jupiter-params

同一个示例还显示了第三个 JUnit 依赖项,即 JUnit Jupiter Params。虽然不需要让您的示例测试运行,但它可能用于其他目的。显然与Parameterized Tests 有关。

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.4.0-M1</version>
    <scope>test</scope>
</dependency>

这使得总共有 3 个 JUnit 依赖项。

<!--JUnit 5-->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.4.0-M1</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.4.0-M1</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.4.0-M1</version>
    <scope>test</scope>
</dependency>

您的同一个 POM 文件,现在已更新为所有 3 个 JUnit 依赖项。

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns = "http://maven.apache.org/POM/4.0.0"
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>work.basil.example</groupId>
    <artifactId>tester</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>tester</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>

        <!--JUnit 5-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.4.0-M1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>5.4.0-M1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.4.0-M1</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>3.0.0-M3</version>
                </plugin>
                <plugin>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
                <plugin>
                    <artifactId>maven-site-plugin</artifactId>
                    <version>3.7.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-project-info-reports-plugin</artifactId>
                    <version>3.0.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

junit-jupiter神器

JUnit 5 5.4.0 版带来了一个新的 Maven 工件,junit-jupiter,标题为 JUnit Jupiter (Aggregator)。为了我们的编程方便,“聚合器*”这个词显然是指它在 Maven 中捆绑了一些常用的 JUnit 5 工件。

在您的 POM 中添加一个 dependency 可以在您的项目中获得 8 个库。

<!--JUnit 5-->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.4.0-M1</version>
</dependency>

【讨论】:

  • 从 5.4.0-M1 开始,您可以使用一个聚合器依赖项:org.junit.jupiter:junit-jupiter:5.4.0-M1。这将引入所有三个 org.junit.jupiter 依赖项。
  • @MarcPhilipp 非常感谢关于新单 JUnit Jupiter (Aggregator) 工件替换我项目 POM 中的多个 JUnit 工件的提示。我试过了,确实有效。我修改了我的答案以包含此信息。感谢您的所有工作 - 现在观看您的一个 YouTube 视频。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 2018-02-09
相关资源
最近更新 更多