Angular 1 TDD – Containerize me

In this blogpost, I will explain how to run unit tests for an Angular application in a Docker container.

Prerequisites

This blogpost assumes the following has been installed on your machine.

  • Docker CE for Windows (http://dockr.ly/2mnfX7M)
  • An Angular application with unit tests run with Karma (I’ll use the Angular TDD application from previous posts)

Result

The following will be in place at the end of this post:

  • A docker container and image
  • Two different machines with Docker CE installed
  • Running unit tests on these two different machines, without the need of additional installed software

Containerization

If we would install Node JS, gulp, run npm install and run gulp test on a local machine Karma will start and run the tests. Although the steps that are needed are minimal, we could do better.
The goal is to:

  • Run the tests on any machine/OS with the minimal amount of effort.
  • Minimize the footprint of installed software.
  • Avoid the WOMM (works on my machine) syndrome.

I.e.: we would like to keep it as lightweight and portable as possible.
Docker provides us the means to realize this, by creating containers.

Installing and configuring Docker

Docker CE can be installed from http://dockr.ly/2mnfX7M.

After installation, switch to Linux containers:

If you stay on Windows containers you’ll get the following message when you pull the official node image from the docker hub (described in the next section):

Unfortunately, it is not described clearly on which OS the official Node JS image is built. You’ll need to search in the Dockerfile to find this.

Dockerizing the TDD app

In the root of the application we add a Dockerfile file without an extension. In Windows we need to create a file “Dockerfile..” (notice the two dots at the end, which tells Windows the file has no extension).

For the unit tests to run we need:

  1. Node JS
  2. Chrome (launched by karma)

You could also use a headless browser, such as PhantomJS, which would save us the trouble of installing Chrome, but I would like to show how easy it is to setup software in a container that requires a display.

The contents of the Dockerfile will be as follows:

FROM node:7
WORKDIR /AngularTDDApplication

# Xvfb
RUN apt-get update -qqy \
	&& apt-get -qqy install xvfb \
	&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*

# Google Chrome
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
	&& echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list \
	&& apt-get update -qqy \
	&& apt-get -qqy install google-chrome-stable \
	&& rm /etc/apt/sources.list.d/google-chrome.list \
	&& rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
	&& sed -i 's/"$HERE\/chrome"/xvfb-run "$HERE\/chrome" --no-sandbox/g' /opt/google/chrome/google-chrome


RUN npm install -g gulp
COPY package.json /AngularTDDApplication
RUN npm install


COPY . /AngularTDDApplication

Node JS version 7 is chosen in the FROM statement. This tells Docker to pull the Node JS image from the Docker hub (https://hub.docker.com/_/node/).

The WORKDIR is the working directory that will be created on the image. This working directory will contain the files of the Angular TDD application.

Xvfb is needed by Google Chrome. Xvfb is a virtual framebuffer. It performs all kind of graphical operations in virtual memory without showing anything on screen.
I have copied the Xvfb and Google Chrome commands from the existing Docker Node JS Chrome image created by mattlewis92 (http://dockr.ly/2mq4Nz9).

Before creating anything from scratch in your Dockerfile, search the Docker hub registry. Nine times out of ten you can reuse instructions from Docker files in existing images.

An extra command is needed to install Gulp, since it needs to be installed globally for the “gulp test” to work.
Next, the package.json is copied, so the npm install command takes pulls the libraries that are defined and finally the rest of the code is copied from the current directory on the host to the working directory ./AngularTDDApplication

Creating the image and running the container

Let’s open a command prompt in the application folder (where the Dockerfile is located) and type “docker build . -t angulartddapplication”.

Docker will execute the instructions from the Dockerfile and prepare the image. This might take a while to finish.

Upon completion, a message could be shown regarding permissions and we ignore that for now.

The image has been created:

Let’s start the container and open a bash shell:


Now, let’s run the tests:

Success:

Running it anywhere

We already knew we could run it locally, so can this be run on a machine that has no Node JS or Chrome installed.

Push the image

To retrieve our image easier from the other machine, we’ll push it to the Docker hub registry.

I am logged into an Ubuntu server hosted in Azure:

Docker has been installed, but npm is not available. Now, I will pull the image and run the container with the same commands as before.

And it runs flawlessly. Notice that the version of docker on the Ubuntu machine is 1.12.6 while on our windows host machine it is 17.09.0-ce:

VS

Summary

We have demonstrated how an existing angular TDD application running Karma unit tests can be containerized with Docker. The unit tests can be run on different machines with different operating systems having only Docker installed. Even if the machines have different Docker versions, the tests will still run.

Leave a Reply