Skip to content

Session scoped fixture called twice (another example) #4894

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Sup3rGeo opened this issue Mar 7, 2019 · 2 comments
Closed

Session scoped fixture called twice (another example) #4894

Sup3rGeo opened this issue Mar 7, 2019 · 2 comments
Labels
topic: fixtures anything involving fixtures directly or indirectly type: question general question, might be closed after 2 weeks of inactivity

Comments

@Sup3rGeo
Copy link
Member

Sup3rGeo commented Mar 7, 2019

Hello!

UPDATE: Environment details:

(venv) D:\pytest-simple-parametrization\otherdir>pip list
Package        Version
-------------- -------
atomicwrites   1.3.0
attrs          19.1.0
colorama       0.4.1
more-itertools 6.0.0
pip            10.0.1
pluggy         0.9.0
py             1.8.0
pytest         4.3.0
setuptools     39.1.0
six            1.12.0

Considering this very simple test case:

from pytest import fixture

@fixture(scope="session", params=[110, 220])
def param1(request):
    return request.param

@fixture(scope="module")
def setup(param1):
    print(f"I am real fixture using param1 = {param1}")

@fixture(scope="session", params=[330, 440])
def param2(request):
    return request.param

def test_normal_operation(setup, param1, param2):
    print(f"Test function using param1 = {param1} and param2 = {param2}")

Running it with --setup-show shows that param2[330] is setup twice, even though it is scoped as session:

test_scope.py
SETUP    S param1[110]
SETUP    S param2[330]
    SETUP    M setup (fixtures used: param1)
        test_scope.py::test_normal_operation[110-330] (fixtures used: param1, param2, setup).
TEARDOWN S param2[330]
SETUP    S param2[440]
        test_scope.py::test_normal_operation[110-440] (fixtures used: param1, param2, setup).
    TEARDOWN M setup
TEARDOWN S param1[110]
SETUP    S param1[220]
    SETUP    M setup (fixtures used: param1)
        test_scope.py::test_normal_operation[220-440] (fixtures used: param1, param2, setup).
TEARDOWN S param2[440]
SETUP    S param2[330]
        test_scope.py::test_normal_operation[220-330] (fixtures used: param1, param2, setup).
    TEARDOWN M setup
TEARDOWN S param2[330]
TEARDOWN S param1[220]

Is it normal or am I missing something? Thanks!

@nicoddemus nicoddemus added the type: question general question, might be closed after 2 weeks of inactivity label Mar 7, 2019
@nicoddemus
Copy link
Member

Hi @Sup3rGeo!

Unfortunately that's how the current mechanism works.

One thing that is usually not obvious is that there can be only one instance of a high-level scoped, parametrized fixture at the same type. IOW, if we have created param2[330] for a test invocation, and need param2[440] for the next test, we need to destroy param2[330] in order to create param2[440].

pytest tries to order the tests to minimize fixture setups, but it has to face a tradeoff here, because of how you are parametrizing the tests, either we need to create param1[110] twice or param2[330] twice.

To exemplify:

test_scope.py::test_normal_operation[110-330]
test_scope.py::test_normal_operation[110-440]
test_scope.py::test_normal_operation[220-440]
test_scope.py::test_normal_operation[220-330]

We avoid creating param2[440] twice by reordering the tests, but need to create param2[330] again for the last test. Another possibility would be to order the tests like this:

test_scope.py::test_normal_operation[110-330]
test_scope.py::test_normal_operation[220-330]
test_scope.py::test_normal_operation[220-440]
test_scope.py::test_normal_operation[110-440]

This would create param2[330] and param2[440] only once each, but would require us to create param1[110] twice again.

Hope that clears things up.

#3551 is about improving that order somehow, but this is a complex topic so it still needs some work.

@nicoddemus nicoddemus added the topic: fixtures anything involving fixtures directly or indirectly label Mar 7, 2019
@Sup3rGeo
Copy link
Member Author

Sup3rGeo commented Mar 7, 2019

Thanks @nicoddemus! Great explanation, will close the question as I now understand the reason why is this happening.

@Sup3rGeo Sup3rGeo closed this as completed Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: fixtures anything involving fixtures directly or indirectly type: question general question, might be closed after 2 weeks of inactivity
Projects
None yet
Development

No branches or pull requests

2 participants