Skip to content

Commit

Permalink
feat: configurable container scopes (#103)
Browse files Browse the repository at this point in the history
* 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 <benedikt.koenig@agile-robots.com>
  • Loading branch information
BetterCallBene and Benedikt Koenig authored Jan 25, 2024
1 parent 508b82d commit a001fd0
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 9 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <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`

Expand Down
14 changes: 14 additions & 0 deletions src/pytest_docker/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from .plugin import (
docker_cleanup,
docker_compose_command,
Expand All @@ -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",
)
21 changes: 14 additions & 7 deletions src/pytest_docker/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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."""

Expand Down Expand Up @@ -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
Expand All @@ -138,15 +145,15 @@ 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."""

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."""
Expand All @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
42 changes: 41 additions & 1 deletion tests/test_fixtures.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import os.path

import pytest

HERE = os.path.dirname(os.path.abspath(__file__))

Expand All @@ -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)

0 comments on commit a001fd0

Please sign in to comment.