--- title: Run Node.js tests in a container linkTitle: Run your tests weight: 30 keywords: node.js, node, test description: Learn how to run your Node.js tests in a container. aliases: - /language/nodejs/run-tests/ - /guides/language/nodejs/run-tests/ --- ## Prerequisites Complete all the previous sections of this guide, starting with [Containerize a Node.js application](containerize.md). ## Overview Testing is an essential part of modern software development. Testing can mean a lot of things to different development teams. There are unit tests, integration tests and end-to-end testing. In this guide you take a look at running your unit tests in Docker when developing and when building. ## Run tests when developing locally The sample application already has the Jest package for running tests and has tests inside the `spec` directory. When developing locally, you can use Compose to run your tests. Run the following command to run the test script from the `package.json` file inside a container. ```console $ docker compose run server npm run test ``` To learn more about the command, see [docker compose run](/reference/cli/docker/compose/run/). You should see output like the following. ```console > docker-nodejs@1.0.0 test > jest PASS spec/routes/deleteItem.spec.js PASS spec/routes/getItems.spec.js PASS spec/routes/addItem.spec.js PASS spec/routes/updateItem.spec.js PASS spec/persistence/sqlite.spec.js ● Console console.log Using sqlite database at /tmp/todo.db at Database.log (src/persistence/sqlite.js:18:25) console.log Using sqlite database at /tmp/todo.db at Database.log (src/persistence/sqlite.js:18:25) console.log Using sqlite database at /tmp/todo.db at Database.log (src/persistence/sqlite.js:18:25) console.log Using sqlite database at /tmp/todo.db at Database.log (src/persistence/sqlite.js:18:25) console.log Using sqlite database at /tmp/todo.db at Database.log (src/persistence/sqlite.js:18:25) Test Suites: 5 passed, 5 total Tests: 9 passed, 9 total Snapshots: 0 total Time: 2.008 s Ran all test suites. ``` ## Run tests when building To run your tests when building, you need to update your Dockerfile to add a new test stage. The following is the updated Dockerfile. ```dockerfile {hl_lines="27-35"} # syntax=docker/dockerfile:1 ARG NODE_VERSION=18.0.0 FROM node:${NODE_VERSION}-alpine as base WORKDIR /usr/src/app EXPOSE 3000 FROM base as dev RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package-lock.json,target=package-lock.json \ --mount=type=cache,target=/root/.npm \ npm ci --include=dev USER node COPY . . CMD npm run dev FROM base as prod RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package-lock.json,target=package-lock.json \ --mount=type=cache,target=/root/.npm \ npm ci --omit=dev USER node COPY . . CMD node src/index.js FROM base as test ENV NODE_ENV test RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package-lock.json,target=package-lock.json \ --mount=type=cache,target=/root/.npm \ npm ci --include=dev USER node COPY . . RUN npm run test ``` Instead of using `CMD` in the test stage, use `RUN` to run the tests. The reason is that the `CMD` instruction runs when the container runs, and the `RUN` instruction runs when the image is being built and the build will fail if the tests fail. Run the following command to build a new image using the test stage as the target and view the test results. Include `--progress=plain` to view the build output, `--no-cache` to ensure the tests always run, and `--target test` to target the test stage. ```console $ docker build -t node-docker-image-test --progress=plain --no-cache --target test . ``` You should see output containing the following. ```console ... #11 [test 3/3] RUN npm run test #11 1.058 #11 1.058 > docker-nodejs@1.0.0 test #11 1.058 > jest #11 1.058 #11 3.765 PASS spec/routes/getItems.spec.js #11 3.767 PASS spec/routes/deleteItem.spec.js #11 3.783 PASS spec/routes/updateItem.spec.js #11 3.806 PASS spec/routes/addItem.spec.js #11 4.179 PASS spec/persistence/sqlite.spec.js #11 4.207 #11 4.208 Test Suites: 5 passed, 5 total #11 4.208 Tests: 9 passed, 9 total #11 4.208 Snapshots: 0 total #11 4.208 Time: 2.168 s #11 4.208 Ran all test suites. #11 4.265 npm notice #11 4.265 npm notice New major version of npm available! 8.6.0 -> 9.8.1 #11 4.265 npm notice Changelog: #11 4.265 npm notice Run `npm install -g npm@9.8.1` to update! #11 4.266 npm notice #11 DONE 4.3s ... ``` ## Summary In this section, you learned how to run tests when developing locally using Compose and how to run tests when building your image. Related information: - [docker compose run](/reference/cli/docker/compose/run/) ## Next steps Next, you’ll learn how to set up a CI/CD pipeline using GitHub Actions.