Relentless Coding

A Developer’s Blog

Skipping or Selectively Running Tests With Maven

You might not always want to execute all tests. Sometimes you only want to run a single unit test, or only integrations tests that start with Foo. Let’s look at how to make this happen in Maven.

Table of Contents

Skip Unit or Integration Tests

Skip the execution of unit tests:

$ mvn compile -DskipTests

This will still compile the unit tests, but not run them. To skip both compilation and execution, use -Dmaven.test.skip. Note that this setting is also honored by the Failsafe plugin. Skip executing integration tests:

$ mvn verify -DskipITs

Execute a Single Unit or Integration Test Class

Execute a single unit test class with Surefire:

$ mvn test -Dtest=MyUnitTest

In a multi-module project, we need to add -DfailIfNoTests=false, otherwise a module will fail where a class with that name is not available. Also note that we do not execute integration tests because we instruct Maven to stop after the test phase. To run a single unit test class and skip all integration tests, add -DskipITs. Execute a single integration test class with Failsafe:

$ mvn verify -Dit.test=MyIntegrationTest

As you can guess by now, this will run the single integration test by the name of MyIntegrationTest, and will also run all unit tests. To prevent this, you can add -DskipTests. Again, don’t forget to set -DfailIfNoTests if you run Maven on a multi-module project.

Execute a Single Unit or Integration Test Within a Test Class

Both the Surefire and Failsafe Maven plugins allow you to go crazy in their syntax for filtering which individual test classes or methods should be run. Specifying the parameters -Dtest and -Dit.test will override all defined include all defined includes and excludes from your pom.xml. Maven will create an include that looks like **/${test}.java. We have seen how we can run single test classes by specifying the class name after -Dtest or -Dit.test. The next most simple format (since version 2.7.3) takes the form of ClassName#methodName, so if you have a test class named and a unit test method testEmptyOrderShouldThrow, you can run this test method by itself, excluding all other test by typing:

$ mvn test -Dtest=OrderTest#testEmptyOrderShouldThrow

Complexer syntax with both glob and regex patterns is possible since version 2.19. The documentation gives this example:

$ mvn test '-Dtest=???Test, !Unstable*, pkg/**/Ci*,
> *Test#test*One+testTwo?????, #fast*+slowTest'

Let’s break this down. As you can see, we specify multiple patterns in a single parameter (to prevent shell expansion, they are put inside single quotes):

  • ???Test will run any test that has a name that starts with any three characters and ends with Test (? is a glob character meaning any single character).
  • !Unstable* will not run any test that starts with Unstable (the initial ! negates the pattern).
  • pkg/**/Ci* will run any test that has pkg somewhere in its package name, followed by any number of other child package names, while the class name should start with Ci followed by zero or more wildcard characters and ending with (pkg/ matches, as does foo/bar/pkg/baz/
  • *Test#test*One+testTwo????? will run any test whose class name ends in Test and whose method name matches test + any amount of characters + One or testTwo + any five characters. So this will run two test methods in every test class called *Test.
  • #fast*+slowTest will run the methods fast* and slowTest where ever there are found.

We can even have more fun by throwing in regular expressions:

$ mvn test '-Dtest=Basic*, !%regex[.*.Unstable.*],
> !%regex[.*.MyTest.class#one.*|two.*], %regex[#fast.*|slow.*]'
  • !%regex[.*.Unstable.*] will not run any tests that contain Unstable somewhere in their path.
  • !%regex[.*.MyTest.class#one.*|two.*] will run methods named one and two in a class called MyTest. We see that when using globs, we can use forward slashes to delimit packages. However, when using regex, we use dots.
  • %regex[#fast.*|slow.*] will run the test methods fast and slow wherever they are found. Note that (at least in version 3.0.0-M4), the trailing .* wildcard pattern is not needed.

Further Reading

You can read more about Surefire and Failsafe from the comfort of your terminal:

$ mvn surefire:help -Ddetail
$ mvn failsafe:help -Ddetail

You can also read the Surefire and Failsafe online documentation: