GitHub Actions Certification

Continuous Integration with GitHub Actions

Run Unit Testing Job using a Service

Overview

In this guide, you’ll configure a non-production MongoDB instance as a service container in your GitHub Actions workflow. This ensures your unit tests run against an isolated database and keeps production data safe.

Warning

Never point your test suite at a production database. Service containers provide complete isolation for reliable, repeatable testing.

Existing Workflow: unit-testing Job

Here’s the current setup that uses a production MongoDB URI:

on:
  workflow_dispatch:
  push:
    branches:
      - main
      - 'feature/*'

env:
  MONGO_URI: 'mongodb+srv://supercluster.d83jj.mongodb.net/superData'
  MONGO_USERNAME: ${{ vars.MONGO_USERNAME }}
  MONGO_PASSWORD: ${{ secrets.MONGO_PASSWORD }}

jobs:
  unit-testing:
    name: Unit Testing
    runs-on: ${{ matrix.operating_system }}
    strategy:
      matrix:
        nodejs_version: [18, 20]
        operating_system: [ubuntu-latest]
        exclude:
          - nodejs_version: 18
            operating_system: macos-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.nodejs_version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.nodejs_version }}

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

What Are Service Containers?

Service containers run alongside your job on the same virtual network. They’re ideal for databases, caches, message brokers, or any external service your tests require.

The image shows a GitHub documentation page about service containers, explaining their use in connecting databases, web services, and other tools in workflows. The page includes navigation links and a note on using Docker containers with GitHub Actions.

Note

Service containers are automatically networked with your job runner. You can refer to them by their service name (e.g., mongo-db) or localhost with exposed ports.

Pre-built MongoDB Image on Docker Hub

We’ll use a custom MongoDB image tagged non-prod:

The image shows a Docker Hub page displaying details of a Docker image named "siddharth67/mongo-db:non-prod," including its digest, OS/architecture, compressed size, and image layers.

  • Image name: siddharth67/mongo-db:non-prod
  • Exposes port 27017

Updated Workflow with MongoDB Service

Service Definition

Service NameDocker ImagePort Mapping
mongo-dbsiddharth67/mongo-db:non-prod27017:27017

Full Workflow YAML

on:
  workflow_dispatch:
  push:
    branches:
      - main
      - 'feature/*'

env:
  MONGO_URI: 'mongodb+srv://supercluster.d83jj.mongodb.net/superData'
  MONGO_USERNAME: ${{ vars.MONGO_USERNAME }}
  MONGO_PASSWORD: ${{ secrets.MONGO_PASSWORD }}

jobs:
  unit-testing:
    name: Unit Testing
    runs-on: ${{ matrix.operating_system }}
    strategy:
      matrix:
        nodejs_version: [18, 20]
        operating_system: [ubuntu-latest]
        exclude:
          - nodejs_version: 18
            operating_system: macos-latest

    services:
      mongo-db:
        image: siddharth67/mongo-db:non-prod
        ports:
          - 27017:27017

    env:
      MONGO_URI: 'mongodb://localhost:27017/superData'
      MONGO_USERNAME: non-prod-user
      MONGO_PASSWORD: non-prod-password

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.nodejs_version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.nodejs_version }}

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

Workflow Execution and Logs

When triggered, GitHub Actions creates a private Docker network, pulls the MongoDB image, and starts the service container:

Create local container network
/usr/bin/docker network create --label github_network_...
Pulling docker image siddharth67/mongo-db:non-prod
Starting service container mongo-db
/usr/bin/docker port <container_id> 27017/tcp -> 0.0.0.0:27017

The image shows a GitHub Actions interface running a workflow for unit testing on Ubuntu, displaying job setup and log details.

Once healthy, the test steps connect using:

Run npm test
shell: /usr/bin/bash -e {0}
env:
  MONGO_URI: mongodb://localhost:27017/superData
  MONGO_USERNAME: non-prod-user
  MONGO_PASSWORD: non-prod-password
Solar [email protected] test
mocha app-test.js --timeout 10000 --reporter mocha-junit-reporter --exit
Server successfully running on port - 3000

The image shows a GitHub Actions workflow interface with a "modified mongo uri" workflow in progress, displaying unit testing, code coverage, and containerization steps.

Next Steps

  • Extend this pattern to other tools: PostgreSQL, Redis, Elasticsearch, and more.
  • Parameterize image tags or use official Docker Hub images for broader compatibility.
  • Integrate code coverage or linting services in additional jobs.

Watch Video

Watch video content

Previous
What are Service Containers