在同一个构建中执行 JUnit 4 和 JUnit 5 的测试

57
在Maven项目中,我有一些依赖于JUnit 4的现有测试。由于多种原因,我无法将这些测试迁移到JUnit 5。
基本上,一些测试依赖于使用JUnit 4运行器的库,代码迁移可能需要时间。
我希望能够创建新的测试类,使用现在发布的JUnit 5,并提供新的有趣功能。
如何做到这一点?

我注意到一些流行的BDD工具尚未在JUnit 5下运行。 - Raedwald
@Raedwald 当我写这篇文章时,我的一个问题是针对Cucumber。对于使用多种语言的BDD工具,我注意到标准的Java并不总是得到很好的更新和支持。 - davidxxx
4个回答

84

JUnit 5提供了开箱即用的方式。

JUnit 5 = JUnit平台 + JUnit Jupiter + JUnit Vintage

每个项目都是独立的,使用它们可以在同一个项目中编译和执行JUnit 4和JUnit 5测试。

JUnit Jupiter 是JUnit 5中用于编写测试和扩展的新编程模型和扩展模型的组合。

JUnit Vintage 提供了一个TestEngine,用于在平台上运行基于JUnit 3和JUnit 4的测试。

JUnit平台作为在JVM上启动测试框架的基础。


更新: 自Maven Surefire 2.22.0

根据JUnit 5文档:

从版本2.22.0开始,Maven Surefire提供原生支持在JUnit平台上执行测试。

所以配置变得更加简单。
请注意,junit-4 api依赖项是可选的,因为现在所需的engine依赖项已经默认拉取了一个api版本(对于junit 4和5都是如此)。

这是一个pom.xml示例。

<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>david</groupId>
    <artifactId>jupiter-4-and-5-same-build</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit-jupiter.version>5.1.0</junit-jupiter.version>
        <!-- optional : if we want to use a junit4 specific version -->
        <junit.version>4.12</junit.version>
    </properties>
    <dependencies>
        <!--JUnit Jupiter Engine to depend on the JUnit5 engine and JUnit 5 API -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <!--JUnit Jupiter Engine to depend on the JUnit4 engine and JUnit 4 API  -->
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>${junit-jupiter.version}</version>
        </dependency>
        <!-- Optional : override the JUnit 4 API version provided by junit-vintage-engine -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
            </plugin>
        </plugins>
    </build>

</project>

我在我的GitHub空间中添加了一个可浏览/克隆的工作示例maven项目。

URL: https://github.com/ebundy/junit4-and-5-minimal-maven-project


旧方法:适用于 Maven Surefire 版本低于 2.22.0

以下是与Maven一起使用的最小配置,用于配置项目以编译和运行JUnit4和JUnit5测试:

<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>mygroup</groupId>
    <artifactId>minimal-conf-junit4-5</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <!-- JUnit 5 depends on JDK 1.8 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!--  JUnit dependency versions -->
        <junit.version>4.12</junit.version>
        <junit-vintage-engine>4.12.1</junit-vintage-engine>
        <junit-jupiter.version>5.0.1</junit-jupiter.version>
        <junit-platform.version>1.0.1</junit-platform.version>
    </properties>

    <dependencies>
        <!--JUnit Jupiter API to write and compile tests with JUnit5 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit 4 to make legacy JUnit 4 tests compile -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version> <!-- matters until now-->
                <dependencies>
                    <!-- to let surefire to run JUnit 4 but also JUnit 5 tests -->
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>${junit-platform.version}</version>
                    </dependency>
                    <!-- JUnit vintage engine to run JUnit 3 or JUnit 4 tests -->
                    <dependency>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                        <version>${junit-vintage-engine}</version>
                    </dependency>
                    <!-- JUnit 5 engine to run JUnit 5 tests -->
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>${junit-jupiter.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

现在,mvn test 命令可以编译并运行 JUnit 4 和 JUnit 5 的测试用例。

注1:依赖库 junit-vintage-engine4.12.1)和 junit4.12) 并非完全一致并不会造成问题,因为:

  • 它们的发布版本之间没有关联性;

  • junit-vintage-engine 可以运行任何 JUnit 34 版本的测试用例。

注2:使用 2.19.1 版本的 maven-surefire-plugin 即可编译 JUnit 5 的测试类以及同时编译 JUnit 4 和 JUnit 5 的测试类。该插件的下一个版本在执行 JUnit 5 测试时可能会引起一些异常,但从 2.22.0 版本开始就已经解决了这个问题(请参考答案的第一部分:“更新:从 Maven Surefire 2.22.0 开始”)。


1
非常感谢Marc!我测试了一个Spring Boot项目,它肯定为我添加了它。我进行了更新。 - davidxxx
1
我注意到的一件事是,如果你只有 JUnit 4 测试,那么 Surfire 插件将无法识别它们。无论有多少个 JUnit 4 测试存在,你的项目都需要至少一个 JUnit Jupiter 测试才能运行任何测试。 - Steve Gelman
1
junit-vintage-engine 也应该在 test 范围内。 - Smile
这个命令也适用于failsafe插件吗?mvn -Dit.test=XXXIT verify似乎找不到JUnit 5的集成测试? - Baradé

1

0
由于问题标题比较笼统,这里提供使用 Kotlin DSL(build.gradle.kts)的 Gradle 解决方案:
tasks.withType<Test> {
    useJUnitPlatform() // Enables JUnit Platform (JUnit 5 + JUnit 4)
}

dependencies {
    // Aggregator dependency that also brings JUnit 5 parameterized tests etc.
    testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
    // The Vintage engine is needed to be able to run JUnit 4 tests
    testImplementation("org.junit.vintage:junit-vintage-engine:5.10.0")
}

public class MyTestClass {
    @org.junit.jupiter.api.Test // <- JUnit 5 test
    public void jUnit5test() { /* ... */ }

    @org.junit.Test // <- JUnit 4 test
    public void jUnit4Test() { /* ... */ }
}

通过运行Gradle的testcheck任务来执行测试。

0

对于Gradle实现,只需使用junit 4和junit vintage依赖项。

dependencies {
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.junit.vintage:junit-vintage-engine'
}

并且还要添加测试来使用junitPlatform

test {
    useJUnitPlatform()
}

然后junit4和junit5测试都应该正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接