Pytest: How to reuse same fixture implementation with different scopes?

Created on 24 Apr 2018  路  5Comments  路  Source: pytest-dev/pytest

Hello!

I am looking for a way to reuse same fixture or same fixture implementation in different scopes. I would like to avoid copy-pasting implementation in multiple fixtures with different scopes defined. What would be recommended approach?

So far I have thought about (ab)using yield from as in following example. Not sure if this can lead to some unexpected issues.

@pytest.fixture(session='function')
def my_fixture_fun():
    yield from fixture_impl()

@pytest.fixture(scope='module')
def my_fixture_mod():
    yield from fixture_impl()

@pytest.fixture(scope='session')
def my_fixture_ses():
    yield from fixture_impl()

def fixture_impl():
    # Rather long on complicated fixture implementation here
    print('SETUP: Fixture implmentation')
    yield
    print('TEARDOWN: Fixture implmentation')

Any other ideas or suggestions?
Thanks!

fixtures question

Most helpful comment

@jurisbu correct

with fixture_impl(...) as result:
   yield result

All 5 comments

GitMate.io thinks possibly related issues are https://github.com/pytest-dev/pytest/issues/538 (Fixture scope documentation), https://github.com/pytest-dev/pytest/issues/1552 (Suggestion: add new 'parametrization' fixture scope), https://github.com/pytest-dev/pytest/issues/2732 (Fixture scope mixing?), https://github.com/pytest-dev/pytest/issues/3393 (Customize the fixture ordering on the same scope level), and https://github.com/pytest-dev/pytest/issues/668 (autouse fixtures break scope rules).

iriginally multi scoped fixtures was planned for pytest 3.0, but it demonstrated impossible to implement without a major refactoring, what you do there is the common workaround, but its suggested to use a contextmanager instead of yield from

@RonnyPfannschmidt Thanks for such a prompt response. As per your suggestions of using contexmanager instead, do you mean something along these lines?

@pytest.fixture(scope='module')
def my_fixture_mod():
    with fixture_impl():
        pass


@contextmanager
def fixture_impl():
    print('BEFORE: Fixture implmentation')
    yield
    print('AFTER: Fixture implmentation')

@jurisbu correct

with fixture_impl(...) as result:
   yield result

Satisfactory answer received. Closing.

Was this page helpful?
0 / 5 - 0 ratings