### Install pytest-docker Source: https://context7.com/avast/pytest-docker/llms.txt Install the package using pip. Use the `docker-compose-v1` extra for legacy Docker Compose V1 support. ```bash pip install pytest-docker ``` ```bash pip install pytest-docker[docker-compose-v1] ``` -------------------------------- ### Install pytest-docker with test dependencies Source: https://github.com/avast/pytest-docker/blob/master/README.md Install the pytest-docker package along with its test dependencies using pip. This command is typically used in a development environment. ```bash pip install -e ".[tests]" ``` -------------------------------- ### Run tests with pytest Source: https://github.com/avast/pytest-docker/blob/master/README.md Execute tests using pytest with a specific configuration file. This ensures that the correct setup is used, mirroring the CI environment. ```bash pytest -c setup.cfg ``` -------------------------------- ### Pin Docker Compose Project Name and Control Setup Source: https://github.com/avast/pytest-docker/blob/master/README.md Pin the docker_compose_project_name to a specific value to avoid creating multiple stacks. The docker_setup fixture is overridden to first 'down -v' the existing stack and then 'up --build --wait' to ensure a clean state. ```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(): return ["down -v", "up --build --wait"] ``` -------------------------------- ### Manage Compose Services with docker_services fixture Source: https://context7.com/avast/pytest-docker/llms.txt The `docker_services` fixture starts services defined in a compose file before tests and tears them down afterwards. It yields a `Services` object for interacting with running containers and waiting for them to become responsive. ```python import pytest import requests from requests.exceptions import ConnectionError def is_responsive(url): try: return requests.get(url).status_code == 200 except ConnectionError: return False @pytest.fixture(scope="session") def http_service(docker_ip, docker_services): """Wait for the httpbin container to accept connections, then return its URL.""" port = docker_services.port_for("httpbin", 80) url = f"http://{docker_ip}:{port}" docker_services.wait_until_responsive( timeout=30.0, pause=0.1, check=lambda: is_responsive(url) ) return url # tests/test_httpbin.py def test_teapot(http_service): response = requests.get(f"{http_service}/status/418") assert response.status_code == 418 ``` -------------------------------- ### Configure Docker Compose V1 Command Source: https://github.com/avast/pytest-docker/blob/master/README.md Override the default docker_compose_command fixture to use 'docker-compose' for V1 compatibility. Ensure Docker Compose V1 is installed separately. ```python import pytest @pytest.fixture(scope="session") def docker_compose_command() -> str: return "docker-compose" ``` -------------------------------- ### Use Multiple Docker Compose Files Source: https://github.com/avast/pytest-docker/blob/master/README.md Configure the docker_compose_file fixture to return a list of paths, enabling the use of multiple compose files for merging configurations. This allows for modular setup of services. ```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"), ] ``` -------------------------------- ### Resolve Docker Host IP with docker_ip fixture Source: https://context7.com/avast/pytest-docker/llms.txt Use the `docker_ip` fixture to get the IP address for TCP connections to exposed container ports. This is useful for making requests to services running in Docker. ```python import requests def test_service_reachable(docker_ip, docker_services): port = docker_services.port_for("myapp", 8080) url = f"http://{docker_ip}:{port}/health" response = requests.get(url, timeout=5) assert response.status_code == 200 ``` -------------------------------- ### Customize Docker Lifecycle Commands Source: https://context7.com/avast/pytest-docker/llms.txt Control commands executed before (`docker_setup`) and after (`docker_cleanup`) tests. Return a list of compose subcommands or a falsy value to skip. ```python import pytest @pytest.fixture(scope="session") def docker_compose_project_name() -> str: return "ci-tests" # fixed name so the teardown below always hits the right stack @pytest.fixture(scope="session") def docker_setup(): # Tear down any leftover stack from a previous interrupted run, then start fresh return ["down -v", "up --build --wait"] @pytest.fixture(scope="session") def docker_cleanup(): # Keep containers alive after tests for post-mortem inspection in CI return [] # falsy list skips teardown ``` -------------------------------- ### Switch Docker Compose Command (V1/V2) Source: https://context7.com/avast/pytest-docker/llms.txt Specify the shell command to invoke Docker Compose. Override this to use `docker-compose` (legacy V1) or other compatible wrappers. ```python import pytest @pytest.fixture(scope="session") def docker_compose_command() -> str: return "docker-compose" # use legacy Docker Compose V1 ``` -------------------------------- ### Define HTTP Service Fixture Source: https://github.com/avast/pytest-docker/blob/master/README.md Sets up an HTTP service dependency for tests. It waits for the service to be responsive using a helper function and returns the service URL. Requires 'requests' library and 'docker_ip', 'docker_services' fixtures. ```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 ``` -------------------------------- ### Poll Service Readiness with Services.wait_until_responsive Source: https://context7.com/avast/pytest-docker/llms.txt The `Services.wait_until_responsive` method polls a `check` function periodically until it returns a truthy value or a timeout is reached. This is essential for ensuring a service is ready before tests interact with it. ```python import socket import pytest def is_port_open(host, port): try: with socket.create_connection((host, port), timeout=1): return True except OSError: return False @pytest.fixture(scope="session") def postgres_service(docker_ip, docker_services): port = docker_services.port_for("postgres", 5432) docker_services.wait_until_responsive( check=lambda: is_port_open(docker_ip, port), timeout=60.0, pause=0.5, ) return {"host": docker_ip, "port": port} ``` -------------------------------- ### Single Compose File Fixture Source: https://context7.com/avast/pytest-docker/llms.txt Use this fixture to specify a single `docker-compose.yml` file for your tests. ```python import pytest import os @pytest.fixture(scope="session") def docker_compose_file(pytestconfig): return os.path.join(str(pytestconfig.rootdir), "infra", "compose.yml") ``` -------------------------------- ### Discover Mapped Host Port with Services.port_for Source: https://context7.com/avast/pytest-docker/llms.txt Use `Services.port_for(service, container_port)` to find the host port mapped to a specific container port for a given service. This is useful for connecting to services like databases or APIs. ```python import redis def test_redis_set_get(docker_ip, docker_services): host_port = docker_services.port_for("redis", 6379) # returns e.g. 32771 client = redis.Redis(host=docker_ip, port=host_port, decode_responses=True) client.set("key", "value") assert client.get("key") == "value" ``` -------------------------------- ### Multiple Compose Files Fixture Source: https://context7.com/avast/pytest-docker/llms.txt Provide multiple compose files to merge configurations. Docker Compose will merge them, with later files overriding earlier ones. ```python import pytest import os @pytest.fixture(scope="session") def docker_compose_file(pytestconfig): root = str(pytestconfig.rootdir) return [ os.path.join(root, "infra", "compose.yml"), os.path.join(root, "infra", "compose.override.yml"), ] ``` -------------------------------- ### Low-level Compose Command Runner Source: https://context7.com/avast/pytest-docker/llms.txt Use the `DockerComposeExecutor` class for fine-grained control over individual Docker Compose invocations within unit tests or custom fixtures. ```python from pytest_docker.plugin import DockerComposeExecutor def test_custom_compose_command(): executor = DockerComposeExecutor( compose_command="docker compose", compose_files=["docker-compose.yml", "docker-compose.ci.yml"], compose_project_name="my-project", ) # Run an arbitrary compose subcommand; returns raw bytes output output = executor.execute("ps") print(output.decode()) # Run a command that may return non-zero exit codes output = executor.execute("logs myservice", success_codes=(0, 1)) ``` -------------------------------- ### Customize Compose File Path with docker_compose_file fixture Source: https://context7.com/avast/pytest-docker/llms.txt Override the `docker_compose_file` fixture to specify a custom path to your Docker Compose file or return a list of paths to merge multiple compose files. ```python # conftest.py import os import pytest ``` -------------------------------- ### Change Fixture Scope at Runtime Source: https://context7.com/avast/pytest-docker/llms.txt Use the `--container-scope` CLI option to change fixture scope from the default `session` to `module`, `class`, or `function` to control container sharing and isolation. ```bash # Restart containers between test modules pytest --container-scope=module tests/ # Restart containers between test classes pytest --container-scope=class tests/ # Fresh containers for every individual test (slow but maximally isolated) pytest --container-scope=function tests/ ``` -------------------------------- ### Specify Custom Docker Compose File Location Source: https://github.com/avast/pytest-docker/blob/master/README.md Override the default docker_compose_file fixture to point to a docker-compose.yml file in a custom directory. This is useful when your compose file is not in the default 'tests' directory. ```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") ``` -------------------------------- ### Pin Docker Compose Project Name Source: https://context7.com/avast/pytest-docker/llms.txt Override the default `pytest` project name to a fixed name. This is useful for reusing or cleanly replacing stacks left behind after debugging sessions. ```python import pytest @pytest.fixture(scope="session") def docker_compose_project_name() -> str: return "myapp-tests" ``` -------------------------------- ### Test HTTP Service Status Code Source: https://github.com/avast/pytest-docker/blob/master/README.md A basic test function that uses the 'http_service' fixture to make a request and assert the status code. It demonstrates consuming the service URL provided by the fixture. ```python def test_status_code(http_service): status = 418 response = requests.get(http_service + "/status/{}".format(status)) assert response.status_code == status ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.