Skip to main content

Testcontainers is the preferred choice for writing integration tests using real dependencies as Docker containers. In this article, we are going to explore:

  • How to run Testcontainers-based tests on GitHub Actions CI
  • How to configure GitHub Actions to use Testcontainers Cloud
  • Explore the Testcontainers usage patterns on Testcontainers Cloud dashboard

Let us see how we can run Testcontainers based integration tests in a Spring Boot application using GitHub Actions. For this article, we are going to use testcontainers-showcase application to demonstrate how to run tests using GitHub Actions.

If you have Docker installed on your local machine then you can clone the repository and run tests locally as follows:

git clone https://github.com/testcontainers/testcontainers-showcase.git
cd testcontainers-showcase
./mvnw verify

Configuring GitHub Actions CI

Let’s add the GitHub Actions configuration file .github/workflows/ci.yml with the following configuration:

name: CI Build

on:
  push:
    branches:
      - '**'
jobs:
  build:
    name: Maven Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Java 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'temurin'
          cache: 'maven'

      - name: Build with Maven
        run: ./mvnw verify

Testcontainers libraries require a valid Docker environment in order to run the tests. As GitHub Actions by default provides a Docker environment, we don’t have to configure anything specifically to provide a valid Docker environment.

Now if you add the .github/workflows/ci.yml file and commit and push the changes then the GitHub Actions CI Pipeline will be triggered automatically and your tests should run successfully.

Configuring GitHub Actions to use Testcontainers Cloud

While you are able to run your Testcontainers-based tests on GitHub Actions using the default Docker environment, you can speed up the execution of tests by offloading the burden of running the containers required for your tests to Testcontainers Cloud.

Go to Testcontainers Cloud and get a Free account if you don’t have one already. Once logged into Testcontainers Cloud, you can follow the installation instructions in the webapp to create a Service Token and configure the token as a GitHub Secret with name TC_CLOUD_TOKEN.

Now, let’s update the .github/workflows/ci.yml file to configure the Testcontainers Cloud Agent as follows:

name: CI Build

on:
  push:
    branches:
      - '**'
jobs:
  build:
    name: Maven Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Java 17
        uses: actions/setup-java@v3
        with:
          java-version: 17
          distribution: 'temurin'
          cache: 'maven'

      - name: Setup Testcontainers Cloud Client
        uses: atomicjar/testcontainers-cloud-setup-action@v1
        with:
          token: ${{ secrets.TC_CLOUD_TOKEN }}

      - name: Build with Maven
        run: ./mvnw verify

We have added a step to start the Testcontainers Cloud agent by using atomicjar/testcontainers-cloud-setup-action@v1. We have passed the token as an argument with the Service Account Token value fetched from GitHub Actions Secrets.

Now if you commit and push the changes then you should notice the following log statements indicating the tests are running using Testcontainers Cloud and also you should see the tests are executed quicker than with the default Docker environment.

[testcontainers-lifecycle-0] INFO org.testcontainers.DockerClientFactory - Connected to docker:
 Server Version: 78+testcontainerscloud
 API Version: 1.43
 Operating System: Ubuntu 22.04.2 LTS
 Total Memory: 15537 MB

Running Tests in parallel with Testcontainers Cloud turbo mode

Testcontainers Cloud turbo mode allows you to run tests in parallel so that each test process receives its own cloud environment making tests parallelization scalable.

You can find more information on Testcontainers Cloud turbo mode in the knowledge base with the rest of the docs about it.

We can also turn-on the turbo mode in CI by passing the TC_CLOUD_CONCURRENCY environment variable as follows:

- name: Setup Testcontainers Cloud Client
  uses: atomicjar/testcontainers-cloud-setup-action@v1
  with:
    token: ${{ secrets.TC_CLOUD_TOKEN }}
    env:
      TC_CLOUD_CONCURRENCY: 2

Once the turbo mode is enabled, we can leverage our build tools test parallelization features to run tests in parallel. We can configure Maven surefire-plugin to run tests using 4 forks as follows:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.1.2</version>
    <configuration>
          <parallel>classes</parallel>
          <forkCount>4</forkCount>
    </configuration>
</plugin>

With the turbo mode and test parallelization, you should notice that the tests are executed even quicker. Note that we’re still conveniently using the default GitHub action worker even when parallelizing the tests, because the container dependencies for our app are handled by the Testcontainers Cloud.

Testcontainers Cloud provides a dashboard where you explore your test executions.

Test execution insights from Testcontainers Cloud

Once you logged into Testcontainers Cloud, you will be redirected to the dashboard page where you can see the Testcontainers Activity and Top 10 images in the last 30 days as follows:

You can also select a specific user or service account and see the activity of that particular account as well.

We can see the Testcontainers Cloud test execution sessions as follows:

You might be using a specific version of services like databases, message brokers etc and you would like to run your tests with the containers of the same versions. From the dashboard you can get an overview of the containers running and you can easily catch if the tests are running with unexpected versions of containers.

In the above screenshot, you can see the tests are running using different versions(15-alpine, 15.2-alpine, 15.3-alpine) of postgresql containers which is most likely not what you wanted. The dashboard can help you to catch these kinds of issues as well.

You can also see how long each container was running.

Looking at this view, you can think about if it is ok to run multiple containers for separate test classes or you might want to leverage singleton containers pattern to use the same set of containers for multiple test classes.

You can learn more about Testcontainers lifecycle management using JUnit 5 from this guide. You can also watch the video version of Testcontainers container lifecycle management using JUnit 5.

Conclusion

We have learned how to configure GitHub Actions to run Testcontainers-based tests and how to leverage Testcontainers Cloud to scale up the container workloads. We have explored how we can use turbo mode and run the tests even more quickly using test parallelization technique. Finally, we have seen how we can gain Testcontainers Cloud usage insights using the Testcontainers Cloud dashboard.

Want to experience the awesomeness of Testcontainers Cloud by yourself? No need to wait, go to https://testcontainers.com/cloud/ and get started by creating a Free account.

Siva Katamreddy

Siva Katamreddy is a Developer Advocate at AtomicJar sharing the awesomeness of Testcontainers and helping the developers to build and release their software with confidence. He is a published author, and has written multiple books on Java technologies.