For integration tests with few external dependencies that don’t require much orchestration beyond networking Docker containers and setting up environment variables, Docker Compose is a simple and easy to manage solution for building, running and tearing down tests.
This Flask application example is typical. The project’s multistage Dockerfile defines both the service and test images:
FROM python:3.6 AS base # Upgrade pip RUN pip install --upgrade pip WORKDIR /usr/app COPY . . # run app with gunicorn server ENTRYPOINT ["gunicorn"] CMD ["flask_app:app", \ "--bind", "0.0.0.0:5000", "--log-level", "debug", \ "--access-logfile", "/usr/app/logs/access.log", \ "--error-logfile", "/usr/app/logs/error.log", \ "--reload"] FROM base AS deploy RUN pip install -r requirements.txt FROM deploy AS test RUN pip install -r test_requirements.txt ENTRYPOINT ["pytest"] CMD ["-s", "-ra", "--cov=.", "t"]
The web application and test services are configured with the following Docker Compose file along with MongoDB, which is required by both services:
version: '3.4' services: # MongoDB mongo: hostname: mongo container_name: mongo image: mongo:3.6.3 ports: - '27017:27017' webapp: container_name: flask build: context: . target: deploy volumes: - ./logs:/usr/app/logs ports: - '5000:5000' links: - mongo depends_on: - mongo webapp_test: container_name: test build: context: . target: test volumes: - ./logs:/usr/app/logs links: - mongo depends_on: - mongo
I usually run the test suite using the
docker-compose up command, which can build, connect and run the services defined in the Docker Compose file. I’ve found it useful to get the exit code from the test service, which is webapp_test here, to report if any tests failed. The –exit-code-from flag takes care of this, and also has the side-effect of turning on the –abort-on-container-exit flag to stop all services when the test service terminates.
TeamCity, which is what I’m currently using for CI, has a Docker Compose build runner that runs the
docker-compose up -d and
docker-compose down -v commands on a given Docker Compose file. Unfortunately, this build runner currently (v2017.2 and earlier) doesn’t supported any other flags.
Instead, I use the command-line build runner to run docker-compose up to run Docker Compose commands. The command line build runner is used to run any command line tool or script supported by the build agent OS. An extra build step that calls
docker-compose down is needed in this case.