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.