DEV Community

Kashif Soofi
Kashif Soofi

Posted on • Edited on

Integration Test Postgres using GitHub Actions

This is a continuation of an earlier post Integration Testing Postgres Store. In this tutorial I will show you how I setup GitHub Actions to run integration tests when a change is made to the repository.

Prior to this sample, only way to run those integration tests was to start database server, apply migrations and run the tests either using VisualStudio or dotnet command line. This automates running those tests and ensures that tests are successful not only on developer's machine.

Workflow

Name and filters

I started off by naming the workflow and defining which branches and paths to run it for.

name: Integration Test Postgres on: push: branches: [ "main" ] paths: - 'postgres-store-integration-test/**' 
Enter fullscreen mode Exit fullscreen mode

build job

Next step is to define job, we only have a single job for this workflow that is named build. We will be running it on ubuntu-latest and we will set the default directory to where sample project is located, we would not need to set the default directory if the repo contains a single solution.

jobs: build: runs-on: ubuntu-latest defaults: run: working-directory: postgres-store-integration-test 
Enter fullscreen mode Exit fullscreen mode

services

Next is to define the services our tests are dependent on, in this case its a postgres database server. We will leavarage service containers to run postgres container, setting up username, password, database and exposing port so that we can access it on Docker host.

services: postgres: image: postgres:14-alpine env: POSTGRES_USER: postgres POSTGRES_PASSWORD: Password123 POSTGRES_DB: moviesdb options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 
Enter fullscreen mode Exit fullscreen mode

Build solution

Next is to define the steps. I have started with the standard steps defined in Building and testing .NET guide. We checkout code, setup dotnet SDK, restore packages and build the solution in release mode.

steps: - uses: actions/checkout@v3 - name: Setup .NET Core SDK uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0.x - name: Install dependencies run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore 
Enter fullscreen mode Exit fullscreen mode

Apply Migrations

Before we can run our integration tests, we need to apply database migrations so that database has all the necessary tables our code and tests are dependent on. We already have a Dockerfile to build a container that can run migrations, so I have added a step to build that container and a step to apply those migrations to database running as a container under services.

Please note the connection string, its connecting migrations container to host where our database service is accessible on default port.

steps: ... - name: Build migratinos Docker image run: docker build --file ./db/Dockerfile -t movies.db.migrations ./db - name: Run migrations run: docker run --add-host=host.docker.internal:host-gateway movies.db.migrations "Host=host.docker.internal;Username=postgres;Password=Password123;Database=moviesdb;Integrated Security=false; 
Enter fullscreen mode Exit fullscreen mode

Run integration tests

Final step is to execute integration tests. This is done with following step

steps: ... - name: Run integration tests run: dotnet test --configuration Release --no-restore --no-build --verbosity normal 
Enter fullscreen mode Exit fullscreen mode

Please note we have the connection string hardcoded in DatabaseFixture, code can be updated to be read that from environment variable to make it configurable.

Complete Workflow

Here is the complete workflow, also available at GitHub.

name: Integration Test Postgres on: push: branches: [ "main" ] paths: - 'postgres-store-integration-test/**' jobs: build: runs-on: ubuntu-latest defaults: run: working-directory: postgres-store-integration-test services: postgres: image: postgres:14-alpine env: POSTGRES_USER: postgres POSTGRES_PASSWORD: Password123 POSTGRES_DB: moviesdb options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 steps: - uses: actions/checkout@v3 - name: Setup .NET Core SDK uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0.x - name: Install dependencies run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore - name: Build migratinos Docker image run: docker build --file ./db/Dockerfile -t movies.db.migrations ./db - name: Run migrations run: docker run --add-host=host.docker.internal:host-gateway movies.db.migrations "Host=host.docker.internal;Username=postgres;Password=Password123;Database=moviesdb;Integrated Security=false;" - name: Run integration tests run: dotnet test --configuration Release --no-restore --no-build --verbosity normal 
Enter fullscreen mode Exit fullscreen mode

Source

Source code for the demo application is hosted on GitHub in blog-code-samples repository, source for this workflow is in integration-test-postgres.yml.

References

In no particular order

Top comments (0)