GitLab: Using a PostgreSQL Database Inside your Testing Pipeline

Many applications are automatically tested on each commit inside a GitLab pipeline. If your application relies on a database such as PostgreSQL, it can be tempting to use an in-memory database such as H2 for tests because it is easier to set up and destroy for each execution of your test suite. While this works for simple applications, it is no longer possible once you rely on vendor-specific SQL features (e.g., usage of column types not available in H2).

In this article, I will demonstrate how you can easily set up PostgreSQL in your GitLab pipeline for Spring Boot applications and improve the quality of your unit and integration tests.

Setting Up PostgreSQL in your .gitlab-ci.yml

Gitlab allows the definition of (network accessible) services that are linked to your application containers when the pipeline is executed. Databases are perfect examples of such services. They are defined in the services: section of your .gitlab-ci.yml file:

services:
  - postgres:13-alpine
The postgres service exists independently of the individual pipeline jobs and can be accessed by all of the jobs via network calls.

Services defined this way are automatically available for all your jobs (you can however also define them on a per-job basis). The service can be accessed by its image name (where everything after the : is stripped): postgres.

The database credentials can be defined using the variables: section:

variables:
  POSTGRES_DB: my_database
  POSTGRES_USER: bernhard
  POSTGRES_PASSWORD: "somepassword"
  POSTGRES_HOST_AUTH_METHOD: trust

Configure your application to use the database

You can connect to the database the same way you would connect to any database on a network. In Spring Boot, it is best practice to define the database connection via your application.properties file or directly via environment variables.

For the above credentials, your configuration would look like this:

spring.datasource.driverClassName=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://postgres:5432/my_database
spring.datasource.username=bernhard
spring.datasource.password=somepassword

As stated above, the host name of your database service is postgres, which is why your jdbc connection string connects to postgres:5432 (which is the default port of PostgreSQL).

Summary

Yes, it is really that easy to use a real PostgreSQL database in your unit and integration test pipeline. By matching the exact database version that is also used in production, you can avoid many subtle errors that may not be apparent when relying on an in-memory database.

Let me know if you have any questions or whether you found this useful in the comments section.

Bernhard Knasmüller on Software Development