JUnit 5 - How to run unit tests in Maven
Introduction
In this post, I'll show you how you can configure your Apache Maven project to execute JUnit 5 (or JUnit 4) tests using the Maven Surefire plugin.
Apache Maven is a build automation tool specially designed for Java projects (although you can use it for other languages too).
If we check the Maven homepage, we'll learn that Maven relies on plugins to perform most of its tasks. This is summarized by the following quote:
Maven is -at its heart- a plugin execution framework; all work is done by plugins.
The Maven plugin in charge of running unit tests is the Maven Surefire plugin. Let's learn how it works.
Configuring the Maven Surefire Plugin
Maven uses the Maven Surefire Plugin by default whenever we execute the mvn test
goal.
This means that we don't even need to configure the plugin for Maven to use it.
For example, consider a base project with the following pom.xml content:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.marcnuri.demo</groupId>
<artifactId>junit5-surefire</artifactId>
<version>0.0-SNAPSHOT</version>
<properties>
<java.source.version>17</java.source.version>
<java.target.version>17</java.target.version>
</properties>
</project>
By executing the following command:
mvn test
We should be able to see a message like:
[INFO] --- surefire:3.0.0:test (default-test) @ junit5-surefire ---
[INFO] No tests to run.
Since we don't have tests in the project, we get the No tests to run
message.
You can notice in the logs that Maven is running version 3.0.0
of the Surefire plugin.
This is because I'm running Maven 3.9.2
which uses this version of the Surefire plugin.
In the future, we might want to set an explicit version of the plugin or provide further configurations.
For that purpose, we need to declare a plugin dependency in the build
section of the pom.xml
file:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
</plugins>
</build>
If we run the mvn test
command again, we'll notice that the surefire version has changed and it reports 3.1.2
instead:
[INFO] --- surefire:3.1.2:test (default-test) @ junit5-surefire ---
[INFO] No tests to run.
However, we still don't have any test to run. Let's now see how to add a JUnit 5 test to the project.
Creating JUnit 5 tests
Let's start by adding the JUnit 5 dependency to our project's pom.xml
file:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Next, let's create an example test class in the src/test/java
directory with the name ExampleTest.java
:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
class ExampleTest {
@Test
void test() {
assertTrue(true);
}
}
This is a very simple test that will always pass. We're just asserting that true
is true
.
The class name is important so that the Maven Surefire Plugin can include the test in the execution.
In this case, we've named the class ExampleTest
with the Test
suffix.
You can further configure these suffixes in the Maven Plugin configuration.
Let's execute once more the mvn test
command:
[INFO] --- surefire:3.1.2:test (default-test) @ junit5-surefire ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running ExampleTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.032 s -- in ExampleTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
Maven Surefire plugin successfully detects the test we just implemented and executes it for us. The Surefire plugin also prints a very simple report with the name of the test class and the test results.
Conclusion
In this post, I've shown you how to prepare your Java Maven project to be able to run both JUnit 4 and JUnit 5 tests. This is the most basic structure that will enable you to add complexity in the future.