Thomas Sundberg

April 29, 2015

Separating acceptance tests

This post has been migrated to

It is very convenient to run the unit tests separated from other, slower, tests. There are different ways to do this. One way is to have a separate module for the acceptance tests.

Separating the modules is acceptable in some cases. It is not acceptable in others. There is a simple way to separate the source code for the acceptance tests while keeping the it in the same project if you use Gradle. Separate the tests with different source sets.

Separation on source sets means that you will keep all the acceptance tests in another directory structure than the unit tests. If you use the usual separation of production code and test code, then all you want to do is to add a new source set that contains the acceptance tests.

The regular source code structure used by Gradle is a src directory and then a main directory for the production code and test for the test code. This is a good separation. We will add another directory under src called acceptanceTest that will contain the source code used for acceptance testing the system.

The magic is in the Gradle build script. When you apply the java plugin, Gradle defines sourceSets. It will read src/main for the production code and src/test for the test code.

To be able to add acceptance tests in the same module you need to add an additional source set and call it something describing.

This my exact strategy in the example below:


plugins { id 'java' } sourceSets { acceptanceTest { java.srcDir file('src/acceptanceTest/java') resources.srcDir file('src/acceptanceTest/resources') compileClasspath += main.output + test.output + configurations.testRuntime runtimeClasspath += output + compileClasspath } } task acceptanceTest(type: Test) { description = 'Runs the acceptance tests' group = 'verification' testClassesDir = sourceSets.acceptanceTest.output.classesDir classpath = sourceSets.acceptanceTest.runtimeClasspath reports.junitXml.destination = '$buildDir/acceptance-test-results' reports.html.destination = '$buildDir/reports/acceptanceTest' dependsOn(test) } check { dependsOn(acceptanceTest) }

Notice that you don’t replace the current sourceSets definition, you enhance it.

I want to have access to the output from the production and test code for the acceptance tests. The way to get that access is to sum the output and place it in my compile classpath compileClasspath += main.output + test.output + configurations.testRuntime

The runtime class path for the acceptance tests should be the same as the compile class path and the result of the compilation of the acceptance tests.

The next thing is to add a specific acceptance test task so I can execute my acceptance test separately.

The description of the task is easy, write whatever you want here. Make sure that is descriptive though.

After that I want to add my task to a group that it should belong to. The group should be set to verification. This is strictly not necessary, but the task will be grouped properly when you execute gradle tasks.

Defining the task as a test task will give me access to the properties testClassesDir and classpath. To connect them to my acceptance test stuff, I set them to sourceSets.sourceSets.output.output and sourceSets.acceptanceTest.runtimeClasspath.

Separating the execution reports are nice. I do that by setting reports.junitXml.destination and reports.html.destination to something different compared to the unit tests. This allows me to get specific reports for the acceptance tests.

The last thing I want to do is to include the acceptance tests in the task chain at a reasonable place. I want the the acceptance tests to be executed after the unit tests. The unit tests are fast so executing them before the slower acceptance tests is reasonable. The solution is to add a dependency from the acceptanceTest to the test task. I want the acceptanceTest to be executed when check is executed so I add a dependency from the check task to the acceptanceTest task. This will give the desired execution order and I will always execute the acceptance tests when check is executed.

That is all you have to do to separate the acceptance test from the unit tests and get a specific task that will execute the acceptance tests.

The result is that you now have the possibility to organize your code like this:

|-- build.gradle
`-- src
    |-- acceptanceTest
    |   |-- java
    |   `-- resources
    |-- main
    |   |-- java
    |   `-- resources
    `-- test
        |-- java
        `-- resources


I would like to thank Malin Ekholm, Johan Helmfrid and Alexandru Bolboaca for proof reading.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at

%d bloggers like this: