Home > other >  Jest Unit Testing in Docker Container
Jest Unit Testing in Docker Container

Time:01-17

I am trying to move my tests to my docker image build stage but it seems to ignore my test build at all and just skip it when I build the image.

What can be the problem?

# Base build 
FROM node:16.13 AS build
RUN mkdir /app
WORKDIR /app
ADD package*.json ./
RUN npm i -g [email protected]
RUN npm i --production
COPY . .
RUN npm run build

# Clean
RUN npm prune --production
RUN npm install -g node-prune
RUN node-prune

# Test
FROM build AS test
RUN npm i -g [email protected]
RUN npm i -D jest typescript
RUN npm i -D ts-jest @types/jest
RUN npm i -D @shelf/jest-mongodb
RUN npx jest

# Release
FROM node:16.13-alpine
RUN mkdir /app
WORKDIR /app
COPY --from=build /app/dist ./dist/
COPY --from=build /app/node_modules ./node_modules/
COPY --from=build /app/package.json ./
CMD npm start

Above you can see my Dockerfile where I am preparing the build, then plan to have tests and after that, I am making my release image.

I've already been playing around with that for hours; I cleared cache, made tweaks with the order in the file) but it didn't help. It keeps ignoring my test build.

Any hint of that and in general on my Dockerfile is welcomed

CodePudding user response:

Docker internally has two different systems to build images. Newer Dockers default to a newer system called BuildKit. One of the major differences is the way the two systems handle multi-stage builds: the older system just runs all of the build stages until the end, but BuildKit figures out that the final stage COPY --from=build but doesn't use anything from the test stage, and just skips it.

I wouldn't run these tests in a Dockerfile (since it doesn't produce a runnable artifact) or in Docker at all. I'd probably run them in my host-based development environment, before building a Docker image:

# On the host
npm install    # devDependencies include all test dependencies

npm run tests  # locally
# repeat until the tests pass (without involving a container)

# Build the image _after_ the tests pass
docker build -t myapp .

docker build also has a --target option to name a specific stage so you could tell Docker to "build the test image", but you'd just immediately delete it. This is where I don't think Docker quite makes sense as a test runner.

docker build -t delete-me --target test
docker build -t my-app .
docker rmi delete-me

Your Dockerfile also installs a MongoDB test helper. If the test depends on a live database rather than a mock implementation, the other thing to be aware of here is that code in a Dockerfile can never connect to other containers. You have to run this test from somewhere else in this case.

  •  Tags:  
  • Related