Using Node(4)

Run your tests

Intro

Node.js 와 Mocha frameworks 를 사용하여 Docker 안에서 Unit test 를 진행하는 방법을 알아본다.

Create a test

./test 폴더를 application 안에서 생성한다

1
$ mkdir -p test

test.js 파일을 ./test 폴더 안에 생성한다.

1
2
3
4
5
6
7
8
var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal([1, 2, 3].indexOf(4), -1);
});
});
});

Running locally and testing the application

Docker image 를 컨테이너 안에서 build 하고 실행시킨다.

1
$ docker-compose -f docker-compose.dev.yml up --build

Install Mocha

개발 의존성으로 Mocha 를 설치한다.

1
$ npm install --save-dev mocha

Update package.json and Dockerfile to run tests

컨테이너 안에서 test 가 진행될 수 있도록 package.json을 수정하자. 위에서 똑같은 docker run command를 실행시킬건데 이번에는 package.json 에 test 스크립트를 추가하고 test가 실행 될 수 있도록 한다.

1
2
3
4
5
6
{
"script": {
"test" : "mocha ./**/*.js",
"start" : "nodemon --inspect=0.0.0.0:9229 server.js"
}
}

test 실행:

1
$ docker-compose -f docker-compose.dev.yml run notes npm run test

Multi-stage Dockerfile for testing

명령에 따라 테스트를 실행하는 것 외에도 Dockerfile을 사용해서 이미지를 빌드할 때 테스트를 실행할 수 있다. 밑에 Dockerfile 은 test를 진행하고 production image 를 build 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# syntax=docker/dockerfile:1
FROM node:14.15.4 as base

WORKDIR /code

COPY package.json package.json
COPY package-lock.json package-lock.json

FROM base as test
RUN npm ci
COPY . .
CMD [ "npm", "run", "test" ]

FROM base as prod
RUN npm ci --production
COPY . .
CMD [ "node", "server.js" ]

먼저 , base image에 라벨을 as base 로 추가한다. build stage 마다 참조할 수 있도록 해준다. docker command 를 입력할 때 --target test 같이 명시해서 build stage를 명시해서 build 할 수 있다.

1
$ docker build -t node-docker --target test .

이렇게 하면 test 이미지가 빌드 된다. 이제 test 이미지를 실행해 본다.

1
$ docker run -it --rm -p 8000:8000 node-docker

테스트가 실행 된다.

지금은 build 한다음 run 을 하는 방식을 사용하는데 이렇게 하면 실행하기 위해 2번씩 명령어를 입력해야 한다. Dockerfile 내부에 CMD 를 RUN 으로 바꾸어서 조금 개선할 수 있다. CMD 는 컨테이너에서 이미지를 실행할 때 실행된다. 반면에 RUN 은 이미지를 build 할때 실행 되고 실패하면 중지된다. 수정한 Dockerfile은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# syntax=docker/dockerfile:1
FROM node:14.15.4 as base

WORKDIR /code

COPY package.json package.json
COPY package-lock.json package-lock.json

FROM base as test
RUN npm ci
COPY . .
RUN npm run test

FROM base as prod
RUN npm ci --production
COPY . .
CMD [ "node", "server.js" ]

똑같이 build 한다

1
$ docker build -t node-docker --target test .