Need to run automated tests against your Java app?

In order to run automated integration or functional tests, you need to spin up your application, together with all it's dependencies - that might include a database, a cache, etc.

You may still be doing this the old fashioned way: start MySQL separately, start Redis, then your application, and then run your tests. And you probably have these instructions documented in a team Wiki.

Perhaps you're doing it better: you have a few Dockerfiles, together with a Docker Compose file to spin up the application, and then you run your tests against the Dockerized version. Again, your Wiki probably tells your team how to setup Docker, build images, run Docker Compose, and your tests.

This is a sample for the open source Sandbox tool

Run a workflow to automate your tests

There's an even simpler way still to automate it all. With Docker-based workflows, you can create a list of steps that automate the entire process: run third-party services, run your application, and then run your tests. And your team can execute the workflow immediately, right after checking out your Git repository, using Sandbox.

A workflow that tests the Spring Pet Clinic

The workflows that Sandbox runs are just YAML files. Here's one that automates what we've described so far for the Spring Pet Clinic: it runs MySQL, and then runs integration tests. Let's take a look:

Workflows define a sequence of steps. This one begins with a service step, which starts MySQL, using an official MySQL Docker image.

steps:
  - service:
      image: mysql:5.7.20

Normally all project source files are added to images created for steps. Here we request that source files are omitted for the MySQL service. In addition, we use environment variables to set the name of the initial MySQL database, and the root password.

      source:
        omit: true
      environment:
       - name: MYSQL_ROOT_PASSWORD
         value: pass
       - name: MYSQL_DATABASE
         value: test

Here, the MySQL port is exposed "internally" to other workflow steps. It is exposed under the name mysql, which allows other step containers to resolve that name using DNS (our app is going to use the JDBC connection string jdbc:mysql://mysql/test).

      ports:
       - name: mysql
         container: 3306
         internal: 3306

We tell Sandbox to check that TCP port 3306 (the MySQL port) can be reached before considering the service ready. It will wait for the service to be ready before continuing.

      readiness:
        tcp:
          port: 3306

The second step builds and runs the app, and runs integration tests. It uses an official Maven Docker image to run a Maven goal.

  - run:
      image: maven:3.5.2-jdk-8

The script is run within the step's Docker container - here you can see it runs Maven goals to build and run tests.

      script: |-
        cd /app
        mvn clean install test

Mounting the .m2 folder within the project at /root/.m2 will mean that the local Maven repository can be re-used on subsequent runs of the workflow, without having to re-create it from scratch every time.

      volumes:
        - mountPath: /root/.m2
          hostPath: ./.m2

Run your tests immediately after checkout, no setup required!

The workflow above automates the entire process. And it can be run immediately after checkout if you commit both your workflow and Sandbox into your Git repo (Sandbox is tiny - under 200KB just so you can do this). No other software installation or setup is required! No databases, no caches, no Docker! And no long Wiki instructions required!

Try it yourself

We setup a sample repo at https://github.com/stackfoundation/sbox-java-tests so you can try how easy it can be yourself. Just clone and run the workflow using Sandbox, which is included in the repo!

git clone https://github.com/stackfoundation/sbox-java-tests
cd sbox-java-tests
./sbox run integration-tests