pytest-dev / pytest-dev/pytest

Parametrized fixture being used by other fixtures

Open
#7,737 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

topic: fixtures
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

This issue is split from https://github.com/pytest-dev/pytest/issues/1953.

The following test shows a case which is not currently supported: foo is parametrized, and used indirectly through bar, which is also overwritten closer to the test:

    def test_extend_fixture_with_parametrized_dependency(self, testdir):
        testdir.makeconftest("""
            import pytest

            @pytest.fixture(params=[1])
            def foo(request):
                return request.param

            @pytest.fixture
            def bar(foo):
                return foo
        """)
        testfile = testdir.makepyfile("""
            import pytest

            @pytest.fixture
            def bar(bar):
                return bar * 2

            def test_spam(bar):
                assert bar == 2
        """)
        result = testdir.runpytest(testfile)
        result.stdout.fnmatch_lines(["*1 passed*"])

The current fixture parametrization mechanism implemented in FixtureManager doesn't follow the fixture dependencies to apply fixture parametrization, it only looks at the argument names of the function explicitly (those in Metafunc).

More investigation is needed.

Workaround

A workaround is to re-specify the dependency to foo in bar.

    def test_extend_fixture_with_parametrized_dependency(self, testdir):
        testdir.makeconftest("""
            import pytest

            @pytest.fixture(params=[1])
            def foo(request):
                return request.param

            @pytest.fixture
            def bar(foo):
                return foo
        """)
        testfile = testdir.makepyfile("""
            import pytest

            @pytest.fixture
            def bar(bar, foo):
                return bar * 2

            def test_spam(bar):
                assert bar == 2
        """)
        result = testdir.runpytest(testfile)
        result.stdout.fnmatch_lines(["*1 passed*"])

Thanks to @jmoldow for the original report.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproducing test in the issue and inspect FixtureManager's fixture-parametrization handling alongside Metafunc's argument processing. Trace how parametrized dependencies are discovered through overridden fixtures. Done means the test passes for the indirect dependency and regression coverage preserves the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.