DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Separating Maven Unit & Integration Tests

Separating Maven Unit & Integration Tests

John Dobie user avatar by
John Dobie
·
Oct. 20, 11 · Interview
Like (0)
Save
Tweet
Share
13.49K Views

Join the DZone community and get the full member experience.

Join For Free

In this example I will show how you can perform a standard Maven build whilst keeping your unit and integration tests in separate packages.

Other techniques specify using either a naming convention or a separate module to do this.
This example allows true package separation and is self contained in a single profile so it can easily be used across projects. Alternative profiles can also be created for different types of test.

This solution lends itself well to generating code coverage metrics using Sonar and Jacoco.
http://johndobie.blogspot.com/2011/06/seperating-test-code-coverage-with.html

The first section shows what happens in the example and how to run it.
The second section explains how it works.

1.1 Example Structure

Here we have the typical maven structure and our new folder \src\integrationtest\java




1.2 Running the Example

The full code is hosted at google code. Use the following commands to check it out and run it.

svn co https://designbycontract.googlecode.com/svn/trunk/failsafe
cd failsafe
mvn –Pit clean integration-test

Alternatively you can look at the Hudson build here :https://designbycontract.ci.cloudbees.com/job/maven_with_split_tests/

1.3 Results of running the example

  • The tests in the standard maven test structure are run during the unit test phase as usual.
  • The tests in the \src\integrationtest\java directory are run during the integration test phase.
  • The integration test classes are placed in the seperate \target\integrationtest-classes directory

1.4 Isn't there an easier way?

Maven doesn’t really have a tidy way of dealing with this. Common suggestions are discussed here. http://olemortenamundsen.wordpress.com/2009/07/22/strategies-for-separating-unit-and-integration-tests-using-maven-eclipse-idea-cobertura/

The main ones are

  • Use \src\test package and use a separate directory or naming convention.
  • Put the integration tests in a separate module.

Maven does allow you to change the test source directories as demonstrated. The problem is that the Maven properties are immutable so you can't change them twice in the same build.

Firstly, we need to keep them at the defaults to enable our unit tests to run correctly.

<testSourceDirectory>src\test\java</testSourceDirectory>   
<testOutputDirectory>target\test-classes</testOutputDirectory> 

Secondly we need to change them as below for our integration tests to be run correctly.

<testSourceDirectory>src\integrationtest\java</testSourceDirectory>  
<testOutputDirectory>target\integrationtest-classes</testOutputDirectory>  

Unfortunately we cannot do this because the properties are immutable and cannot be both in the same build. However by using a number of different plugins and settings we can get the above scenario to work.

2. So what’s the Solution?

There are a number of discrete actions.

  • Firstly define variables for your integration test source and target directories
  • Use ant to create the output directory for the integration tests
  • Use the build helper plugin to add your test source to the compile path and copy any resources.
  • Compile the integration tests using -d to specify the path to the integration test source
  • Use the failsafe plugin to run the tests using parameters to specify the correct directories
  • Put it all in a profile so it can be used conveniently

These are shown in the lifecycle diagram below.




2.1 Define 2 Variables pointing to the integration tests

We need to define where the integration test classes are and where to compile and run them from.


<properties>
<integrationSourceDirectory>src\integrationtest</integrationSourceDirectory>
<integrationOutputDirectory>target\integrationtest-classes</integrationOutputDirectory>
</properties>

2.2 Create The Output Directory

Use the Maven antrun plugin to create the output directory \target\integrationtest-classes This is needed for the compiler which won't create it!

<execution>
<id>create-directory</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<echo message="Creating Directory ${integrationOutputDirectory}"/>
<mkdir dir="${integrationOutputDirectory}" />
</tasks>
</configuration>
</execution>

2.3 Use Build Helper To Add The Test Source And Resources

First add the classes in src\integrationtest\java to the compile path

<execution>
<id>add-test-sources</id>
<phase>pre-integration-test</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>${integrationSourceDirectory}/java</source>
</sources>
</configuration>
</execution>

Copy any resources from \src\integrationtest\resource to \target\integration-classes. This is not strictly necessary to get things working but allows easy packaging if you required.

<execution>
<id>add-test-resources</id>
<phase>pre-integration-test</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${integrationSourceDirectory}/java</directory>
<targetPath>${integrationOutputDirectory}</targetPath>
</resource>
</resources>
</configuration>
</execution>

2.4. Compile The Classes Using -d to Control the location

By default your classes will be compiled to \target\classes. This forces your classes to be output to target\integrationtest-classes

<execution>
<phase>pre-integration-test</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<compilerArguments>
<d>${integrationOutputDirectory}</d>
</compilerArguments>
</configuration>
</execution>


2.5 Use Failsafe to run the tests and customise the locations

This runs all tests in \target\integrationtest-classes. The failsafe reports are put in \target\integrationtest-classes\failsafe-reports.

<testClassesDirectory>${integrationOutputDirectory}</testClassesDirectory>
<reportsDirectory>${integrationOutputDirectory}/failsafe-reports</reportsDirectory>
<test>**/*.java</test>
<additionalClasspathElements>
<additionalClasspath>${integrationSourceDirectory}/resources</additionalClasspath>
</additionalClasspathElements>


2.6 The 'IT' Profile

The implementation of this is placed in a profile ‘it'https://designbycontract.googlecode.com/svn/trunk/failsafe/pom.xml

2.7 Wrapping Up.

This is a simple solution that can be rolled out to teams even if they are not strong in Maven.By providing the profile, they only need to define their own paths.

2.7 Whats Next.

Check out how to add code coverage metrics using Sonar.

http://johndobie.blogspot.com/2011/06/seperating-test-code-coverage-with.html

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

unit test Integration Apache Maven integration test Directory

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • The 12 Biggest Android App Development Trends in 2023
  • Tech Layoffs [Comic]
  • Using JSON Web Encryption (JWE)
  • Remote Debugging Dangers and Pitfalls

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: