From a001fd0cfd036db9180897480cfff43997e93f05 Mon Sep 17 00:00:00 2001 From: Benedikt Date: Thu, 25 Jan 2024 11:44:38 +0100 Subject: [PATCH] feat: configurable container scopes (#103) * feat: allow to change the scope of the container through the parameter container-scope * Fix: change to standard scope session again * fix: default container scope of config.getoption * fix: revert bump version * fix: formating of test_fixtures with black * fix: formating and removing unused imports * fix: extend test 'test_general_container_scope' to cover all cases * chore: update README.md --------- Co-authored-by: Benedikt Koenig --- README.md | 11 ++++++++- src/pytest_docker/__init__.py | 14 ++++++++++++ src/pytest_docker/plugin.py | 21 ++++++++++++------ tests/test_fixtures.py | 42 ++++++++++++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 65322e3..6dcfb67 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,16 @@ def docker_compose_file(pytestconfig): ``` ## Available fixtures -All fixtures have `session` scope. + +By default the scope of the fixtures are `session` but can be changed with +`pytest` command line option `--container-scope `: + +```bash +pytest --container-scope +``` + +For available scopes and descriptions +see https://docs.pytest.org/en/6.2.x/fixture.html#fixture-scopes ### `docker_ip` diff --git a/src/pytest_docker/__init__.py b/src/pytest_docker/__init__.py index 2c0888c..ffb2e96 100644 --- a/src/pytest_docker/__init__.py +++ b/src/pytest_docker/__init__.py @@ -1,3 +1,4 @@ +import pytest from .plugin import ( docker_cleanup, docker_compose_command, @@ -18,3 +19,16 @@ "docker_cleanup", "docker_services", ] + + +def pytest_addoption(parser: pytest.Parser) -> None: + group = parser.getgroup("docker") + group.addoption( + "--container-scope", + type=str, + action="store", + default="session", + help="The pytest fixture scope for reusing containers between tests." + " For available scopes and descriptions, " + " see https://docs.pytest.org/en/6.2.x/fixture.html#fixture-scopes", + ) diff --git a/src/pytest_docker/plugin.py b/src/pytest_docker/plugin.py index 79979a6..b90798b 100644 --- a/src/pytest_docker/plugin.py +++ b/src/pytest_docker/plugin.py @@ -10,6 +10,13 @@ import pytest +@pytest.fixture +def container_scope_fixture(request): + return request.config.getoption("--container-scope") + +def containers_scope(fixture_name, config): + return config.getoption("--container-scope", "session") + def execute(command, success_codes=(0,)): """Run a shell command.""" try: @@ -42,7 +49,7 @@ def get_docker_ip(): return match.group(1) -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def docker_ip(): """Determine the IP address for TCP connections to Docker containers.""" @@ -129,7 +136,7 @@ def execute(self, subcommand): return execute(command) -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def docker_compose_command(): """Docker Compose command to use, it could be either `docker compose` for Docker Compose V2 or `docker-compose` for Docker Compose @@ -138,7 +145,7 @@ def docker_compose_command(): return "docker compose" -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def docker_compose_file(pytestconfig): """Get an absolute path to the `docker-compose.yml` file. Override this fixture in your tests if you need a custom location.""" @@ -146,7 +153,7 @@ def docker_compose_file(pytestconfig): return os.path.join(str(pytestconfig.rootdir), "tests", "docker-compose.yml") -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def 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.""" @@ -159,7 +166,7 @@ def get_cleanup_command(): return "down -v" -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def docker_cleanup(): """Get the docker_compose command to be executed for test clean-up actions. Override this fixture in your tests if you need to change clean-up actions. @@ -173,7 +180,7 @@ def get_setup_command(): return "up --build -d" -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def docker_setup(): """Get the docker_compose command to be executed for test setup actions. Override this fixture in your tests if you need to change setup actions. @@ -207,7 +214,7 @@ def get_docker_services( docker_compose.execute(docker_cleanup) -@pytest.fixture(scope="session") +@pytest.fixture(scope=containers_scope) def docker_services( docker_compose_command, docker_compose_file, diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index e15dd3d..a60cdab 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -1,5 +1,5 @@ import os.path - +import pytest HERE = os.path.dirname(os.path.abspath(__file__)) @@ -15,8 +15,48 @@ def test_docker_compose_project(docker_compose_project_name): def test_docker_cleanup(docker_cleanup): assert docker_cleanup == "down -v" + def test_docker_setup(docker_setup): assert docker_setup == "up --build -d" + def test_docker_compose_comand(docker_compose_command): assert docker_compose_command == "docker compose" + + +def test_default_container_scope(pytester): + pytester.makepyfile( + """ + import pytest + @pytest.fixture(scope="session") + def dummy(docker_cleanup): + return True + + def test_default_container_scope(dummy): + assert dummy == True + """ + ) + + result = pytester.runpytest() + result.assert_outcomes(passed=1) + + +@pytest.mark.parametrize("scope", ["session", "module", "class"]) +def test_general_container_scope(testdir, request, scope): + params = [f"--container-scope={scope}"] + assert request.config.pluginmanager.hasplugin("docker") + + testdir.makepyfile( + f""" + import pytest + @pytest.fixture(scope="{scope}") + def dummy(docker_cleanup): + return True + + def test_default_container_scope(dummy): + assert dummy == True + """ + ) + + result = testdir.runpytest(*params) + result.assert_outcomes(passed=1)