在 GitHub 上叉我

使用 JUnit 5 平台

配置 JUnit 平台

要开始使用 JUnit 平台,您需要向项目中添加至少一个TestEngine实现。例如,如果您想使用 Jupiter 编写测试,请将测试工件添加junit-jupiter-engine到 POM 中的依赖项中:

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

这将引入所有必需的依赖项。在这些依赖项中junit-jupiter-api,包含您的测试源需要编译的类和接口。junit-platform-engine也解决并添加。

这是开始所需的唯一步骤 - 您现在可以在测试源目录中创建测试(例如,src/test/java)。

如果您想通过 JUnit 平台编写和执行 JUnit 3 或 4 测试,请将 Vintage Engine 添加到依赖项中,该依赖项会传递(并需要)junit:junit:4.12

<dependencies>
    [...]
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>
    [...]
</dependencies>

有关使用 JUnit 5(即 JUnit Platform、JUnit Jupiter 和 JUnit Vintage)的更多信息,请参阅JUnit 5 网站JUnit 5 用户指南

Jupiter Engine 和 Vintage Engine for JUnit4 的智能分辨率

JUnit5 API 工件和您的测试源与引擎隔离。在这些章节中,您将了解如何以各种方式分离、组合、选择 API 和引擎。您可以使用 JUnit4/5JUnit5/TestNGJUnit4 Runner 找到用于 Jupiter 测试的集成测试。(参见 Maven 配置文件。)

如何只运行一个 API

通常,开发人员不想访问 JUnit5 引擎的内部类(例如5.4.0)。在接下来的章节中,您可以找到使用插件解析引擎的 Jupiter 或 JUnit5 API 的方法。

测试依赖项中的 Jupiter API

在这个例子中,POM 在测试类路径中只有 Jupiter API 依赖。该插件将解析并下载junit-jupiter-engine与版本相关的版本junit-jupiter-api。类似的原则也可以在以下章节中找到。

<dependencies>
    [...]
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>
    [...]
</dependencies>
...
<build>
    <plugins>
        [...]
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            [... configuration or goals and executions ...]
        </plugin>
        [...]
    </plugins>
</build>
...
API-Engine 版本隔离

在以下示例中,引擎工件出现在插件依赖项中,并且引擎由插件解析并从插件的远程存储库下载。您可能希望使用已修复的错误更新引擎版本,5.3.2但 API 版本5.3.0保持不变!

<dependencies>
    [...]
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.3.0</version>
        <scope>test</scope>
    </dependency>
    [...]
</dependencies>
...
<build>
    <plugins>
        [...]
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>5.3.2</version>
                </dependency>
            </dependencies>
        </plugin>
        [...]
    </plugins>
</build>
...
测试依赖项中的 JUnit4 API

这是在项目 POM 的测试依赖项中使用 JUnit4 的类似示例。Vintage 引擎工件必须在插件依赖项中;否则插件将使用surefire-junit4提供者而不是surefire-junit-platform提供者。

<dependencies>
    [...]
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    [...]
</dependencies>
...
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                    <version>5.4.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>
...

如何运行多个 API 或引擎

在以下示例中,您可以同时使用 JUnit4 和 JUnit5 测试。

Jupiter API 和 JUnit4

在依赖项中定义任何 JUnit5 API 后,将surefire-junit-platform选择提供程序,并且您始终可以添加 JUnit4 依赖项。

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>
Jupiter API 和 Vintage 引擎
<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>
木星和老式引擎
<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

选择引擎并使用多个 API

在这些示例中,您在测试依赖项中同时使用 API,即 Jupiter 和 JUnit4,但您希望通过插件依赖项选择引擎。

选择木星

在这里,您的测试从 JUnit4 和 Jupiter 导入包,但您只想选择一个带有 JUnit4 测试的 Maven 配置文件。

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<个人资料>
    <id>选择-junit5</id>
    <构建>
        <插件>
            <插件>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <依赖项>
                    <依赖>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <版本>5.6.2</版本>
                    </依赖>
                </依赖>
            </插件>
        </插件>
    </build>
</profile>
选择 JUnit4

在这里,您的测试从 JUnit4 和 Jupiter 导入包,但您只想选择一个带有 Jupiter 测试的 Maven 配置文件。

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<个人资料>
    <id>选择-junit4</id>
    <构建>
        <插件>
            <插件>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <依赖项>
                    <依赖>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                        <版本>5.6.2</版本>
                    </依赖>
                </依赖>
            </插件>
        </插件>
    </build>
</profile>

如何在 Jupiter 引擎中运行 TestNG 测试

