Running Java Unit and Integration Tests Separately

Eclipse and Maven are not designed from the ground up to run automated integration tests separately from unit tests. This is a problem because integration tests typically take longer to run, so when coding, especially if doing test-driven development, there is the need to frequently run just the unit test suite from Eclipse.

Maven by its default convention expects all tests in a single test source directory (src/test) that are all run as a single group. Maven does support integration tests by the inclusion of the Failsafe plugin using the convention that such tests be named "**/*" or "**/IT*.java" and are located in the test source directory along with the unit tests.

This causes a problem within Eclipse, whose primitive JUnit test runner only allows running multiple tests based on a single project, package, or source folder. So there is no way to select unit tests and exclude integration tests within Eclipse based on Maven's conventions.

There are several options for resolving this difficulty which basically all involve changing the configuration of the tests. I recently set up a new Java project where I reevaluated these alternatives and discovered a new approach that I am quite happy with compared to the other options. The basic issue I have with changing test configuration is that it essentially imposes extra work on the creation of integration tests.

One common solution is to move all integration tests into a separate source folder (e.g. src/it). Eclipse can then run the desired set of tests based on the source folder. The problem is that you now need three directory trees for each tested package (one for src/main, one for src/test, and one for src/it), and you cannot easily get an overview of the tests for a single class/package due to the tests being split across two source folders.

An alternative solution is to mark each integration test class with a JUnit category and then configuring both the unit and integration run configurations in Eclipse to filter by this category. The problem I have with this is this reflects a redundant piece of information (since each integration test class name already specifies this) which you need to remember to do for each new integration test.

The new approach I found involves using the JUnit Toolbox library to define separate unit and integration test suite classes using a wildcard naming pattern to automatically filter integration tests by their name, just like Maven. Eclipse test runners can then be configured to run these individual test suite classes. The integration tests themselves do not need to be changed. An added benefit of this approach is that you can optionally choose to execute the tests in parallel, resulting in a faster runtime for the overall test suite (and potentially 'free' testing for concurrency issues :) In my simple project I observed the unit test suite runtime cut in half after switching to the parallel test runner.

The steps to using JUnit Toolbox are easy:

  1. Add the library as a dependency to your Maven pom.xml.
  2. Create a test suite class to run only unit tests. The code below is configured to run the tests in parallel: switch the ParallelSuite class to the WildcardPatternSuite class to run sequentially instead.
    import org.junit.runner.RunWith;
    import com.googlecode.junittoolbox.ParallelSuite;
    import com.googlecode.junittoolbox.SuiteClasses;
    public class AllUnitTests {
      // Nothing needed
  3. Create an Eclipse JUnit run configuration that runs as a single test the AllUnitTests class created in the prior step.

A similar test class can be created for running just the integration tests, if desired.

If you find this article helpful, please make a donation.

Leave a Reply

(Not displayed)