Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I skip tests in maven install goal, while running them in maven test goal?

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:

  1. If I run mvn install, I want all tests to compile, but I do not want to execute any.
  2. If I run mvn test, I want all tests to compile, but execute only unit tests.
  3. 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.

like image 446
thegeko Avatar asked Jun 14 '13 21:06

thegeko


People also ask

What is Maven test Skip?

In Maven, you can define a system property -Dmaven. test. skip=true to skip the entire unit test. By default, when building project, Maven will run the entire unit tests automatically. If any unit tests is failed, it will force Maven to abort the building process.

How do you skip an integration-test?

If, instead, you want to skip only the integration tests being run by the Failsafe Plugin, you would use the skipITs property instead: mvn install -DskipITs.


1 Answers

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:

  1. validate
  2. initialize
  3. generate-sources
  4. process-sources
  5. generate-resources
  6. process-resources
  7. compile
  8. process-classes
  9. generate-test-sources
  10. process-test-sources
  11. generate-test-resources
  12. process-test-resources
  13. test-compile
  14. process-test-classes
  15. test
  16. prepare-package
  17. package
  18. pre-integration-test
  19. integration-test
  20. post-integration-test
  21. verify
  22. install

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:

  1. If I run 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 
  1. If I run 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).

  1. If I run 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.

like image 84
khmarbaise Avatar answered Sep 16 '22 17:09

khmarbaise