Skip to content
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

indirectly parameterized session-scoped fixtures aren't #13159

Open
jclerman opened this issue Jan 22, 2025 · 4 comments
Open

indirectly parameterized session-scoped fixtures aren't #13159

jclerman opened this issue Jan 22, 2025 · 4 comments
Labels
status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity topic: fixtures anything involving fixtures directly or indirectly type: question general question, might be closed after 2 weeks of inactivity

Comments

@jclerman
Copy link

jclerman commented Jan 22, 2025

Summary

When a fixture is passed parameters from a test, via @pytest.mark.parameterize's indirect=True, per-parameter-value session-scoping does not work. For a given passed value, the fixture may be created/torn down multiple times.

Minimal example

Code

import pytest
from _pytest.fixtures import FixtureRequest

@pytest.fixture(scope="session")
def case_fixture(request: FixtureRequest):
    n = request.param
    print(f"Setting up case {n}")
    yield f"case_fixture {n}"
    print(f"Tearing down case {n}")

@pytest.mark.parametrize(
    "case_fixture, expected",
    [
        (1, "case_fixture 1"),
        (2, "case_fixture 2"),
        (1, "case_fixture 1"),
    ],
    indirect=["case_fixture"],
    scope="session"
)
def test_one(case_fixture, expected):
    assert case_fixture == expected

Expected Result

% pytest -k test_fixture_p -s
Test session starts (platform: darwin, Python 3.11.10, pytest 8.2.2, pytest-sugar 1.0.0)
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /Users/jclerman/git/backend-integration-tester
configfile: pyproject.toml
plugins: ddtrace-2.14.4, cov-5.0.0, sugar-1.0.0, icdiff-0.9, benchmark-4.0.0, anyio-4.6.2.post1, asyncio-0.25.1
asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=function
collected 3 items / 0 deselected / 3 selected
Setting up case 1
 tests/test_fixture_parameterization.py ✓
Setting up case 2
 tests/test_fixture_parameterization.py ✓✓
Tearing down case 2
Tearing down case 1
 tests/test_fixture_parameterization.py ✓✓✓

Actual Result

% pytest -k test_fixture_p -s
Test session starts (platform: darwin, Python 3.11.10, pytest 8.2.2, pytest-sugar 1.0.0)
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /Users/jclerman/git/backend-integration-tester
configfile: pyproject.toml
plugins: ddtrace-2.14.4, cov-5.0.0, sugar-1.0.0, icdiff-0.9, benchmark-4.0.0, anyio-4.6.2.post1, asyncio-0.25.1
asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=function
collected 3 items / 0 deselected / 3 selected
Setting up case 1
 tests/test_fixture_parameterization.py ✓
Tearing down case 1
Setting up case 2
 tests/test_fixture_parameterization.py ✓✓
Tearing down case 2
Setting up case 1
Tearing down case 1
 tests/test_fixture_parameterization.py ✓✓✓

Platform details

Pytest 8.2.2
Python 3.11.10
MacOS 15.2 (Sequoia)

Pip list output
% pip list
Package                       Version     Editable project location
----------------------------- ----------- ----------------------------------------------
alabaster                     0.7.16
annotated-types               0.7.0
anyio                         4.6.2.post1
arq                           0.26.1
Babel                         2.15.0
backend_integration_tester    0.1.0       /Users/jclerman/git/backend-integration-tester
bytecode                      0.15.1
cachetools                    5.5.0
certifi                       2024.7.4
cfgv                          3.4.0
chardet                       5.2.0
charset-normalizer            3.3.2
click                         8.1.7
colorama                      0.4.6
coverage                      7.6.0
ddtrace                       2.14.4
Deprecated                    1.2.14
distlib                       0.3.8
dnspython                     2.7.0
docutils                      0.18.1
email_validator               2.2.0
envier                        0.6.1
fastapi                       0.115.3
filelock                      3.15.4
h11                           0.14.0
hiredis                       3.1.0
httpcore                      1.0.6
httpx                         0.27.2
icdiff                        2.0.7
identify                      2.6.0
idna                          3.7
imagesize                     1.4.1
importlib_metadata            8.4.0
iniconfig                     2.0.0
Jinja2                        3.1.4
MarkupSafe                    2.1.5
mypy                          1.14.1
mypy-extensions               1.0.0
nest-asyncio                  1.6.0
nodeenv                       1.9.1
opentelemetry-api             1.27.0
packaging                     24.1
pip                           24.3.1
platformdirs                  4.2.2
pluggy                        1.5.0
pprintpp                      0.4.0
pre-commit                    3.7.1
protobuf                      5.28.3
py-cpuinfo                    9.0.0
pydantic                      2.10.4
pydantic_core                 2.27.2
pydantic-extra-types          2.10.2
Pygments                      2.18.0
pyproject-api                 1.8.0
pytest                        8.2.2
pytest-asyncio                0.25.1
pytest-benchmark              4.0.0
pytest-cov                    5.0.0
pytest-icdiff                 0.9
pytest-sugar                  1.0.0
python-dateutil               2.9.0.post0
PyYAML                        6.0.1
re-assert                     1.1.0
redis                         5.2.1
regex                         2024.11.6
requests                      2.32.3
sentry-sdk                    2.17.0
setuptools                    75.6.0
sironabackend                 0.66.0
six                           1.17.0
sniffio                       1.3.1
snowballstemmer               2.2.0
Sphinx                        7.3.7
sphinx-rtd-theme              1.3.0
sphinxcontrib-applehelp       1.0.8
sphinxcontrib-devhelp         1.0.6
sphinxcontrib-htmlhelp        2.0.5
sphinxcontrib-jquery          4.1
sphinxcontrib-jsmath          1.0.1
sphinxcontrib-qthelp          1.0.7
sphinxcontrib-serializinghtml 1.1.10
starlette                     0.41.0
termcolor                     2.4.0
toml                          0.10.2
tox                           4.23.2
typing_extensions             4.12.2
tzdata                        2024.2
urllib3                       2.2.2
uvicorn                       0.32.0
uvloop                        0.21.0
virtualenv                    20.26.3
wrapt                         1.16.0
xmltodict                     0.14.2
zipp                          3.20.2
@RonnyPfannschmidt
Copy link
Member

Pytest cannot know if a duplicate is intentional or accidentally

See pytest -v

Also see --setup-plan

@RonnyPfannschmidt
Copy link
Member

A important note I forgot

Multiple parameter variants of a fixture may not exist at the same time

@RonnyPfannschmidt RonnyPfannschmidt added type: question general question, might be closed after 2 weeks of inactivity status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity topic: fixtures anything involving fixtures directly or indirectly labels Jan 23, 2025
@jclerman
Copy link
Author

A important note I forgot

Multiple parameter variants of a fixture may not exist at the same time

I think this latter point is the limit I'm running into. If that could be overcome, it would be very helpful for my use cases. Doing so would sidestep any issues related to case (or test) ordering.

Would it be possible to fix that, either in pytest or in a plugin?

@RonnyPfannschmidt
Copy link
Member

There's currently no plan/concepts for such fixtures in a builtin way

It's so deep in pytest that a plugin can't safely mess with it

A workaround could be a managing fixture that creates data and essentially having the concrete parameterized fixture leak so the managing fixture has to clean up all instances

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity 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