How do I get my Maven Integration tests to run
Solution 1
You can set up Maven's Surefire to run unit tests and integration tests separately. In the standard unit test phase you run everything that does not pattern match an integration test. You then create a second test phase that runs just the integration tests.
Here is an example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>test</goal>
</goals>
<phase>integration-test</phase>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Solution 2
The Maven build lifecycle now includes the "integration-test" phase for running integration tests, which are run separately from the unit tests run during the "test" phase. It runs after "package", so if you run "mvn verify", "mvn install", or "mvn deploy", integration tests will be run along the way.
By default, integration-test runs test classes named **/IT*.java
, **/*IT.java
, and **/*ITCase.java
, but this can be configured.
For details on how to wire this all up, see the Failsafe plugin, the Failsafe usage page (not correctly linked from the previous page as I write this), and also check out this Sonatype blog post.
Solution 3
I have done EXACTLY what you want to do and it works great. Unit tests "*Tests" always run, and "*IntegrationTests" only run when you do a mvn verify or mvn install. Here it the snippet from my POM. serg10 almost had it right....but not quite.
<plugin>
<!-- Separates the unit tests from the integration tests. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Skip the default running of this plug-in (or everything is run twice...see below) -->
<skip>true</skip>
<!-- Show 100% of the lines from the stack trace (doesn't work) -->
<trimStackTrace>false</trimStackTrace>
</configuration>
<executions>
<execution>
<id>unit-tests</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- Never skip running the tests when the test phase is invoked -->
<skip>false</skip>
<includes>
<!-- Include unit tests within integration-test phase. -->
<include>**/*Tests.java</include>
</includes>
<excludes>
<!-- Exclude integration tests within (unit) test phase. -->
<exclude>**/*IntegrationTests.java</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- Never skip running the tests when the integration-test phase is invoked -->
<skip>false</skip>
<includes>
<!-- Include integration tests within integration-test phase. -->
<include>**/*IntegrationTests.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Good luck!
Solution 4
You can split them very easily using JUnit categories and Maven.
This is shown very, very briefly below by splitting unit and integration tests.
Define A Marker Interface
The first step in grouping a test using categories is to create a marker interface.
This interface will be used to mark all of the tests that you want to be run as integration tests.
public interface IntegrationTest {}
Mark your test classes
Add the category annotation to the top of your test class. It takes the name of your new interface.
import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
@Test
public void longRunningServiceTest() throws Exception {
}
}
Configure Maven Unit Tests
The beauty of this solution is that nothing really changes for the unit test side of things.
We simply add some configuration to the maven surefire plugin to make it to ignore any integration tests.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.11</version>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<excludedGroups>
com.test.annotation.type.IntegrationTest
</excludedGroups>
</configuration>
</plugin>
When you do a mvn clean test
, only your unmarked unit tests will run.
Configure Maven Integration Tests
Again the configuration for this is very simple.
We use the standard failsafe plugin and configure it to only run the integration tests.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<groups>
com.test.annotation.type.IntegrationTest
</groups>
</configuration>
</plugin>
The configuration uses a standard execution goal to run the failsafe plugin during the integration-test phase of the build.
You can now do a mvn clean install
.
This time as well as the unit tests running, the integration tests are run during the integration-test phase.
Solution 5
You should use maven surefire plugin to run unit tests and maven failsafe plugin to run integration tests.
Please follow below if you wish to toggle the execution of these tests using flags.
Maven Configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>${skipUnitTests}</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<include>**/*IT.java</include>
</includes>
<skipTests>${skipIntegrationTests}</skipTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<properties>
<skipTests>false</skipTests>
<skipUnitTests>${skipTests}</skipUnitTests>
<skipIntegrationTests>${skipTests}</skipIntegrationTests>
</properties>
So, tests will be skipped or switched according to below flag rules:
Tests can be skipped by below flags:
-
-DskipTests
skips both unit and integration tests -
-DskipUnitTests
skips unit tests but executes integration tests -
-DskipIntegrationTests
skips integration tests but executes unit tests
Running Tests
Run below to execute only Unit Tests
mvn clean test
You can execute below command to run the tests (both unit and integration)
mvn clean verify
In order to run only Integration Tests, follow
mvn failsafe:integration-test
Or skip unit tests
mvn clean install -DskipUnitTests
Also, in order to skip integration tests during mvn install
, follow
mvn clean install -DskipIntegrationTests
You can skip all tests using
mvn clean install -DskipTests
Related videos on Youtube
Peter Delaney
Software developer focusing mostly with integration of applications using SOAP/REST, JMS and other integration technologies. Experienced deploying applications in AWS cloud environment and AWS Architect/Developer/SysOps Associate certified.
Updated on February 11, 2022Comments
-
Peter Delaney over 2 years
I have a maven2 multi-module project and in each of my child modules I have JUnit tests that are named
Test.java
andIntegration.java
for unit tests and integration tests respectively. When I execute:mvn test
all of the JUnit tests
*Test.java
within the child modules are executed. When I executemvn test -Dtest=**/*Integration
none of the
Integration.java
tests get execute within the child modules.These seem like the exact same command to me but the one with the -Dtest=/*Integration** does not work it displays 0 tests being run at the parent level, which there are not any tests
-
heenenee over 8 yearsKief's answer should be the accepted one, as it is the current standard for defining integration tests in Maven.
-
-
Peter Delaney over 14 yearsHi and thanks I have two kinds of tests normal POJO Junit tests called SomethingTest.java which get fired. I also have integration tests called SomethingIntegration.java which do not get fired. The SomethingTest.java get fired via mvn test or mvn install. The second tests do not get fired. mvn test -Dtest=**/*Integration
-
Peter Delaney over 14 yearsI configured this as you said and only the *Test not the *Integration.java files will run when executing: mvn install I need to run my *Test.java as the default, but for my nightlty build I need to run both *Test.java and *Integration.java. I have to execute mvn install then cd to each sub-child directory and execute mvn -Dtest=**/*Integration test
-
mdma about 13 years+1 This is what I use. Works well, and allows you to do pre/post setup, such as starting and shutting down a local servlet container.
-
Joshua Davis almost 13 yearsWhy wouldn't you use the integration-test phase? Profiles can then be used for things like integration-testing against various app servers, etc. like Arquillian does. I'm not a Maven expert, but I think the experts might say this is not very 'Maven-y'.
-
Joshua Davis almost 13 years.. and by "Maven only runs tests that have Test somewhere in the class name" you mean "the Maven surefire plugin only runs tests that have Test somewhere in the class name".
-
Jorge almost 13 years@Joshua I guess I do it this way because my integration tests take at least 5 minutes to run and I issue 'mvn clean install' many times a day because I need to update my artifacts in my local maven repo. According to what people are saying above, running 'install' will cause the integration-test phase to run causing me to lose precious developer time.
-
Joshua Davis almost 13 yearsHmm... not sure about 'install' running integration-test. In any case I'd still use the phase instead of a profile. Profiles are better off used for things like supporting different app servers, etc.
-
Jorge almost 13 yearsI'll go ahead and play around with that then. Thanks for the advice!
-
Dave over 12 yearsThen feel free to check the box for this response being the answer!
-
John Gordon about 12 yearsYou should use the Fail-safe plugin for integration testing, not the sure-fire plugin. It won't fail the build until after the post-integration phase is complete; allowing you to tear down test resources (a web server, for example) before the build is failed. Hence, fail-safe.
-
Julian almost 12 yearsIts not "somewhere in the classname" its "the class name ends with Test", for example MyTest works but MyTests doesn't
-
Kilokahn over 11 years@jorge I guess the correct goal to use here would be verify, right?
-
Tarun Kumar about 11 yearsfor me, as part of pre-integration phase, jetty server starts. Last log line is : [INFO] Started Jetty Server. After that, nothing happens. It gets stuck. maven surefire failsafe plugin doesn't execute tests nor jetty server stops. Any idea what's wrong? I am using same configuration as specified by you.
-
DeejUK almost 11 yearsThis only works if the marker interface already exists somewhere available to Maven. It does not work if your marker interface exists in another module of the same multi-module build.
-
Jin Kwon about 10 years
maven-failsafe-plugin
has gone to Plugin Graveyard -
V Krishan about 10 yearsThe graveyard page just says the
failsafe
plugin has been moved tomaven-failsafe-plugin
. It looks like themaven-failsafe-plugin
is still active (docs were last pushed March 2014). -
Jin Kwon almost 10 years@WillV Correct. The Codehaus' graveyard. And the maven-failsafe-plugin is in Apache now. Sorry. :)
-
Shadow Man almost 10 yearsBy default
mvn integration-test
also runs unit tests (using via surefire) butmvn failsafe:integration-test
runs only the failsafe integration tests. -
Henno Vermeulen over 8 yearsIncredibly, the Failsafe plugin documentation, usage page and FAQ do not mention that it runs test classes named */IT.java, **/*IT.java, and **/*ITCase.java...
-
SujitS over 8 yearsWhat if I use excludedGroups instead of exclude in default one. I tried that but I cannot run the
integration-tests
with that. While I triedmvn clean install -P integration-tests
it ignores the excluded group and test categorized withintegration-tests
wont run. -
Neill Lima over 7 yearsThis should be the accepted answer. The associated maven goal is:
clean compile integration-test -Dmaven.test.failure.ignore=false
-
Bruce Sun over 7 yearsIf it runs after
package
phase, that means I should put all my IT java source code undersrc/main/java
instead ofsrc/test/java
right? -
Joshua Taylor over 7 years@HennoVermeulen I was confused about what to name tests as well. It's described in Inclusions and Exclusions of Tests. It's nice that the defaults can be overridden, but it'd be nice if they'd mention the defaults earlier on.
-
Zac Thompson over 6 yearsThis answer is very out of date and should be updated or removed.
-
Rohit Barnwal over 6 yearsAny help with this one? stackoverflow.com/questions/48639730/…
-
Praveen Tiwari over 5 years@HennoVermeulen it does, see here maven.apache.org/surefire/maven-failsafe-plugin/…
-
Praveen Tiwari over 5 years@HennoVermeulen and maven.apache.org/surefire/maven-failsafe-plugin/…
-
Henno Vermeulen over 5 years@p_champ you are right, I guess I didn't look well enough
-
Jacob van Lingen almost 5 years@BruceSun: Neither, put them under
src/it/java
, see also khmarbaise.github.io/maui/it-example-1.html -
Nexonus over 3 yearsWithout additional configuration in the surefire plugin the IT tests did not run although my IT tests fit the default naming pattern. However calling
mvn clean test-compile failsafe:integration-test
did execute them directly. (Source: stackoverflow.com/a/43470158/9478795) -
Jorge Muñoz over 2 yearsExactly the solution that I have been searching for may hours. Works fine!, Thankyou Liquidpie.
-
king pong over 2 yearsAm I really MAD if I find it UNBELIEVABLE when such an ESSENTIAL functionality like this SIMPLE separation of running Unit-tests or Integration-tests still isn't working RELIABLY in Maven ? Do I really want too much ?
-
Derlin about 2 yearsUPDATE: the
skipXXTests
trick doesn't work anymore. As of version 3.0.0 of failsafe, the<skipTests>
option has been removed. Now, we need to use-DskipITs
to skip integration tests,-DskipTests
to skip all tests, andmvn integration-test
to only run its (no unit tests).