I have a multi-module maven project with both integration and unit tests in the same folder (src/test/java). Integration tests are marked with @Category(IntegrationTest.class)
. I want to end up with the following setup:
- If I run
mvn install
, I want all tests to compile, but I do not want to execute any. - If I run
mvn test
, I want all tests to compile, but execute only unit tests. - If I run
mvn integration-test
, I want to compile and execute all tests.
The important point is, I want this configured in the pom.xml
without any extra commandline arguments.
Currently I came up with the following setup in my parent pom.xml, where the only problem is #1, where all tests are executed:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${project.java.version}</source>
<target>${project.java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
<excludedGroups>cz.cuni.xrg.intlib.commons.IntegrationTest</excludedGroups>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14.1</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<configuration>
<groups>cz.cuni.xrg.intlib.commons.IntegrationTest</groups>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
All child modules have the following plugin configuration in their pom.xml, which I believe should inherit from the parent pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
</plugins>
</build>
I tried using <skipTests>true</skipTests>
, but it disables test execution for all goals, which is not what I want (violates #2 and #3). It is also quite weird, that mvn test
honors the skipTests=true
option…why would I want to run it in the first place??
After hours of googling and trying different combinations, I am hesitant whether it is even possible to not run tests in mvn install
, while at the same time run them in mvn test
. I hope someone proves this wrong. 😉
I am also willing to accept a solution, where mvn install
would execute only unit tests, but I don't think it makes much difference.
Best Answer
It sounds like you didn't understand the concept of the build life-cycle in Maven. If you run
mvn install
all life-cycle phases (including theinstall
phase itself) run before the install phase. This means running the following phases:which means in other words the
test
as well asintegration-test
life-cycle phases are included. So without any supplemental information it's not possible to change the behaviour as you wish it.It could be achieved by using a profile in Maven:
So your first requirement:
mvn install
, I want all tests to compile, but I do not want to execute any.can be achieved by using the following:
mvn test
, I want all tests to compile, but execute only unit tests.This can simply achieved by using the plain call:
cause the integration tests phase is not run (see the build life cycle).
mvn integration-test
, I want to compile and execute all tests.This means running the default which includes running the
test
phase which will run the unit tests (maven-surefire-plugin) and furthermore running the integration test which are handled by the maven-failsafe-plugin. But you should be aware that if you like to call the integration tests you should using the following command:instead, cause you missed the
post-integration-test
phase in your previous call.Apart from the above you should follow the naming conventions for unit and integration tests where unit tests should be named like the following:
and integration tests should be named like the following:
I hope you have configured the maven-failsafe-plugin like the following which is needed to bound the maven-failsafe-plugin to the correct life-cycle-phases:
as you correctly did, but you should be aware that the
include
tags work on the source code (.java) and not on the compiled names (.class). I wouldn't use the Category annotation, just simply using the naming conventions makes the pom simpler and shorter.