Baeldung Pro – Ops – NPI EA (cat = Baeldung on Ops)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

Testing is crucial to software development, ensuring the code works as expected before it reaches production. While continuous integration (CI) platforms like GitLab CI are typically used to automate testing in a remote server environment, we might sometimes want to run these tests locally to speed up development and debugging processes.

In this tutorial, we’ll learn how to use GitLab CI to run tests locally.

2. Using gitlab-ci-local

As the name indicates, the gitlab-ci-local utility enables us to run GitLab CI jobs and pipelines locally. Let’s explore this to run our tests locally.

2.1. Setup

Let’s start by looking at a sample unit_test job in the .gitlab-ci.yml CI/CD configuration file for our demo project:

$ cat demo/.gitlab-ci.yml
unit_test:
  image: python:latest
  script:
    - echo "running tests ..."

Our job is intentionally simple, and the script section can include the necessary project-specific commands to run the tests. We’ll reuse this configuration file in the remaining sections as well.

Now, let’s follow the install guide to install the gitlab-ci-local on our machine. For example, to install it on macOS, we can execute the brew installation instruction:

$ brew install gitlab-ci-local

Further, let’s verify the installation by inspecting the version information:

$ gitlab-ci-local --version
4.56.2

It looks good to use.

2.2. Running Tests

We can go to our demo project directory and use gitlab-ci-local to see the list of jobs configured in .gitlab-ci.yml configuration file:

$ gitlab-ci-local --list
parsing and downloads finished in 108 ms.
json schema validated in 80 ms
name       description  stage   when        allow_failure  needs
unit_test               test    on_success  false

As expected, we can see the unit_test job listed in the output.

Now, let’s run the unit_test job locally and check its results:

$ gitlab-ci-local unit_test
parsing and downloads finished in 99 ms.
json schema validated in 81 ms
unit_test starting python:latest (test)
unit_test copied to docker volumes in 395 ms
unit_test $ echo "running tests ..."
unit_test > running tests ...
unit_test finished in 778 ms

 PASS  unit_test

Fantastic! It looks like we nailed this one. We can see that the unit_test job executed successfully.

3. Using GitLab Emulator

GitLab Emulator is another interesting tool for locally emulating a GitLab CI/CD job. Let’s use it to solve our use case.

3.1. Installing gle

Firstly, the gle utility isn’t preinstalled, so we must install it:

$ git clone https://gitlab.com/cunity/gitlab-emulator.git && cd gitlab-emulator
$ ./install-venv.sh
$ source ~/.gle/venv/bin/activate

We’ve installed the utility using its source code.

Now, let’s verify the installation by using the –version option of the gle command:

$ gle --version
16.3.2

It looks like we’ve got this one right.

3.2. Running Tests

We can now change the working directory to the demo project and use gle to list available jobs:

$ cd demo && gle --list
unit_test

As our .gitlab-ci.yml configuration file has only a single job, we can see it’s listed correctly.

Next, let’s run the unit_test job and see it in action:

$ gle unit_test
>>> execute unit_test:
2025-01-20 11:02:08,003 gitlab-emulator  allocating runner
2025-01-20 11:02:08,003 gitlab-emulator  running docker job unit_test
2025-01-20 11:02:08,003 gitlab-emulator  runner = docker-runner default-docker
2025-01-20 11:02:08,003 gitlab-emulator  pulling docker image python:latest
Pulling python:latest...
2025-01-20 11:02:13,064 gitlab-emulator  launching image python:latest as container gle-docker-52712-ead51fb ..
2025-01-20 11:02:13,337 gitlab-emulator  started container 49375beb611a029ffd524b2fbc4333e903495598f0c09adef77cb9e0f4f7da0c
2025-01-20 11:02:13,337 gitlab-emulator  attempting to set git safe.directory..
2025-01-20 11:02:13,337 gitlab-emulator  running command -v git 2>&1 >/dev/null && git config --system safe.directory '/Users/tavasthi/baeldung-gitlab/demo'
2025-01-20 11:02:13,340 gitlab-emulator  Copying /var/folders/lf/j9rwr9p90bjf8_5cjchpgb380000gn/T/generated-gitlab-script.sh to container as /tmp/generated-gitlab-script.sh ..
2025-01-20 11:02:13,381 gitlab-emulator  checking container for bash
2025-01-20 11:02:13,433 gitlab-emulator  bash found
2025-01-20 11:02:13,517 gitlab-emulator  Copying /var/folders/lf/j9rwr9p90bjf8_5cjchpgb380000gn/T/generated-gitlab-script.sh to container as /tmp/generated-gitlab-script.sh ..
running tests ...
gle-docker-52712-ead51fb
Build complete!

Great! We can see from the debug logs that our job was executed successfully.

4. Using GitLab Runner

In this section, let’s learn how to use the gitlab-runner tool to run tests locally.

4.1. Setup

Let’s install version 13.3.0 of the gitlab-runner tool. We can follow the install guide for our operating system and replace the latest keyword with v13.3.0 in the download path:

$ sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/v13.3.0/binaries/gitlab-runner-darwin-amd64

It’s important to note that our use case involves running a specific job locally through GitLab Runner. Since newer versions don’t support gitlab-runner exec command, we must rely on an older version.

4.2. Running Tests

First, we must verify the version of the installed gitlab-runner utility:

$ gitlab-runner --version | grep Version
Version:      13.3.0

We plan to use the exec sub-command supported by version 13.3.0. So, we’re good to go.

Now, we can run our unit_test job locally:

$ gitlab-runner exec docker unit_test
Runtime platform                                    arch=amd64 os=darwin pid=21248 revision=86ad88ea version=13.3.0
Running with gitlab-runner 13.3.0 (86ad88ea)
Preparing the "docker" executor
Using Docker executor with image python:latest ...
Authenticating with credentials from /Users/tavasthi/.docker/config.json
Pulling docker image python:latest ...
Using docker image sha256:3eb60a97864f318f1522587ba7e097a4f39d715c8f8f5acb8933b30c711965a0 for python:latest ...
Preparing environment
Running on runner--project-0-concurrent-0 via Tapans-MacBook-Air.local...
Getting source from Git repository
Fetching changes...
Initialized empty Git repository in /builds/project-0/.git/
Created fresh repository.
Checking out 2871d3b2 as main...

Skipping Git submodules setup
Executing "step_script" stage of the job script
$ echo "running tests ..."
running tests ...
Job succeeded

We can see that gitlab-runner downloaded the necessary Docker image and executed the unit_test job locally. Further, our job was executed successfully.

5. Conclusion

In this article, we learned how to use GitLab CI to run tests locally. Further, we explored different utilities such as GitLab CI Local, GitLab Emulator, and GitLab Runner to solve this use case.