您可以结合 JUnit5 测试运行 TestNG 测试。

有关详细信息,请参阅此示例

<dependencies>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.1.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.github.testng-team</groupId>
        <artifactId>testng-junit5</artifactId>
        <version>0.0.1</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

在这种情况下,Maven 不对损坏的兼容性和依赖项负责com.github.testng-team:testng-junit5

JUnit Runner

JUnit4 库在 JUnit5 的工件中实现了Runnerjunit-platform-runner

有关详细信息,请参阅此示例

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.6.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-runner</artifactId>
        <version>1.6.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

提供者选择

如果未配置任何内容,Surefire 会通过以下算法检测要使用的 JUnit 版本:

if the JUnit 5 Platform Engine is present in the project
    use junit-platform
if the JUnit version in the project >= 4.7 and the <<<parallel>>> configuration parameter has ANY value
    use junit47 provider
if JUnit >= 4.0 is present
    use junit4 provider
else
    use junit3.8.1

使用此技术时,不会检查项目的类路径中是否存在正确的测试框架。未能添加正确的测试框架将导致构建失败。

并行运行测试

从 JUnit 平台不支持并行运行测试。

运行单个测试类

JUnit Platform Provider 支持testMaven Surefire 插件支持的 JVM 系统属性。例如,要仅在org.example.MyTest测试类中运行测试方法,您可以mvn -Dtest=org.example.MyTest test从命令行执行。

按测试类名称过滤 Maven Failsafe

Maven Failsafe 插件将扫描其完全限定名称与以下模式匹配的测试类。

  • **/IT*.java
  • **/*IT.java
  • **/*ITCase.java

    此外,它会默认排除所有嵌套类(包括静态成员类)。

    但是请注意,您可以通过在 `pom.xml` 文件中配置显式的 `include` 和 `exclude` 规则来覆盖此默认行为。例如,要防止 Maven Failsafe 排除静态成员类,您可以覆盖其排除规则。

覆盖 Maven Failsafe 的排除规则

...
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <excludes>
                    <exclude>some test to exclude here</exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>
...

按标签过滤

您可以使用 JUnit5 标签并按标签或标签表达式过滤测试。

  • 要包括tagstag expressions,请使用groups
  • 要排除tagsor tag expressions,请使用excludedGroups
    ...
    <build>
        <plugins>
            ...
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    <groups>acceptance | !feature-a</groups>
                    <excludedGroups>integration, regression</excludedGroups>
                </configuration>
            </plugin>
        </plugins>
    </build>
    ...
    

配置参数

您可以通过使用 Java文件语法(如下所示)或通过文件声明configurationParameters属性并提供键值对来设置 JUnit 平台配置参数以影响测试发现和执行。Propertiesjunit-platform.properties

...
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <properties>
                    <configurationParameters>
                        junit.jupiter.conditions.deactivate = *
                        junit.jupiter.extensions.autodetection.enabled = true
                        junit.jupiter.testinstance.lifecycle.default = per_class
                        junit.jupiter.execution.parallel.enabled = true
                    </configurationParameters>
                </properties>
            </configuration>
        </plugin>
    </plugins>
</build>
...

@DisplayName 的 Surefire 扩展和报告配置

从插件版本 3.0.0-M4 开始,您可以使用细粒度的报告配置,并@DisplayName在您的测试中启用短语名称。这是特定对象属性的完整列表。您不必指定例如disable和。如果未另行指定,布尔值将达到默认值。versionencodingfalse

...
<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
                    <disable>false</disable>
                    <version>3.0</version>
                    <usePhrasedFileName>false</usePhrasedFileName>
                    <usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName>
                    <usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName>
                    <usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
                </statelessTestsetReporter>
                <consoleOutputReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5ConsoleOutputReporter">
                    <disable>false</disable>
                    <encoding>UTF-8</encoding>
                    <usePhrasedFileName>false</usePhrasedFileName>
                </consoleOutputReporter>
                <statelessTestsetInfoReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporter">
                    <disable>false</disable>
                    <usePhrasedFileName>false</usePhrasedFileName>
                    <usePhrasedClassNameInRunning>true</usePhrasedClassNameInRunning>
                    <usePhrasedClassNameInTestCaseSummary>true</usePhrasedClassNameInTestCaseSummary>
                </statelessTestsetInfoReporter>
            </configuration>
        </plugin>
    </plugins>
</build>
...

这些扩展的默认实现是org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporterorg.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporterorg.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter

扩展的目的是让用户自定义默认行为。如果您在 GitHub 上传播您的扩展,我们热衷于在 Apache Maven Surefire 站点上列出有用的扩展。