How to separate unit testing and integration testing on a maven project How to separate unit testing and integration testing on a maven project jenkins jenkins

How to separate unit testing and integration testing on a maven project


I find it more convenient to put integration tests in separate projects, and then run them as if they were unit tests by relying on Maven's default life cycle. As I have to run my tests against different environments, this approach makes it easier to manage environment specific tests.

Let's assume I have an application, represented by the application Maven aggregator project, which contains a jar module called project. I keep unit tests within project itself, so that they get executed whenever I build my application. This is also built every night by Jenkins; ideally successful builds should be automatically deployed to one or more test environments, for both manual and automatic tests. Currently this is done by hand.

For every environment where I need to run my integration tests I have an applicationTestEnvX Maven aggregator project. This contains at least a projectTest module, where I keep those integration tests that are environment independent, as well as any test support code. Tests for my project module that are specific to environment X are kept in a projectTestEnvX module. I have a Jenkins job for each applicationTestEnvX project, which runs my tests every night. Ideally these should be run against the result of the application build, but I'm not there yet.

There is also a direct correspondence with how my projects are stored in Subversion and my Eclipse workspaces, but that's another story ;-)


Have a look at two Maven plugins: Surefire (for unit tests) and Failsafe (for integration tests). They closely resemble each other, Failsafe is a clone of Surefire.

Organize your tests so that their naming schema goes with proposed configuration: **/*Test.java for unit tests and **/*IT.java for integration. Surefire is run by default, for Failsafe you'll need extra excerpt in POM — example and more info in this answer.

Then it's down to mvn test or mvn integration-test.

If you want to run integration test only in certain environments (Jenkins), you could make Failsafe executing only in a profile, for example:

<profiles>    <profile>        <id>env-itest</id>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-failsafe-plugin</artifactId>                 <executions>                    <execution>                        <id>integration-test</id>                        <goals><goal>integration-test</goal></goals>                    </execution>                    <!-- other executions, if needed -->                 </executions>            </plugin>        </plugins>    </profile></profiles>

Then, on Jenkins, you run mvn clean install -P env-itest and on your local environment only mvn clean install (or simliar).


Have a look at the maven documentation around the integration test phase - you can use different plugins to control which tests are run, simply by naming the tests appropriately.

Then running mvn test will build & run your code & unit tests, which mvn verify will run your integration tests as well.