Running Angular Unit Tests in Docker Container

Running Angular Unit Tests in Docker Container

Hi there, today we’re going to check out how to let our Angular Tests run in a docker container.

Interested in the final solution? It’s here.

The default configuration of Angular requires a Chrome browser to be installed on your machine. The browser is launched every time you execute tests locally. That might not work for some Continuous Integration Environment, Build Server as it might not have any browsers installed. Therefore we would need to run a browser in headless mode inside the docker container.

If you can run docker containers in your Build Pipeline, it should be possible to adjust Angular project setup to run the tests there. Let us see how a simple Proof of Concept might look like.

If you don’t have Angular CLI and docker installed yet, please do so.

Create New Application

To focus on the technic let’s just create a new folder ng-test-docker and execute ng new app in a command line. You’ll be asked regarding the routing module and stylesheet format – just select anything; I did opt out of the routing, as for stylesheet format – SCSS was my choice.

After that, angular creates a template app along with default tests.

You can check how the tests run by calling cd ./app and then ng test. You’ll notice that a browser starts and executes in total 3 tests:

AppComponent
should render title
should have as title 'app'
should create the app

Change Tests Configuration

As you see, the Browser starting with tests is what we try to solve now. Before we proceed with the docker, let’s make some adjustments in our tests’ configuration so that the tests run in headless mode, without Graphical User Interface (GUI).

In the file app/karma.conf.js, add a new custom launcher configuration just right after config.set({

    customLaunchers: {
      ChromeHeadless: {
        base: 'Chrome',
        flags: [
          '--no-sandbox',
          '--disable-gpu',
          '--headless',
          '--remote-debugging-port=9222'
        ]
      }
    },

The following setting in this file browsers: ['ChromeHeadless'], should be set to ChromeHeadless – newly described launcher.

And the last thing: singleRun: true, tells karma to launch test in one single run within one start of the browser.

What we have just done is sufficient not to see the browser when calling ng test. Try running it in the ./app folder to check it out.

Create Dockerfile

With Docker, we have many choices on how to address the issue. But let us do some simple, minimalistic configuration.

That minimalistic configuration would have Alpine Linux as a base and Chromium browser inside.

Let’s create a new file frontend.Dockerfile in the root ng-test-docker before app folder.

FROM node:current-alpine3.12
RUN apk add chromium
WORKDIR /app

ENV CHROME_BIN=/usr/bin/chromium-browser

COPY ./app/. ./
RUN npm install
RUN npm run test

This Dockerfile is easy to run like this docker build -f frontend.Dockerfile -t ng-test-docker .

After running the Docker container tests, you would get a console output similar to the one below.

...
HeadlessChrome 86.0.4240 (Linux 0.0.0): Executed 3 of 3 SUCCESS (0.887 secs / 0.746 secs)
TOTAL: 3 SUCCESS
TOTAL: 3 SUCCESS
Removing intermediate container fedf7a5967b7
 ---> 8aa93030300d
Successfully built 8aa93030300d
Successfully tagged ng-test-docker:latest

What the Dockerfile basically does is simple:

  1. Take npm Alpine Linux base image.
  2. Install Chromium browser on top of it.
  3. Specify our working directory /app inside the image.
  4. Define an environment variable CHROME_BIN with the location to chromium. This will be needed by Angular later on.
  5. Copy all local files from ./app/ into the working directory of the Docker image.
  6. Run npm install to install all dependencies.
  7. Run the tests.

That is it; now you have your tests running in a Docker container.

To get a complete source version of this example, just follow this way.

If you plan to have some pictures or other assets in your tests, please consider adding this setting into karma.conf.js.

I hope it helps you in doing something nice.

If you have any suggestions, questions, or opinions, just let me know; I’d be happy to hear back. You can reach me out over the social links below.

May your tests always be green.

Take care,
Ievgen