From 6bb9b981e5f1f25291e27422ba60df0d195810c6 Mon Sep 17 00:00:00 2001 From: Mikhail Bulash Date: Wed, 12 Nov 2025 15:30:20 +0100 Subject: [PATCH] Find Compose files --- src/pytest_docker/plugin.py | 26 +++++++++++++++--- tests/test_fixtures.py | 54 ++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/pytest_docker/plugin.py b/src/pytest_docker/plugin.py index c0a0ecd..dd70938 100644 --- a/src/pytest_docker/plugin.py +++ b/src/pytest_docker/plugin.py @@ -149,12 +149,30 @@ def docker_compose_command() -> str: return "docker compose" +def _find_compose_file(basedir: Path) -> Optional[Path]: + # Search for well-known filenames, in the order defined by the compose docs. + # https://docs.docker.com/compose/intro/compose-application-model/#the-compose-file + names = [ + "compose.yaml", + "compose.yml", + "docker-compose.yaml", + "docker-compose.yml", + ] + paths = (basedir / filename for filename in names) + exisiting_paths = (path for path in paths if path.is_file()) + + return next(exisiting_paths, None) + + @pytest.fixture(scope=containers_scope) -def docker_compose_file(pytestconfig: Any) -> Union[List[str], str]: - """Get an absolute path to the `docker-compose.yml` file. Override this - fixture in your tests if you need a custom location.""" +def docker_compose_file(pytestconfig: Config) -> Union[List[str], str]: + """Get an absolute path to the compose file. Override this fixture in your tests + if you need a custom location.""" + + tests_dir = Path(pytestconfig.rootpath) / "tests" + fallback_path = tests_dir / "docker-compose.yml" - return os.path.join(str(pytestconfig.rootdir), "tests", "docker-compose.yml") + return str(_find_compose_file(tests_dir) or fallback_path) @pytest.fixture(scope=containers_scope) diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 87d6ae8..b059192 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -1,15 +1,61 @@ -import os.path +import os +from pathlib import Path from typing import List import pytest from _pytest.fixtures import FixtureRequest from _pytest.pytester import Pytester -HERE = os.path.dirname(os.path.abspath(__file__)) +@pytest.fixture +def tests_dir(pytester: Pytester) -> Path: + dir = Path(pytester.path) / "tests" + dir.mkdir() + return dir + + +@pytest.fixture(params=[[]]) +def tests_dir_contents(tests_dir: Path, request: FixtureRequest) -> List[Path]: + filenames: List[str] = getattr(request, "param", []) + paths = [tests_dir / filename for filename in filenames] + for path in paths: + path.touch() + + return paths + + +@pytest.mark.parametrize( + ("tests_dir_contents", "expected_compose_file"), + [ + ( + [ + "compose.yaml", + "compose.yml", + "docker-compose.yaml", + "docker-compose.yml", + ], + "compose.yaml", + ), + (["compose.yml", "docker-compose.yaml", "docker-compose.yml"], "compose.yml"), + (["docker-compose.yaml", "docker-compose.yml"], "docker-compose.yaml"), + (["docker-compose.yml"], "docker-compose.yml"), + ([], "docker-compose.yml"), + ], + indirect=["tests_dir_contents"], +) +@pytest.mark.usefixtures("tests_dir_contents") +def test_docker_compose_file( + pytester: Pytester, expected_compose_file: str, tests_dir: Path +) -> None: + pytester.makepyfile( + f""" + def test_docker_compose_file(docker_compose_file): + assert docker_compose_file == "{tests_dir}/{expected_compose_file}" + """ + ) -def test_docker_compose_file(docker_compose_file: str) -> None: - assert docker_compose_file == os.path.join(HERE, "docker-compose.yml") + result = pytester.runpytest() + result.assert_outcomes(passed=1) def test_docker_compose_project(docker_compose_project_name: str) -> None: