Запускать свои тесты, используя фреймворки Node.js и Mocha

Предпосылки

Выполняет шаги, чтобы создать образ и запускает его как контейнерное приложение в Используйте свой контейнер для разработки.

Введение

Тестирование — неотъемлемая часть современной разработки программного обеспечения. Тестирование может означать многое для разных команд разработчиков. Существуют модульные тесты, интеграционные тесты и сквозное тестирование. В этом руководстве мы рассмотрим запуск ваших модульных тестов в Docker.

Создаёт тест

Давайте определим тест Mocha в каталоге ./test в нашем приложении.

$ mkdir -p test

Сохраняет следующий код в ./test/test.js.

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);
    });
  });
});

Запуск локально и тестирование приложения

Давайте создадим наш образ Docker и убедимся, что все работает правильно. Выполните следующую команду, чтобы создать и запустить образ Docker в контейнере.

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

Теперь давайте протестируем наше приложение, разместив полезную нагрузку JSON, а затем выполнив HTTP-запрос GET, чтобы убедиться, что наш JSON был сохранен правильно.

$ curl --request POST \
  --url http://localhost:8000/test \
  --header 'content-type: application/json' \
  --data '{"msg": "testing"}'

Теперь выполняет запрос GET к той же конечной точке, чтобы убедиться, что наша полезная нагрузка JSON была сохранена и извлечена правильно. «id» и «createDate» для вас будут разными.

$ curl http://localhost:8000/test

{"code":"success","payload":[{"msg":"testing","id":"e88acedb-203d-4a7d-8269-1df6c1377512","createDate":"2020-10-11T23:21:16.378Z"}]}

Устанавливает Мокко

Выполняет следующую команду, чтобы установить Mocha и добавить его в зависимости разработчика:

$ npm install --save-dev mocha

Обновляет package.json и Dockerfile для запуска тестов

Хорошо, теперь, когда мы знаем, что наше приложение работает правильно, давайте попробуем запускает наши тесты внутри контейнера. Мы будем использовать ту же команду запуска docker, что и выше, но на данный раз мы переопределим CMD, который находится внутри нашего контейнера, с помощью теста запуска npm. Это вызовет команду, которая находится в файле package.json в разделе «сценарий». См. далее.

{
...
  "scripts": {
    "test": "mocha ./**/*.js",
    "start": "nodemon --inspect=0.0.0.0:9229 server.js"
  },
...
}

Далее приведена команда Docker для запуска контейнера и запуска тестов:

$ docker compose -f docker-compose.dev.yml run notes npm run test
Creating node-docker_notes_run ...

> [email protected] test /code
> mocha ./**/*.js



  Array
    #indexOf()
      ✓ should return -1 when the value is not present


  1 passing (11ms)

Многоэтапный Dockerfile для тестирования

Помимо запуска тестов по команде, мы можем запускать их при сборке нашего образа, используя многоэтапный Dockerfile. Следующий Dockerfile запустит наши тесты и создаст наш рабочий образ.

# 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" ]

Сначала мы добавляем метку as base к оператору FROM node:14.15.4. Это позволяет нам ссылаться на данный этап сборки на других этапах сборки. Затем мы добавляем новую стадию сборки, помеченную как test. Мы будем использовать данный этап для запуска наших тестов.

Теперь давайте восстановим наш образ и запустим наши тесты. Мы запустим ту же команду сборки Docker, что и выше, но на данный раз мы добавим флаг --target test, чтобы мы специально запускали этап тестовой сборки.

$ docker build -t node-docker --target test .
[+] Building 66.5s (12/12) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                 0.0s
 => => transferring dockerfile: 662B                                                                                                                                 0.0s
 => [internal] load .dockerignore
 ...
  => [internal] load build context                                                                                                                                    4.2s
 => => transferring context: 9.00MB                                                                                                                                  4.1s
 => [base 2/4] WORKDIR /code                                                                                                                                         0.2s
 => [base 3/4] COPY package.json package.json                                                                                                                        0.0s
 => [base 4/4] COPY package-lock.json package-lock.json                                                                                                              0.0s
 => [test 1/2] RUN npm ci                                                                                                                                            6.5s
 => [test 2/2] COPY . .

Теперь, когда наш тестовый образ создан, мы можем запускает его в контейнере и посмотреть, пройдут ли наши тесты.

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

> [email protected] test /code
> mocha ./**/*.js



  Array
    #indexOf()
      ✓ should return -1 when the value is not present


  1 passing (12ms)

Я сократил выходные данные сборки, но вы можете видеть, что запуск тестов Mocha завершён, и все наши тесты пройдены.

Это здорово, но на данный момент нам нужно запускает две команды docker для сборки и запуска наших тестов. Мы можем немного улучшить это, используя оператор RUN вместо оператора CMD на этапе тестирования. Оператор CMD не выполняется во время построения образа, но выполняется при запуске образа в контейнере. В то время как с оператором RUN наши тесты будут выполняться во время сборки образа и останавливать сборку в случае сбоя.

Обновляет свой Dockerfile выделенной строкой далее.

# 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" ]

Теперь, чтобы запускает наши тесты, нам просто нужно запускает команду сборки docker, как указано выше.

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

[+] Building
8.9s (13/13) FINISHED => [internal] load build definition from
Dockerfile 0.0s => => transferring dockerfile: 650B 0.0s => [internal]
load .dockerignore 0.0s => => transferring context: 2B

[email protected] test /code mocha ./\*\*/\*.js

Array #indexOf() ✓ should return -1 when the value is not present

1 passing (9ms)

Removing intermediate container beadc36b293a ---> 445b80e59acd
Successfully built 445b80e59acd Successfully tagged node-docker:latest

Я снова обрезал вывод для простоты, но вы можете видеть, что наши тесты запущены и пройдены. Давайте сломаем один из тестов и посмотрим на результат, когда наши тесты не пройдут.

Открывает файл test/test.js и изменяет строку 5 следующим образом.

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

Теперь запускает ту же команду сборки docker, что и выше, и обратите внимание, что сборка завершается с ошибкой, а информация о неудачном тестировании выводится на консоль.

$ docker build -t node-docker --target test .
Sending build context to Docker daemon  22.35MB
Step 1/8 : FROM node:14.15.4 as base
 ---> 995ff80c793e
...
Step 8/8 : RUN npm run test
 ---> Running in b96d114a336b

> [email protected] test /code
> mocha ./**/*.js



  Array
    #indexOf()
      1) should return -1 when the value is not present


  0 passing (12ms)
  1 failing

  1) Array
       #indexOf()
         should return -1 when the value is not present:

      AssertionError [ERR_ASSERTION]: 2 == -1
      + expected - actual

      -2
      +-1

      at Context.<anonymous> (test/test.js:5:14)
      at processImmediate (internal/timers.js:461:21)



npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test: `mocha ./**/*.js`
npm ERR! Exit status 1
...

Следующие шаги

В этом модуле мы рассмотрели запуск тестов как часть процесса сборки образа Docker.

В следующем модуле мы рассмотрим, как настроить конвейер CI/CD с помощью GitHub Actions. Видеть:

Настроить CI/CD

Обратная связь

Помогите нам улучшить эту тему, оставив свой отзыв. Дайте нам знать, что вы думаете, создав задачу в репозитории Документы Docker GitHub. Или создайте PR, чтобы предложить обновления.