pytest icon indicating copy to clipboard operation
pytest copied to clipboard

over-riden/extended fixtures that self-depend don't pass over dependend fixtures for parameterization

Open rgilton opened this issue 1 year ago • 4 comments

When I have the following situation:

  • A fixture main that uses another fixture param
  • A test class TestFoo that:
    • overrides the main fixture with a fixture that uses the "parent" fixture
    • has a test test_foo that uses the main fixture and is marked to be parametrised over param

pytest gives me the error "Failed: In test_foo: function uses no argument 'param'".

I was expecting the "parent" main fixture to receive the parametrised param value.

The code:

from pytest import fixture, mark


@fixture
def param() -> int:
    return 1


@fixture
def main(param: int) -> int:
    return sum(range(param + 1))


class TestFoo:
    @fixture
    def main(self, main: int) -> int:
        return main

    @mark.parametrize("param", [2])
    def test_foo(self, main: int) -> None:
        assert main == 3

The error:

$ pytest
======================================== test session starts =========================================
platform linux -- Python 3.12.2, pytest-8.0.2, pluggy-1.4.0
rootdir: /home/rob/tmp/py
collected 0 items / 1 error                                                                          

=============================================== ERRORS ===============================================
___________________________________ ERROR collecting test_class.py ___________________________________
In test_foo: function uses no argument 'param'
====================================== short test summary info =======================================
ERROR test_class.py::TestFoo - Failed: In test_foo: function uses no argument 'param'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================== 1 error in 0.05s ==========================================

pip list output:

$ uv pip list
Package   Version
--------- -------
iniconfig 2.0.0  
packaging 23.2   
pluggy    1.4.0  
pytest    8.0.2

OS: Fedora 39.

rgilton avatar Mar 08 '24 13:03 rgilton

Add indirect=True

RonnyPfannschmidt avatar Mar 08 '24 18:03 RonnyPfannschmidt

Add indirect=True

Hi @RonnyPfannschmidt. I tried this, as I think this is what you meant:

from pytest import fixture, mark


@fixture
def param() -> int:
    return 1


@fixture
def main(param: int) -> int:
    return sum(range(param + 1))


class TestFoo:
    @fixture
    def main(self, main: int) -> int:
        return main

    @mark.parametrize("param", [2], indirect=True)
    def test_foo(self, main: int) -> None:
        assert main == 3

But I still get: ERROR test_class.py::TestFoo - Failed: In test_foo: function uses no fixture 'param'

rgilton avatar Mar 09 '24 14:03 rgilton

Ok,this looks like a possible bug wrt fixture overrides

Please add the parameter to the second main fixture as well,

RonnyPfannschmidt avatar Mar 09 '24 14:03 RonnyPfannschmidt

Please add the parameter to the second main fixture as well,

Yes, it works if the main fixture within TestFoo takes the param fixture but does not use it:

class TestFoo:
    @fixture
    def main(self, main: int, param: int) -> int:
        return main

    @mark.parametrize("param", [2])
    def test_foo(self, main: int) -> None:
        assert main == 3

rgilton avatar Mar 10 '24 13:03 rgilton