Surefire is not picking up Junit 5 tests

72,354

Solution 1

The maven-surefire-plugin, as of today, does not have full support of JUnit 5. There is an open issue about adding this support in SUREFIRE-1206.

As such, you need to use a custom provider. One has already been developed by the JUnit team; from the user guide, you need to add the junit-platform-surefire-provider provider and the TestEngine implementation for the new API:

<build>
  <plugins>        
    <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <!-- latest version (2.20.1) does not work well with JUnit5 -->
      <version>2.19.1</version>
      <dependencies>
        <dependency>
          <groupId>org.junit.platform</groupId>
          <artifactId>junit-platform-surefire-provider</artifactId>
          <version>1.0.3</version>
        </dependency>
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-engine</artifactId>
          <version>5.0.3</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

Also, be sure to declare the junit-jupiter-api dependency with a scope of test:

<dependencies>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.0.3</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Solution 2

Update 2

Issue has been fixed in Maven Surefire Plugin v2.22.0

New version is available at Maven Central Repository.

Maven

<dependency>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
</dependency>

Gradle

compile group: 'org.apache.maven.plugins', name: 'maven-surefire-plugin', version: '2.22.0'

Update

As Marian pointed out, the latest version of JUnit 5 Platform Surefire Provider (1.2.0) supports latest version of Maven Surefire Plugin (2.21.0):

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.2.0</version>
                </dependency>
            </dependencies>
        </plugin>



Example

pom.xml

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

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.2.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

TestScenario.java

package test;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class TestScenario {

    @Test
    @DisplayName("Test 2 + 2 = 4")
    public void test() {
        Assertions.assertEquals(4, 2 + 2);
    }
}

Output (mvn clean install)

