使用Node.js和Mocha框架运行测试

预计阅读时间:8分钟

先决条件

完成“使用容器进行开发”中的步骤来构建映像并将其作为容器化应用程序运行。

介绍

测试是现代软件开发的重要组成部分。对于不同的开发团队来说,测试可能意味着很多事情。有单元测试,集成测试和端到端测试。在本指南中,我们将介绍如何在Docker中运行您的单元测试。

创建一个测试

让我们./test在应用程序的目录中定义Mocha测试。

$ 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 run命令,但是这次,我们将使用npm run test覆盖容器内部的CMD。这将调用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 ... 

> node-docker@1.0.0 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 baseFROM node:14.15.4语句中添加标签。这使我们可以在其他构建阶段中引用此构建阶段。接下来,我们添加一个标记为test的新构建阶段。我们将使用此阶段来运行我们的测试。

现在,让我们重建图像并运行测试。我们将运行与上述相同的docker build命令,但是这次我们将添加--target test标志,以便我们专门运行测试构建阶段。

$ docker build -t node-docker --target test .
Sending build context to Docker daemon  22.35MB
...
Successfully built fa583b97c4dd
Successfully tagged node-docker:latest

现在我们的测试映像已构建,我们可以在容器中运行它,看看我们的测试是否通过。

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

> node-docker@1.0.0 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 build命令即可。

$ 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
 ---> f5be1883c8e0
...
Step 6/8 : RUN npm ci
 ---> Using cache
 ---> bcc5cd4a6a1e
Step 7/8 : COPY . .
 ---> 1528ebcb73fa
Step 8/8 : RUN npm run test
 ---> Running in beadc36b293a

> node-docker@1.0.0 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 build命令,并观察构建失败,并将失败的测试信息打印到控制台。

$ 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

> node-docker@1.0.0 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! node-docker@1.0.0 test: `mocha ./**/*.js`
npm ERR! Exit status 1
...

下一步

在本模块中,我们将运行测试作为Docker映像构建过程的一部分进行了介绍。

在下一个模块中,我们将看一下如何使用GitHub Actions建立CI / CD管道。看:

配置CI / CD

反馈

通过提供您的反馈帮助我们改善此主题。通过在Docker Docs GitHub存储库中创建问题,让我们知道您的想法。或者,创建PR以建议更新。


Node.jsbuildMocha测试