I have a maven2 multi-module project and in each of my child modules I have JUnit tests that are named Test.java
and Integration.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 execute
mvn 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
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.
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>
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!
clean compile integration-test -Dmaven.test.failure.ignore=false
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
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
<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
<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.
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
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, and mvn integration-test
to only run its (no unit tests).
You should try using maven failsafe plugin. You can tell it to include a certain set of tests.
maven-failsafe-plugin
has gone to Plugin Graveyard
failsafe
plugin has been moved to maven-failsafe-plugin
. It looks like the maven-failsafe-plugin
is still active (docs were last pushed March 2014).
By default, Maven only runs tests that have Test somewhere in the class name.
Rename to IntegrationTest and it'll probably work.
Alternatively you can change the Maven config to include that file but it's probably easier and better just to name your tests SomethingTest.
From Inclusions and Exclusions of Tests:
By default, the Surefire Plugin will automatically include all test classes with the following wildcard patterns: \*\*/Test\*.java - includes all of its subdirectory and all java filenames that start with "Test". \*\*/\*Test.java - includes all of its subdirectory and all java filenames that end with "Test". \*\*/\*TestCase.java - includes all of its subdirectory and all java filenames that end with "TestCase". If the test classes does not go with the naming convention, then configure Surefire Plugin and specify the tests you want to include.
Another way of running integration tests with Maven is to make use of the profile feature:
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/*IntegrationTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
<excludes>
<exclude>**/*StagingIntegrationTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
...
Running 'mvn clean install' will run the default build. As specified above integration tests will be ignored. Running 'mvn clean install -P integration-tests' will include the integration tests (I also ignore my staging integration tests). Furthermore, I have a CI server that runs my integration tests every night and for that I issue the command 'mvn test -P integration-tests'.
You can follow the maven documentation to run the unit tests with the build and run the integration tests separately.
<project>
<properties>
<skipTests>true</skipTests>
</properties>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<skipITs>${skipTests}</skipITs>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
This will allow you to run with all integration tests disabled by default. To run them, you use this command:
mvn install -DskipTests=false
I didn't need to do all those setups suggested in other answers and I can run unit tests or integration tests separately.
What I did was:
add the config bellow to pom.xml in order to instruct maven where are the integration tests files (the java code and the resources files):
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-integration-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/integration-test/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-integration-test-resource</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/integration-test/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Name the integration test files with the "IT" suffix, like "MyTestIT.java" Execute only the integration tests with this command: mvn failsafe:integration-test failsafe:verify
In the command above "failsafe:integration-test" will execute the *IT.java files and "failsafe:verify" will tell maven to check if any of the integration tests ran previously have failed. If you don't use 'failsafe:verify' the mvn command will exit with success even if one test has failed.
To run only the unit tests, run: mvn test
Success story sharing
mvn integration-test
also runs unit tests (using via surefire) butmvn failsafe:integration-test
runs only the failsafe integration tests.package
phase, that means I should put all my IT java source code undersrc/main/java
instead ofsrc/test/java
right?