JHipster With Testcontainers

As you might noticed, I really like JHipster and Testcontainers. Right now, when you create a JHipster application and choose e.g. PostgreSQL as your database the integration tests (annotated with @SpringBootTest) are still using an H2 in-memory database. This helps to make the first time experience for our users quite smooth as they don’t need docker for example. When you are planning to use some specific functions of your choosen database H2 is not the right choise anymore. In fact JHipster uses Testcontainers already for non SQL databases like cassandra.

This posts shows how you can use Testcontainers for spring boot integration tests such that your test can use your production database of choice.

Add Testcontainers Dependency

First you must add the correct database module to your project. In this case I used Gradle:

testImplementation "com.h2database:h2" 1
testImplementation "org.testcontainers:postgresql:1.11.2" 2
  1. Remove the not needed h2 dependency
  2. Add the correct database module

Changing Properties

The easiest way to tell spring boot to use Testcontainers to setup a database is using a special jdbc url schema.

You need to modify src/test/resources/config/application.yml like this

spring:
  application:
    name: jhtc
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:tc:postgresql:11.2://localhost:5432/jhtc 1
    name:
    username:
    password:
    hikari:
      auto-commit: false
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver 2
  jpa:
    database-platform: io.github.jhipster.domain.util.FixedPostgreSQL95Dialect 3
    database: POSTGRESQL 4
  1. This tells Testcontainers to start a PostgreSQL container
  2. Use a special database driver which can connect to the random port of the container
  3. Use the same values from src/main/resources/config/application-prod.yml
  4. Use the same values from src/main/resources/config/application-prod.yml

If you now run the integration test via ./gradlew integrationTest there will a PostgreSQL container started. The first run may be a bit slow, as the container must be downloaded first. If you want to make sure everything is setup correctly you can set showStandardStreams = true for the integration tests to see log output.

If everything is correct you should see this output

If everything is correct you should see this output

Using a custom datasource configuration

If you want to use H2 and Testcontainers in parallel you can create a custom datasource https://github.com/intesys/generator-jhipster-testcontainers{configuration which is activated via a special spring boot profile]. This is in paticular useful in case there is no testcontainers module for your database. You may use the existing testcontainers module for that.

CI/CD

As the integration tests now require a docker environment you may need to adapt your CI/CD configuration, especially when your build are executed inside a docker container (e.g. travis, gitlab.com).

Let’s assume you have created a .gitlab-ci.yml via jhipster ci-cd. The recommended way to use Testcontainers with gitlab ci (on gitlab.com) is to include the Docker-In-Docker service (docker:dind).

gradle-integration-test:
    stage: test
    variables:
        DOCKER_DRIVER: overlay2 1
        DOCKER_HOST: "tcp://docker:2375" 2
    services:
        - docker:dind 3
    script:
        - ./gradlew integrationTest -PnodeInstall --no-daemon
    artifacts:
        reports:
            junit: build/test-results/integrationTest/TEST-*.xml
        paths:
            - build/test-results/
            - build/jacoco/
        expire_in: 1 day
  1. Improve performance with overlayfs.
  2. Instruct Testcontainers to use the daemon of DinD.
  3. Require dind service to be available
Successful Gitlab Pipeline Run

Successful Gitlab Pipeline Run

The source code of the complete project is available on gitlab.