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
- Execute a Single Unit or Integration Test Class
- Execute a Single Unit or Integration Test Within a Test Class
- Further Reading
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
OrderTest.java
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*leTest.java,
> *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 withTest
(?
is a glob character meaning any single character).!Unstable*
will not run any test that starts withUnstable
(the initial!
negates the pattern).pkg/**/Ci*leTest.java
will run any test that haspkg
somewhere in its package name, followed by any number of other child package names, while the class name should start withCi
followed by zero or more wildcard characters and ending withleTest.java
(pkg/CileTest.java
matches, as doesfoo/bar/pkg/baz/CiqwertyleTest.java
).*Test#test*One+testTwo?????
will run any test whose class name ends inTest
and whose method name matchestest
+ any amount of characters +One
ortestTwo
+ any five characters. So this will run two test methods in every test class called*Test
.#fast*+slowTest
will run the methodsfast*
andslowTest
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 containUnstable
somewhere in their path.!%regex[.*.MyTest.class#one.*|two.*]
will run methods namedone
andtwo
in a class calledMyTest
. 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 methodsfast
andslow
wherever they are found. Note that (at least in version3.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: