Apache Maven Surefire plugin is the most known plugin to run test with Apache Maven build tool, however it is not the only one. Surefire is a good plugin but it abstracts test engines which means you don't really use as expected the new JUnit Platform when you run JUnit 5 tests which can defeat the selection of a test framework ecosystem. The other issue you can hit *today* - hopefully fixed in some months - is that Surefire 2 is mainly in maintainance mode and Surefire 3 is still in milestones so if your dependency policy is strict you are not in a very well position.

Therefore you can wonder if you can use something else than surefire to run your tests.

If you review testing frameworks, you will realize there are already test plugin which can superseed surefire in some specific area, from the framework specific plugin (scalatest to cite one) to another language testing (frontend plugin to run npm/yan tests).

Now, if you dig into JUnit 5, you realize they have a launcher which is a plain main (java executable) and notifies the success/failure o the suite based on the exit code...so you can run setup the execution of your test with exec-maven-plugin.

However, this last option has a few drawbacks:

  • Each module customizing test environment/system properties must redefine the full command or play with maven merge list configuration flags,
  • No more IDE (Intellij) support - Intellij is able to parse system properties/environment from your pom to automatically align the IDE run test configuration.

But at the end we just need a plugin doing that execution. This is more or less what does junit-platform-maven-plugin once configured.

This plugin fully configure JUnit5 console launcher to execute your tests in a Junit5 way.

Personally I use the brand new 1.0.0 release and configure it to execute the tests in a fork process (not in the maven JVM to avoid to hide issues due to the classloading of maven which is not the classloading of the production code) and I request it to not fail if there is no test in a module - same default as surefire:

<plugin>
  <groupId>de.sormuras.junit</groupId>
  <artifactId>junit-platform-maven-plugin</artifactId>
  <version>1.0.0</version>
  <extensions>true</extensions>
  <configuration>
    <isolation>NONE</isolation>
    <executor>JAVA</executor>
    <javaOptions>
      <inheritIO>true</inheritIO>
      <additionalLauncherOptions>
        <additionalLauncherOption>--disable-banner</additionalLauncherOption>
      </additionalLauncherOptions>
    </javaOptions>
    <tweaks>
      <failIfNoTests>false</failIfNoTests>
    </tweaks>
  </configuration>
</plugin>

The super neat feature of that plugin is fully revealed in extension mode (as in previous snippet). If you set it in your parent pom, it will rewrite all your reactor poms to replace surefire by this plugin and is now able to rewire systemPropertyVariables and environmentVariables to the plugin. The big advantage is that you keep customizing this default configuration (which is just about the execution mode) in submodules defining surefire plugin so you can still rely on Intellij integration to have a fluent development.

So the interesting things in this journey are to keep in mind that:

  • Maven defines (good) defaults but nothing is written in the stone and you can always fully customize your build,
  • You can *today* benefit from the full Junit5 stack (to the execution solution),
  • If you must stick to a strict versioning policy, you have a solution to have an up to date testing plugin,
  • There is always a solution to each issue :).

Happy testing!

From the same author:

In the same category: