使用 Dockerfile 运行 Jest 测试

mee*_*kat 7 docker reactjs jestjs dockerfile

问题

\n

嘿,我没有太多使用 Docker - 我正在尝试通过 Dockerfile 运行我的 Jest 测试。然而,我error在尝试构建图像时得到了这个:

\n

错误

\n
Step 13/16 : RUN if [ "$runTests" = "True" ]; then     RUN npm test; fi\n ---> Running in ccdb3f89fb79\n/bin/sh: RUN: not found\n
Run Code Online (Sandbox Code Playgroud)\n

Dockerfile

\n
FROM node:10-alpine as builder\nARG TOKEN\nWORKDIR /app\n\nARG runTests\n\n\nCOPY .npmrc-pipeline .npmrc\n\nCOPY package*.json ./\nRUN npm install\nCOPY . .\n\nRUN rm -f .npmrc\n\nENV PORT=2000\nENV NODE_ENV=production\n\n\nRUN if [ "$runTests" = "True" ]; then \\\n    RUN npm test; fi\n\nRUN npm run build\n\nEXPOSE 2000\n\nCMD ["npm", "start"]\n
Run Code Online (Sandbox Code Playgroud)\n

我用来构建图像的命令是这样的,其想法是仅当 runTests=True 时才能运行测试。

\n
docker build -t d-image --build-arg runTests="True" --build-arg "MY TOOOOOKEN"\n
Run Code Online (Sandbox Code Playgroud)\n

仅使用 Dockerfile 可以做到这一点吗?或者还需要使用 docker-compose 吗?

\n

条件语句似乎效果很好。

\n

不可能有两个 CMD 命令

\n

我已尝试将此作为解决方法(但它不起作用):\n Dockerfile

\n
FROM node:10-alpine as builder\nARG TOKEN\nWORKDIR /app\n\nARG runTests\n\n\nCOPY .npmrc-pipeline .npmrc\n\nCOPY package*.json ./\nRUN npm install\nCOPY . .\n\nRUN rm -f .npmrc\n\nENV PORT=3000\nENV NODE_ENV=production\n\n\nRUN npm run build\n\nEXPOSE 3000\n\nCMD if [ "$runTests" = "True" ]; then \\\n    CMD ["npm", "test"] && ["npm", "start"] ;fi\n
Run Code Online (Sandbox Code Playgroud)\n

现在我没有从测试中得到任何输出,但看起来是成功的。

\n

进步

\n

我已经取得了一些进展,并且在构建图像时测试实际上正在运行。我还决定使用 RUN 命令来运行测试,以便它们在构建步骤上运行。

\n

Dockerfile:

\n
FROM node:10-alpine as builder\nARG TOKEN\nWORKDIR /app\n\n\nCOPY .npmrc-pipeline .npmrc\n\nCOPY package*.json ./\nRUN npm install\nCOPY . .\nRUN rm -f .npmrc\nENV PORT=3000\nENV NODE_ENV=production\nRUN npm run build\nRUN npm test\nEXPOSE 3000\n
Run Code Online (Sandbox Code Playgroud)\n

错误:

\n
FAIL src/pages/errorpage/tests/accessroles.test.jsx\n  \xe2\x97\x8f Test suite failed to run\n\n    Jest encountered an unexpected token\n\n    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.\n\n    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".\n\n    Here's what you can do:\n     \xe2\x80\xa2 If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.\n     \xe2\x80\xa2 To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.\n     \xe2\x80\xa2 If you need a custom transformation specify a "transform" option in your config.\n     \xe2\x80\xa2 If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.\n\n    You'll find more details and examples of these config options in the docs:\n    https://jestjs.io/docs/en/configuration.html\n\n    Details:\n
Run Code Online (Sandbox Code Playgroud)\n

在我看来,该docker build进程没有使用jest:{...}my 中的配置package.json,即使它被复制并安装在 Dockerfile 中 有什么想法吗?

\n

jon*_*rpe 8

RUN它们CMD不是命令,而是告诉 Docker 在构建容器时做什么的指令。所以例如:

RUN if [ "$runTests" = "True" ]; then \
    RUN npm test; fi
Run Code Online (Sandbox Code Playgroud)

没有意义,RUN <command>运行 shell 命令但未RUN在 shell 中定义,它应该是:

ARG runTests  # you need to define the argument too
RUN if [ "$runTests" = "True" ]; then \
    npm test; fi
Run Code Online (Sandbox Code Playgroud)

更简洁的方法是将其设置npm入口点start特定命令

ENTRYPOINT [ "npm" ]
CMD [ "start" ]
Run Code Online (Sandbox Code Playgroud)

这允许您正常构建容器,它不需要任何构建参数,然后运行start容器中以外的 NPM 脚本,例如运行npm test

RUN if [ "$runTests" = "True" ]; then \
    RUN npm test; fi
Run Code Online (Sandbox Code Playgroud)

但是,请注意,这意味着所有开发依赖项都需要位于容器中。看起来(来自ENV NODE_ENV=production)您打算将其作为生产构建,因此您根本不应该在容器中运行测试。此外,尽管as builder这并不是真正的多阶段构建。惯用的脚本如下:

ARG runTests  # you need to define the argument too
RUN if [ "$runTests" = "True" ]; then \
    npm test; fi
Run Code Online (Sandbox Code Playgroud)

例如,请参阅我为全栈 React/Express 应用程序整理的这个 Dockerfile 。