Sunday Sep 08

Key Concepts

Maven Integration Test

Sébastien Dante Ursini
PDFPrintE-mail
Tuesday, 12 April 2011 09:53
Written by Sébastien Dante Ursini
AddThis Social Bookmark Button

Maven integration tests using Surefire and Junit

Integration test introduction

Let's imagine you have some integration test and you want to put them in your Maven test folder. The Surefire Plugin is used during the test phase of the build lifecycle to execute your Java Unit tests.
Maven takes all the Java Test cases implementing JUnit library and execute them to define if the project can pass to the next lifecycle phase.

It is probably helpful to define what is a unit test and what is an integration test. Integration tests are mandatory to have reliable deliverable it is important to integrate them in our process.  

Unit test:

It is an automatic test to test the internal workings of a class. It should be a stand-alone test which is not related to other resources.

Integration test:

Is an automatic test that is done on an environment, so similar to unit tests but with external resources (db, disk access)

Because the integration tests are dependent on external resources you don't want to rely on them to pass the test phase. Maven should be able to package your solution wherever you are.

To do so find below a way to achieve this objective :

Rename all your Java integration tests using the same naming convention

NameTest > NameIntegrationTest

To tell the test plugin of Maven (Surefire) to exclude them from the test lifecycle we will configure the plugin using the pattern :

**/*IntegrationTest.java to exclude the integration tests

Maven integration tests

        <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12</version>
                <configuration>
                    <excludes>
                        <exclude>**/*IntegrationTest.java</exclude>
                    </excludes>
                </configuration>
             </plugin>   

Run Integration Tests with Maven (prior JUnit 4.7)

By default the Failsafe Maven Plugin looks for integration tests matching the patterns */IT.java, **/IT.java and */*ITCase.java. You will notice that these bindings do not overlap with the default surefire bindings. To use the Maven Failsafe Plugin you need to add the following to your

Apache Maven Project definition

  [...]
  
     <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.6</version>
                <configuration>
                    <excludes>
                        <exclude>**/*IntegrationTest.java</exclude>
                    </excludes>
                </configuration>
            <executions>
              <execution>
                <goals>
                  <goal>integration-test</goal>                 
                  <goal>verify</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
      
  [...]

The advantage to using the Maven Failsafe Plugin is that it will not stop the build during the integration-test phase if there are test failures. The recommendation is that you do not directly invoke the pre-integration-test, integration-test or post-integration-test phases but that instead you run integration tests by specifying the verify phase, e.g.

Apache Maven Plugin

mvn verify

 Congratulation ! You can now put your integration tests within your test folder and Maven is able to distinguish between unit tests and integration tests to run only the unit tests during the test phase

You are now able to run tests using continuous integration systems like Hudson or Continuum without having integration tests failing due to missing external resources.
 

Integration Tests with Junit 4.7

As of  JUnit 4.7 you have you can define categories for your tests. It enables you to define groups or labels on classes or intefaces. I will demonstates how to use it with Maven surefire.

Three steps are required to prevent your integration tests to execute during your build cycle :

  1. Create a marker interface for your integration tests
  2. Mark you integration test classes using the @Category annotation
  3. Configure Maven surefice to exclude the corresponding categories in your unit test cycle

1) Create a marker interface 

In the first step we need to create a marker interface to mark all of the tests you want to skip from the unit testing process

Junit 4.7 category marker

package com.ubiteck.test;

public interface IntegrationTest {}
 

2) Mark your integration classes using the JUnit 4.8 annotation

Mark your integration test class using Junit category annotation at the top of your class

Category annotation with junit Annotation

import com.capbs.test.IntegrationTest;
/**
 * Datasource integration test
 * 
 */
@Category(IntegrationTest.class)
public class DatasourceIntegrationTest {
    ....
}

3) Configure Maven to skip the marked classes from the unit test process

Configure Maven Surefire plugin to include junit in version 4.7 and define the groups you want to exclude using the tag excludedGroups

Maven surefire setting skip integration tests using Junit 4.7

[...]
            <!--*********************************************-->
            <!--*  Integration test exclusion configuration                      *-->
            <!--*********************************************-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.12</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit47</artifactId>
                        <version>2.12</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <includes>
                        <include>**/*.class</include>
                    </includes>
                    <excludedGroups>com.ubiteck.IntegrationTest</excludedGroups>
                </configuration>                
             </plugin>       
[...]

Run the integration test during the maven integration-test phase

If you want to run your integration tests during the integration-test phase you can une the following Maven snippet

<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.12</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>2.12</version>
        </dependency>
    </dependencies>
    <configuration>
        <groups>com.ubiteck.IntegrationTest</groups>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
            </goals>
            <configuration>
                <includes>
                    <include>**/*.class</include>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

If you have any remark or questions feel free to put a comment.If you enjoyed this tutorial and want to promote it don't hesitate to click on

Maven Tutorial related articles

 

 

Tags: maven, build, integration, tests, test, plugin, unit
Sébastien Dante Ursini

Sébastien Dante Ursini

Java/Finance Specialist 
17 Years of experience in Java
22 Year in Banking/Finance
Based in Geneva/Switzerland

Comments  

 
+1 #1 John Dobie 2011-06-29 14:09
Nice example. You can take this a step further and seperate them completely.

http://johndobie.blogspot.com/2011/06/seperating-maven-unit-integration-tests.html

Thought it might be of some interest to you.
Quote
 

Add comment


Security code
Refresh

Java Tutorial on Facebook