Should I run tests during the docker build?

Question:

I have a Dockerfile like this:

FROM python:3.9

WORKDIR /app

RUN apt-get update && apt-get upgrade -y

RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/install-poetry.py | python -

ENV PATH /root/.local/bin:$PATH

COPY pyproject.toml poetry.lock Makefile ./

COPY src ./src

COPY tests ./tests

RUN poetry install && poetry run pytest && make clean

CMD ["bash"]

As you can see that tests will be run during the build. It could slow down the build little bit, but will ensure that my code runs in the Docker container.

If tests pass in my local machine, does not mean that they will also pass in the docker container.

Suppose I add a feature in my code that uses chromedriver or ffmpeg binaries, that is present in my system, so tests will pass in my system.

But, suppose I forget to install those dependencies in the Dockerfile, then the docker build will fail (as tests are running during the build)

What is the standard way of doing what i am trying to do ?

Is my Dockerfile good ? or should i do something differently ?

Asked By: aahnik

||

Answers:

Run pytest on image construction makes no sense to me. However, what you can do is run tests after the image is completed. In your pipeline you should have something like this:

  1. Test your python package locally
  2. Build wheel with poetry
  3. Build docker image with your python package
  4. Run your docker image to test if it works (running pytests for example)
  5. Publish your tested image to container registry
Answered By: Daniel Argüelles

If you use multiple stages, you can run docker build and avoid running the tests, and if you want to run the tests afterwards, running docker build --target test would then run the tests on what was previously built. This approach is explained on the docker official documentation.

This way not only we avoid running the build twice due to the Docker caching mechanism, we also can avoid having the test code being shipped in the image.

A possible use case of this implementation when doing CI/CD is to run the two commands when developing locally and in the CI; and not run the tests command in the CD, because the code being deployed will already be tested.

Answered By: ccoutinho