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:
mvn install
, I want all tests to compile, but I do not want to execute any.mvn test
, I want all tests to compile, but execute only unit tests.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.
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 the install
phase itself) run before the install phase. This means running the following phases:
which means in other words the test
as well as integration-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:
<project>
[...]
<profiles>
<profile>
<id>no-unit-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
[...]
</project>
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 -Pno-unit-test test
mvn test
, I want all tests to compile, but execute only unit tests.This can simply achieved by using the plain call:
mvn test
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:
mvn verify
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:
<includes>
<include>**/*Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
and integration tests should be named like the following:
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
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:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.15</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
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.