Using JUnit 5 Platform
Configuring JUnit 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:
<dependencies> [...] <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.4.0</version> <scope>test</scope> </dependency> [...] </dependencies>
This will pull in all required dependencies. Among those dependencies is junit-jupiter-api
which contains the classes and interfaces your test source requires to compile. junit-platform-engine
is also resolved and added.
This is the only step that is required to get started - you can now create tests in your test source directory (e.g., src/test/java
).
If you want to write and execute JUnit 3 or 4 tests via the JUnit Platform add the Vintage Engine to the dependencies, which transitively pulls in (and requires) junit:junit:4.12
:
<dependencies> [...] <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <version>5.4.0</version> <scope>test</scope> </dependency> [...] </dependencies>
For more information on using JUnit 5, that is the JUnit Platform, JUnit Jupiter, and JUnit Vintage, see the JUnit 5 web site and the JUnit 5 User Guide.
Smart Resolution of Jupiter Engine and Vintage Engine for JUnit4 (since plugin version 3.0.0-M4)
JUnit5 API artifact and your test sources become isolated from engine.
Normally the developer does not want to access internal classes of JUnit5 engine (e.g. 5.4.0
). In this example the POM has only Jupiter API dependency in test classpath.
<dependencies> [...] <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.4.0</version> <scope>test</scope> </dependency> [...] </dependencies> ... <build> <plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> [... configuration or goals and executions ...] </plugin> [...] </plugins> </build> ...
In the following example the engine artifact appears in plugin dependencies and the engine is resolved by the plugin and downloaded from a remote repository for plugins. You may want to update the version of engine with fixed bugs in 5.3.2
but the API version 5.3.0
stays intact!
<dependencies> [...] <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.3.0</version> <scope>test</scope> </dependency> [...] </dependencies> ... <build> <plugins> [...] <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>5.3.2</version> </dependency> </dependencies> </plugin> [...] </plugins> </build> ...
Similar with JUnit4 in test dependencies of your project POM. The Vintage engine artifact is in plugin dependencies.
<dependencies> [...] <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> [...] </dependencies> ... <build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> <dependencies> <dependency> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> <version>5.4.0</version> </dependency> </dependencies> </plugin> </plugins> </build> ...
Provider Selection
If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:
if the JUnit 5 Platform Engine is present in the project use junit-platform if the JUnit version in the project >= 4.7 and the <<<parallel>>> configuration parameter has ANY value use junit47 provider if JUnit >= 4.0 is present use junit4 provider else use junit3.8.1
When using this technique there is no check that the proper test-frameworks are present on your project's classpath. Failing to add the proper test-frameworks will result in a build failure.
Running Tests in Parallel
From JUnit Platform does not support running tests in parallel.
Running a Single Test Class
The JUnit Platform Provider supports the test
JVM system property supported by the Maven Surefire Plugin. For example, to run only test methods in the org.example.MyTest
test class you can execute mvn -Dtest=org.example.MyTest test
from the command line.
Filtering by Test Class Names for Maven Failsafe
The Maven Failsafe Plugin will scan for test classes whose fully qualified names match the following patterns.
**/IT*.java
**/*IT.java
**/*ITCase.java
Moreover, it will exclude all nested classes (including static member classes) by default.
Note, however, that you can override this default behavior by configuring explicit `include` and `exclude` rules in your `pom.xml` file. For example, to keep Maven Failsafe from excluding static member classes, you can override its exclude rules.
Overriding exclude rules of Maven Failsafe
... <build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> <configuration> <excludes> <exclude>some test to exclude here</exclude> </excludes> </configuration> </plugin> </plugins> </build> ...
Filtering by Tags
You can use JUnit5 Tags and filter tests by tags or tag expressions.
- To include
tags
ortag expressions
, usegroups
. - To exclude
tags
ortag expressions
, useexcludedGroups
.... <build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> <configuration> <groups>acceptance | !feature-a</groups> <excludedGroups>integration, regression</excludedGroups> </configuration> </plugin> </plugins> </build> ...
Configuration Parameters
You can set JUnit Platform configuration parameters to influence test discovery and execution by declaring the configurationParameters
property and providing key-value pairs using the Java Properties
file syntax (as shown below) or via the junit-platform.properties
file.
... <build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> <configuration> <properties> <configurationParameters> junit.jupiter.conditions.deactivate = * junit.jupiter.extensions.autodetection.enabled = true junit.jupiter.testinstance.lifecycle.default = per_class junit.jupiter.execution.parallel.enabled = true </configurationParameters> </properties> </configuration> </plugin> </plugins> </build> ...
Surefire Extensions and Reports Configuration for @DisplayName
Since plugin version 3.0.0-M4 you can use fine grained configuration of reports and enable phrased names together with @DisplayName
in you tests. This is the complete list of attributes of particular objects. You do not have to specify e.g. disable
, version
and encoding
. The boolean values reach default values false
if not specified otherwise.
... <build> <plugins> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M4</version> <configuration> <statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter"> <disable>false</disable> <version>3.0</version> <usePhrasedFileName>false</usePhrasedFileName> <usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName> <usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName> <usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName> </statelessTestsetReporter> <consoleOutputReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5ConsoleOutputReporter"> <disable>false</disable> <encoding>UTF-8</encoding> <usePhrasedFileName>false</usePhrasedFileName> </consoleOutputReporter> <statelessTestsetInfoReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporter"> <disable>false</disable> <usePhrasedFileName>false</usePhrasedFileName> <usePhrasedClassNameInRunning>true</usePhrasedClassNameInRunning> <usePhrasedClassNameInTestCaseSummary>true</usePhrasedClassNameInTestCaseSummary> </statelessTestsetInfoReporter> </configuration> </plugin> </plugins> </build> ...
Default implementations of these extensions are org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter
, org.apache.maven.plugin.surefire.extensions.SurefireConsoleOutputReporter
, and org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter
.
The aim of extensions is to let the users customizing the default behavior. We are keen on listing useful extensions on Apache Maven Surefire site if you propagate your extensions on GitHub.