Search code examples
mavenjunitjunit5maven-surefire-plugin

JUnit5/Maven/Surefire: skipping (or forcing) selected slow unit tests


I have a Maven project using JUnit 5 and maven-surefire-plugin 2.22.2.

When I execute mvn clean install or mvn test, I would like a few specific tests to be skipped - they are either particularly slow, or require other services to be up (= integration tests).

So, I proceed like this:

import org.junit.jupiter.api.Tag;

public class ExampleTest {
    @Test
    public void testSomethingRegular() {
        // ...
    }

    @Test
    @Tag("IntegrationTest")
    public void testDatabaseAccess() {
        // ...
    }
}

And in pom.xml, I add this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
    <configuration>
        <excludedGroups>IntegrationTest</excludedGroups>
    </configuration>
</plugin>

...

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

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

In general, this works fine. I like the fact that this change is not intrusive - it does not force me to tag each "fast" unit test with e.g. @Tag("fast"), and I don't need to add/activate any new Maven profiles.

However, I have 2 questions:

  1. After tests are executed, I see Tests run: 1, Failures: 0, Errors: 0, Skipped: 0. Is it possible for testDatabaseAccess to be counted as Skipped, instead of being ignored?

  2. How to force executing testDatabaseAccess on-demand? I've tried mvn test -DincludedGroups=IntegrationTest -DexcludedGroups=aaa, but it did not work...


Solution

  • Answering question 2 - this can be achieved using Maven profiles:

    <properties>
        <project.tests.exclude>IntegrationTest</project.tests.exclude>
    </properties>
    
    ...
    
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.2</version>
        <configuration>
            <excludedGroups>${project.tests.exclude}</excludedGroups>
        </configuration>
    </plugin>
    
    ...
    
    <profiles>
        <profile>
            <id>allTests</id>
            <properties>
                <project.tests.exclude></project.tests.exclude>
            </properties>  
        </profile>
    </profiles>
    

    By default, executing mvn clean install will skip unit tests tagged IntegrationTest, while executing mvn clean install -PallTests will force all tests to run. And there's no need to declare the allTests profile in the .m2 directory or anywhere else.