Metadata-Version: 2.2 Name: pytest-docker Version: 3.1.2 Summary: Simple pytest fixtures for Docker and Docker Compose based tests Home-page: https://github.com/avast/pytest-docker Author: Max K., Andre Caron Author-email: maxim.kovykov@avast.com License: MIT Keywords: docker,docker-compose,pytest Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: License :: OSI Approved :: MIT License Classifier: Topic :: Utilities Classifier: Intended Audience :: Developers Classifier: Operating System :: Unix Classifier: Operating System :: POSIX Classifier: Operating System :: Microsoft :: Windows Requires-Python: >=3.8 Description-Content-Type: text/markdown License-File: LICENSE.txt Requires-Dist: pytest<9.0,>=4.0 Requires-Dist: attrs>=19.2.0 Provides-Extra: docker-compose-v1 Requires-Dist: docker-compose<2.0,>=1.27.3; extra == "docker-compose-v1" Provides-Extra: tests Requires-Dist: requests<3.0,>=2.22.0; extra == "tests" Requires-Dist: mypy<2.000,>=0.500; extra == "tests" Requires-Dist: pytest-pylint<1.0,>=0.14.1; extra == "tests" Requires-Dist: pytest-pycodestyle<3.0,>=2.0.0; extra == "tests" Requires-Dist: pytest-mypy<1.0,>=0.10; extra == "tests" Requires-Dist: types-requests<3.0,>=2.31; extra == "tests" Requires-Dist: types-setuptools<70.0,>=69.0; extra == "tests" Docker-based integration tests ===== [![PyPI version](https://img.shields.io/pypi/v/pytest-docker?color=green)](https://pypi.org/project/pytest-docker/) [![Build Status](https://github.com/avast/pytest-docker/actions/workflows/tests.yaml/badge.svg?branch=master)](https://github.com/avast/pytest-docker/actions/workflows/tests.yaml) [![Python versions](https://img.shields.io/pypi/pyversions/pytest-docker)](https://pypi.org/project/pytest-docker/) [![Code style](https://img.shields.io/badge/formatted%20with-black-black)](https://github.com/psf/black) # Description Simple [pytest](http://doc.pytest.org/) fixtures that help you write integration tests with Docker and [Docker Compose](https://docs.docker.com/compose/). Specify all necessary containers in a `docker-compose.yml` file and `pytest-docker` will spin them up for the duration of your tests. `pytest-docker` was originally created by André Caron. # Installation Install `pytest-docker` with `pip` or add it to your test requirements. By default, it uses the `docker compose` command, so it relies on the Compose plugin for Docker (also called Docker Compose V2). ## Docker Compose V1 compatibility If you want to use the old `docker-compose` command (deprecated since July 2023, not receiving updates since 2021) then you can do it using the [`docker-compose-command`](#docker_compose_command) fixture: ```python @pytest.fixture(scope="session") def docker_compose_command() -> str: return "docker-compose" ``` If you want to use the pip-distributed version of `docker-compose` command, you can install it using ``` pip install pytest-docker[docker-compose-v1] ``` Another option could be usage of [`compose-switch`](https://github.com/docker/compose-switch). # Usage Here is an example of a test that depends on an HTTP service. With a `docker-compose.yml` file like this (using the [httpbin](https://httpbin.org/) service): ```yaml version: '2' services: httpbin: image: "kennethreitz/httpbin" ports: - "8000:80" ``` You can write a test like this: ```python import pytest import requests from requests.exceptions import ConnectionError def is_responsive(url): try: response = requests.get(url) if response.status_code == 200: return True except ConnectionError: return False @pytest.fixture(scope="session") def http_service(docker_ip, docker_services): """Ensure that HTTP service is up and responsive.""" # `port_for` takes a container port and returns the corresponding host port port = docker_services.port_for("httpbin", 80) url = "http://{}:{}".format(docker_ip, port) docker_services.wait_until_responsive( timeout=30.0, pause=0.1, check=lambda: is_responsive(url) ) return url def test_status_code(http_service): status = 418 response = requests.get(http_service + "/status/{}".format(status)) assert response.status_code == status ``` By default, this plugin will try to open `docker-compose.yml` in your `tests` directory. If you need to use a custom location, override the `docker_compose_file` fixture inside your `conftest.py` file: ```python import os import pytest @pytest.fixture(scope="session") def docker_compose_file(pytestconfig): return os.path.join(str(pytestconfig.rootdir), "mycustomdir", "docker-compose.yml") ``` To use [multiple compose files](https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/), return a list of paths from the `docker_compose_file` fixture: ```python import os import pytest @pytest.fixture(scope="session") def docker_compose_file(pytestconfig): return [ os.path.join(str(pytestconfig.rootdir), "tests", "compose.yml"), os.path.join(str(pytestconfig.rootdir), "tests", "compose.override.yml"), ] ``` If you want to debug the test suite in your IDE (Pycharm, VsCode, etc.) and need to stop the test, the stack will be left running. To avoid creating multiple stacks, you can pin the project name and always teardown before starting a new stack: ```python import pytest # Pin the project name to avoid creating multiple stacks @pytest.fixture(scope="session") def docker_compose_project_name() -> str: return "my-compose-project" # Stop the stack before starting a new one @pytest.fixture(scope="session") def docker_setup_command(): return ["down -v", "up --build -d"] ``` ## Available fixtures By default, the scope of the fixtures are `session` but can be changed with `pytest` command line option `--container-scope <scope>`: ```bash pytest --container-scope <scope> <test_directory> ``` For available scopes and descriptions see <https://docs.pytest.org/en/6.2.x/fixture.html#fixture-scopes> ### `docker_ip` Determine the IP address for TCP connections to Docker containers. ### `docker_compose_file` Get an absolute path to the `docker-compose.yml` file. Override this fixture in your tests if you need a custom location. ### `docker_compose_project_name` Generate a project name using the current process PID. Override this fixture in your tests if you need a particular project name. ### `docker_services` Start all services from the docker compose file (`docker-compose up`). After test are finished, shutdown all services (`docker-compose down`). ### `docker_compose_command` Docker Compose command to use to execute Dockers. Default is to use Docker Compose V2 (command is `docker compose`). If you want to use Docker Compose V1, change this fixture to return `docker-compose`. ### `docker_setup` Get the list of docker_compose commands to be executed for test spawn actions. Override this fixture in your tests if you need to change spawn actions. Returning anything that would evaluate to False will skip this command. ### `docker_cleanup` Get the list of docker_compose commands to be executed for test clean-up actions. Override this fixture in your tests if you need to change clean-up actions. Returning anything that would evaluate to False will skip this command. # Development Use of a virtual environment is recommended. See the [venv](https://docs.python.org/3/library/venv.html) package for more information. First, install `pytest-docker` and its test dependencies: ```bash pip install -e ".[tests]" ``` Run tests with ```bash pytest -c setup.cfg ``` to make sure that the correct configuration is used. This is also how tests are run in CI. Use [black](https://pypi.org/project/black/) with default settings for formatting. You can also use `pylint` with `setup.cfg` as the configuration file as well as `mypy` for type checking. # Contributing This `pytest` plug-in and its source code are made available to you under a MIT license. It is safe to use in commercial and closed-source applications. Read the license for details! Found a bug? Think a new feature would make this plug-in more practical? We welcome issues and pull requests! When creating a pull request, be sure to follow this projects conventions (see above).
Memory