1. Overview

In this tutorial, we're going to look at how we can select unit tests using Maven. For this purpose, we'll examine different configuration properties of the Maven Surefire plugin.

2. Include Tests

2.1. Configure includes

Firstly, we can select the test classes with the includes property. This property enables us to specify test class patterns.

By default, it includes the patterns Test*.java, *Test.java, *Tests.java and *TestCase.java.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.0</version>
            <configuration>
                <includes>
                    <include>**/Test*.java</include>
                    <include>**/*Test.java</include>
                    <include>**/*Tests.java</include>
                    <include>**/*TestCase.java</include>
                </includes>
            </configuration>
        </plugin>
    </plugins>
</build>

If we want to specify additional patterns, we must append them to the default ones:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <includes>
            <include>**/*E2E.java</include>
            <include>**/E2E*.java</include>
            <include>**/Test*.java</include>
            <include>**/*Test.java</include>
            <include>**/*Tests.java</include>
            <include>**/*TestCase.java</include>
        </includes>
    </configuration>
</plugin>

Here, we're adding *E2E.java and E2E*.java to the possible test class names.

Note that if we provide additional patterns without specifying the default ones, the default ones are discarded.

2.2. Configure includesFile 

We can also use the includesFile property to include test classes:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <includesFile>src/test/resources/includes.txt</includesFile>
    </configuration>
</plugin>

where includes.txt contains:

*/test/*
%regex[.*Test.*|.*Live.*]

The target file defines each pattern on a new line. In the first line, we're getting all classes in the test package. In the second line, we're including the test classes whose name contains Test or Live.

3. Exclude Tests

Maven Surefire plugin also provides excludes and excludesFile properties to exclude the tests - similar to includes and includesFile.

The excludes property defines exclusions with the exclude elements:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <excludes>
            <exclude>**/norun/*.java</exclude>
            <exclude>%regex[com.*Heavy.*.class], Ignored*</exclude>
            <exclude>**/*$*</exclude>
        </excludes>
        <excludesFile>src/test/resources/excludes.txt</excludesFile>
    </configuration>
</plugin>

On the other hand, the excludesFile property references a target file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <excludesFile>src/test/resources/excludes.txt</excludesFile>
    </configuration>
</plugin>

where excludes.txt contains:

*/exclude/*
%regex[.*Test.*|.*Live.*]

4. Specify Tests

We can also specify which tests to run using the test property:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <test>*Test,Test*,E2E*</test>
    </configuration>
</plugin>

In this example, Surefire will select only the classes that start with Test, E2E or end with Test.

Most importantly, this property overrides the includes, includesFile, excludes and excludesFile properties. Moreover, each specified pattern is converted to an include pattern. So after the conversion, the previous example becomes:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <includes>
            <include>**/*Test.java</include>
            <include>**/Test*.java</include>
            <include>**/E2E*.java</include>
        </includes>
    </configuration>
</plugin>

5. Include/Exclude Groups

Alternatively, we can use the groups property to include tests or use the excludedGroups property to exclude tests.

But before that, we must mark our tests with a group.

We'll first create the classes that will define our groups. Each class can be a marker interface - an interface without any methods:

public interface SlowTest {
}
public interface FastTest {
}

Here, we have two marker classes: SlowTest and FastTest.

Then we'll annotate our test methods with @Category whose value is one of the marker classes:

public class MixedPersonTest {

    @Category(FastTest.class)
    @Test
    public void runsFast() {
        // Test code
    }

    @Category(SlowTest.class)
    @Test
    public void runsSlow() {
        // Test code
    }
}

We can also annotate the test classes with @Category:

@Category(SlowTest.class)
public class SlowPersonTest {

    @Test
    public void run() {
        // Test code...
    }
}

Here, we have the SlowPersonTest class. Since we know that it contains slow tests, we're marking it with @Category(SlowTest.class). Consequently, this also marks all the test methods inside the class as SlowTest.

After we've marked our test methods and classes, we can now configure the Surefire plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <groups>
            com.javabyexamples.maven.plugins.surefire.groups.FastTest
        </groups>
        <excludedGroups>
            com.javabyexamples.maven.plugins.surefire.groups.SlowTest
        </excludedGroups>
    </configuration>
</plugin>

Here, we're defining both groups and excludedGroups. As a result, the Surefire plugin runs the tests marked with FastTest and excludes the ones marked with SlowTest.

6. Summary

In this tutorial, we examined different configurations of the Maven Surefire plugin to select test classes.

Finally, check out the source code for all examples over on Github.