avast / pytest-docker

Docker-based integration tests
MIT License
406 stars 68 forks source link

Allow for overriding of pytest fixture scope #89

Closed austinkeller closed 5 months ago

austinkeller commented 1 year ago

Being able to override the pytest fixtures to have a "function" scope instead of "session" scope would be useful when using containers that may carry state between tests.

An example of a useful configuration (though hard-coded): https://github.com/Greenlight-Analytical/pytest-docker/commit/102eedb65d3ff8a9cddc285363bd31d6e8e45f15

Some boilerplate to connect a flag:

def pytest_addoption(parser):
    parser.addoption(
        "--keep-containers",
        action="store_true",
        help="Keep containers between tests. This is faster but may cause test failures from leftover state between tests.",
    )

@pytest.fixture
def keep_containers(request):
    return request.config.getoption("--keep-containers")

def keep_containers_scope(fixture_name, config):
    if config.getoption("--keep-containers", None):
        return "session"
    return "function"

@pytest.fixture(scope=keep_containers_scope)
# This annotation can apply to all fixtures, instead of the hard-coded "session" scope
mmetc commented 1 year ago

Having scope=module on the other hand is useful to run a battery of tests against a set of environments defined in the same file. At least it's a better fit for my use case, otherwise I have to run pytest multiple times.

austinkeller commented 1 year ago

@mmetc in that case, it'd be better to allow the flag to be set to the desired scope directly, so something like

def pytest_addoption(parser):
    parser.addoption(
        "--containers-scope",
        type=str,
        default="function"
        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",
    )

@pytest.fixture
def containers_scope_fixture(request):
    return request.config.getoption("--containers-scope")

def containers_scope(fixture_name, config):
    return config.getoption("--containers-scope-fixture", "function"):

@pytest.fixture(scope=containers_scope)
# This annotation can apply to all fixtures, instead of the hard-coded "session" scope
shaohme commented 1 year ago

Having scope=module on the other hand is useful to run a battery of tests against a set of environments defined in the same file. At least it's a better fit for my use case, otherwise I have to run pytest multiple times.

That is true, but sometimes I need different compose.yaml configs for different set of tests. If I haven't got different scopes, I need to run pytest for each set of tests needing the same docker-compose yaml.

SRv6d commented 8 months ago

I would've expected a function scope to be the default, are there any blockers to implementing this?

BetterCallBene commented 5 months ago

I need this for my project. Is it possible that this mr comes into the next release?