Run Both JUnit 4 and Junit5 With Maven Surefire Plugin - 2020

Viewed 5119

I see a few people having this issue and am struggling for a few weeks now, but not able to run both JUnit4 and JUnit5 on the same project (I need this to maintain some old tests). I noticed that if I remove the maven surefire plugin I can run the JUnit4 tests whereas when it's added to the POM only the JUnit5 ones.

<plugins>
    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
       <version>3.0.0-M4</version>
    </plugin>
</plugins>

Similar thing happens to this dependency. If I add it to the POM file I can run JUnit4 tests even if the maven surefire plugin is there. However, I need to remove it to be able to run JUnit5 tests.

<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>${junit5.version}</version>
    <scope>test</scope>
</dependency>

This is my complete 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>com.hmhco</groupId>
<artifactId>tests</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
    <java.version>1.8</java.version>
    <maven.compiler.version>3.8.1</maven.compiler.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <rest-assured.version>3.0.0</rest-assured.version>
    <json-schema-validator.version>3.3.0</json-schema-validator.version>
    <junit5.version>5.2.0</junit5.version>
</properties>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>${junit5.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.5.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.30</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M4</version>
        </plugin>
    </plugins>
</build>

And these are the small classes I'm try to run using mvn test

import org.junit.Test;

public class J4Test {

@Test
public void testing() {
    System.out.println("Testing J4");
    }
}

--

import org.junit.jupiter.api.Test;

public class J5Test {

@Test
public void testing() {
    System.out.println("Testing J5");
    }
}
4 Answers

We have improved the plugin in the 3.0.0-M5 version so that you do not need to use engines in your dependencies. This new approach avoids using internal code of the engine in your tests and it enables you to only call the API:

Maybe this example and documentation helps.

<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>

In my case upgrading maven-surefire-plugin to version 3.0.0-M5 did not help, but adding the engines helped. Now I have both engines in my pom.xml as dependencies:

    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>

The first is to run JUnit 4 tests, the second to run JUnit 5 tests. So in my case both run now together.

As per @johanneslink answer, this is my new pom where I can run both JUnit4 and Junit5 together from maven command.

<?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>com.example</groupId>
<artifactId>junit5-migration-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>

    <junit.version>4.13</junit.version>
    <junit.jupiter.version>5.6.2</junit.jupiter.version>
    <junit.vintage.version>5.6.2</junit.vintage.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>${junit.jupiter.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>${junit.jupiter.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>${junit.vintage.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
            <configuration>
                <!--<groups>fast</groups>-->
                <excludedGroups>slow</excludedGroups>
                <properties>
                    <!--
                    <configurationParameters>
                        junit.jupiter.conditions.deactivate = *
                    </configurationParameters>
                    -->
                </properties>
            </configuration>
        </plugin>
    </plugins>
</build>

We actually had both Junit 4 and JUnit 5 tests running with junit-platform and surefire 2.22

When we upgraded to surefire 3.0.0-M5 it caused Junit 5 tests to stop running.

We needed to exclude junit-platform to get them to run again.

Related