2022-10-23 02:00:00+00:00

Running continuous integration (CI) tests for microservice applications requires setting up real environment dependencies. If a microservice test suite requires access to a database (like PostgreSQL) or cache servers (like Redis), mocking these dependencies inside unit tests can mask query bugs. A comprehensive pipeline spins up real companion services in parallel containers using GitLab service definitions, executing integration tests against active dependencies.

By structuring GitLab CI stages with multi-container services, we can execute database integration tests reliably on every code push.


1. Structuring the GitLab CI Container Services

We write a .gitlab-ci.yml file configuring runners to launch PostgreSQL and Redis containers side-by-side with our test suite:

# .gitlab-ci.yml
stages:
  - test

run_integration_tests:
  stage: test
  image: python:3.9
  
  # Register service dependencies
  services:
    - name: postgres:13
      alias: db-host
    - name: redis:6-alpine
      alias: cache-host
      
  variables:
    POSTGRES_DB: "test_db"
    POSTGRES_USER: "test_user"
    POSTGRES_PASSWORD: "secret_password"
    DATABASE_URL: "postgresql://test_user:secret_password@db-host:5432/test_db"
    REDIS_URL: "redis://cache-host:6379/0"
    
  before_script:
    - apt-get update && apt-get install -y libpq-dev
    - pip install -r requirements.txt
    
  script:
    # Run tests using the environment variable connections
    - pytest tests/integration/

2. Caching Virtual Environments to Speed Up Runs

To reduce run durations, we define cache keys targeting local python packages (like pip and virtualenvs). This avoids re-downloading packages on subsequent runs, decreasing build queue execution times.