...
[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ test --- [INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running test.TestScenario
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 s - in test.TestScenario
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
...


Simplest way till today:

    <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.19.1</version>
        <dependencies>
            <dependency>
                <groupId>org.junit.platform</groupId>
                <artifactId>junit-platform-surefire-provider</artifactId>
                <version>1.1.0</version>
            </dependency>
        </dependencies>
    </plugin>

Solution 3

From the JUnit 5 documentation :

Starting with version 2.22.0, Maven Surefire provides native support for executing tests on the JUnit Platform.

Additionally you can read in the maven-surefire-plugin documentation :

Using JUnit 5 Platform

To get started with JUnit Platform, you need to add at least a single TestEngine implementation to your project. For example, if you want to write tests with Jupiter, add the test artifact junit-jupiter-engine to the dependencies in POM

So just that is enough to make run JUnit 5 tests :

<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>davidxxx</groupId>
    <artifactId>minimal-pom-junit5</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <junit-jupiter.version>5.2.0</junit-jupiter.version> 
        <!--optional below but good practice to specify our java version-->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

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

        <!--optional below -->
        <!-- add any JUnit extension you need such as -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

On my GitHub space I added a working sample maven project that you can browse/clone.
URL: https://github.com/ebundy/junit5-minimal-maven-project

Solution 4

I encountered the same problem in August 2019 which I asked about here: Maven silently fails to find JUnit tests to run. These answers led me in the right direction, but I found that you can solve the problem even more concisely. I copied my solution from the JUnit5 sample Maven project.

As of JUnit 5.5.1 and maven-surefire-plugin 2.22.2, you do not need to add the junit-platform-surefire-provider dependency. It is enough to have this one dependency and one plugin specified in your pom.xml:

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.5.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.2</version>
        </plugin>
    </plugins>
</build>

Solution 5

I ran into this issue with JUnit5 and Maven but also noticed that, even if only junit-jupiter-engine was added as a dependency, tests would run on some projects, not on others. And I kind of see the same pattern in the comments here: In @Alex comment above you can see he doesn't have any issue, even with earlier versions of surefire/junit/platform.

After scratching my head for some time I realized that those projects where the tests wouldn't run were those where the tests method names dit not contain the word "test". Though this isn't mandated by http://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html

In other words: just with

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

this

@Test
public void something() {
    assertTrue(true);
}

will NOT be run, whereas

@Test
public void testSomething() {
    assertTrue(true);
}

WILL be run !

This issue unfolds as a russian doll...

Anyway, +1 for @Mikhail Kholodkov whose updated answer fixes all the issues at once!

Share:
72,354
Ali Dehghani
Author by

Ali Dehghani

I'm Ali Dehghani, grew up in northern Iran, in a small village called Malijgaleh. Interested in software engineering, computer science, traveling, and astrophysics!

Updated on July 08, 2022

Comments

  • Ali Dehghani
    Ali Dehghani almost 2 years

    I wrote a simple test method with JUnit 5:

    public class SimlpeTest {
        @Test
        @DisplayName("Some description")
        void methodName() {
            // Testing logic for subject under test
        }
    }
    

    But when I run mvn test, I got:

    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running SimlpeTest
    Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec
    
    Results :
    
    Tests run: 0, Failures: 0, Errors: 0, Skipped: 0
    

    Somehow, surefire didn't recognize that test class. My pom.xml looks like:

    <properties>
        <java.version>1.8</java.version>
        <junit.version>5.0.0-SNAPSHOT</junit.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.junit</groupId>
            <artifactId>junit5-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <repositories>
        <repository>
            <id>snapshots-repo</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <updatePolicy>always</updatePolicy>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    Any idea how to make this work?

  • FrVaBe
    FrVaBe over 6 years
    Not that simple (at least at the moment). See JUnit 5 User Guide
  • LazerBanana
    LazerBanana over 6 years
    @FrVaBe weird its works just fine on mine with the m6 version.
  • splatch
    splatch over 6 years
    Worth to note that at this moment surefire 2.20.1 doesn't work with junit 5 provider thus 2.19.1 used in sample is still valid despite of passed year.
  • Eric
    Eric over 6 years
    I tired surefire-2.20.1 + junit-5.0.2 and it didn't work. I also tried surefire-2.20.1 + junit-5.1.0-M6 and it didn't work
  • user7610
    user7610 about 6 years
    I've tried the SNAPSHOTs and all is working (with Surefire 2.21.0). Hopefully it be still working at the time of release.
  • valodzka
    valodzka about 6 years
    surefire 2.21.0 doesn't work too, have to rollback to 2.19.1
  • Thirler
    Thirler almost 6 years
    @valodzka For me it does work with 2.21.0 and newer versions of the plugin and junit5. See junit.org/junit5/docs/current/user-guide/…
  • dann.dev
    dann.dev almost 6 years
    I have also just experienced an issue with mvn 3.5.0, jdk 1.8.0_101 where my class name did not have 'Test' in and the test was not picked up, this helped me find that!
  • Fabien M
    Fabien M almost 6 years
    Yeah indeed you should be compliant to maven.apache.org/surefire/maven-surefire-plugin/examples/… But I was talking about something different.
  • dann.dev
    dann.dev almost 6 years
    Yes it turned out I had two problems, the first was not remembering the basic maven surefire test rules. The second was not doing a Maven > update project for eclipse to pick up the junit 5 launcher.
  • Serhii Povísenko
    Serhii Povísenko almost 6 years
    Verified: maven-surefire-plugin v2.21.0 works fine with junit-jupiter-engine v5.2.0 and junit-platform-surefire-provider v1.2.0
  • Alexei Vinogradov
    Alexei Vinogradov almost 6 years
    This only works because of Test in the name of the class. Rename the class to ExampleScenario - it will not be discovered. (Surefire 2.22.0)
  • Mikhail Kholodkov
    Mikhail Kholodkov almost 6 years
    @AlexeiVinogradov Yes. It's expected behavior. More information available here: stackoverflow.com/a/6178629/3523579
  • vicmac
    vicmac over 5 years
    This works for me!. Thanks!. I am using spring-boot 2.0.4.RELEASE. Also with maven-surefire-plugin 2.21.0 did not work.
  • Mark
    Mark over 5 years
    My issue was that I did not have junit-vintage-engine as a dependency, and all of my tests were written for JUnit 4.
  • RedShift
    RedShift over 5 years
    November 2018: still have to use junit-platform-surefire-provider, at version 1.3.1, even though the Junit documentation claims otherwise.
  • John Thompson
    John Thompson over 5 years
    This config will fail with Surefire 2.22.0 or higher. You need to exclude the Junit deps from the Surefire config. I wrote a quick post about it here - springframework.guru/…
  • CoderTR
    CoderTR almost 5 years
    the combination of specified junit, platform and surefire versions worked for me. thanks !
  • user1053510
    user1053510 over 4 years
    You should wrap the <dependency> in <dependencies> in your code sample.
  • Jónás Balázs
    Jónás Balázs almost 4 years
    I would like to add that the class and methods must be public.
  • Wooff
    Wooff over 3 years
    bevare, junit engine version vs. spring boot parent version. Just specify dependency junit-jupiter-engine:5.1 does not work where newer versions does. Spring boot has still preconfigured JUnit4 <junit.version>4.13.
  • silver
    silver over 3 years
    This is the correct and concise approach. Works with OpenJDK 11 and JUnit 5.6.2.
  • Saikat
    Saikat over 3 years
    The junit-platform-surefire-provider has been deprecated and is scheduled to be removed in JUnit Platform 1.4. Please use the built-in support in Maven Surefire >= 2.22.0 instead. junit.org/junit5/docs/current/user-guide/…
  • Carlos
    Carlos almost 3 years
    perfect for me, the other options have not worked
  • pero_hero
    pero_hero over 2 years
    you saved me thanks...groovy-all included groovy-testng and after excluding it....tests are running
  • Matthew Read
    Matthew Read about 2 years
    @RunWith is from JUnit 4, so I don't think that applies to this question about JUnit 5 tests. (You should add junit-vintage-engine as a dependency to maven-surefire-plugin if you want to run JUnit 4 tests under JUnit 5.)