Test as you run (Part 4) – Production like Integration Test

In the previous part of our series about test-driven development of microservices we had a look at how to use Gradle and Docker to debug a service with a database dependency in place and we created a Cassandra Docker image that contains some testdata. This is the fourth part.

The first part can be found here.

Now please checkout the next step:

git checkout step5

Starting with the root build.gradle we see that the testsets-plugin was added to the classpath:

classpath 'org.unbroken-dome.gradle-plugins:gradle-testsets-plugin:1.4.2'

This plugin allows us to easily define additional test source sets with test-tasks. Looking into the service.gradle we see some new lines:

testSets { integrationTest }
integrationTest.mustRunAfter(test)
build.dependsOn(integrationTest)

A new testSet named “integrationTest” is defined using the testSets plugin and the build task got a new dependency to the integrationTest Task. Additionally we define an order between the test- and integrationTest-task to prevent the integration tests to be executed before the unit tests passed (fail early).

With these settings we’re free to add integration tests to every service by putting our tests into the source-set /src/integrationTest/java. To run the tests we execute:

./gradlew integrationTest

Due to the dependency from build to integrationTest we can also execute:

./gradlew build

to run compilation followed by the unit tests followed by the integration tests and finalized by building a binary.

The UserService project contains a source set “integrationTest” in which the testclass “UserServiceIntegrationTest” is located.


The test looks a lot like the server tests we already know. By having a closer look we see that the TestExecutionListener for setting up the EmbeddedCassandra is missing. Futhermore the test “shouldGetKnownUsers” checks that users can be requested without adding them beforehand. These users are the ones we just put into our newly created
testdata image.

Let’s have a look into the UserService build.gradle


Most looks familiar so let’s focus on the changes:

A dockerCompose configuration named “integrationTestWithCassandra” was added in lines 29–33. The corresponding docker-compose file “docker-compose-integrationtest.yml” has the following content:

version: '3'
services:
  cassandra:
      image: usercassandra:latest
      ports:
          - 9042

It’s basically the same as the already known docker-compose file for debugging with the small difference that the Cassandra image is the testdata image we just created.

Looking into lines 31–49 of the build.gradle file above we see that much like the debug setup the integrationTest task is bound to the a dockerCompose-task which will create a cassandra-container and set up the environment for the UserService before the tests are executed.

That’s all we need to create a docker-based integration-test.

Let’s test a system

We’ve seen how we can test and debug our services with third party dependencies in place. Let’s have a look how to create docker images for our services and use these images for a depending services integration tests in part 5.

About Olaf Gunkel

Olaf is a fullstack software craftsman and the head of the web-engineering department. He deeply cares about software craftsmanship, code quality and agility. He publishes articles and gives talks about softwarecraftsmanship, microservices, test driven development and parallelism on a regular basis.