pytest icon indicating copy to clipboard operation
pytest copied to clipboard

Add public API to get value of fixture by its name

Open gryznar opened this issue 1 year ago • 6 comments

What's the problem this feature will solve?

In lower version, it was possible to perform sth like this:

from pytest import FixtureRequest

value = FixtureRequest(item).getfixturevalue('fixture_name')

With pytest 8.0 this is not possible because FixtureRequest is abstract. Public API to get value of fixture would mitigate this problem.

Describe the solution you'd like

The best will be to add method to Item | Function to get fixture value. Alternatively will be to add similar API somewhere in _pytest.fixtures.py and reexport it in pytest.__init__.py Ability to get value from fixture by its name would be really useful to perform actions which requires fixture at hook level. In my example, I am using driver fixture to pass selenium WebDriver to tests. After test teardown I am taking screenshot if test was failed at pytest_runtest_makereport scope. Lack of available API at pytest level makes it impossible to get fixture if error happens at setup (driver is not present at item.funcargs:

class TestFoo:
    @pytest.fixture(autouse=True)
    def setup(self, driver: WebDriver):
        ...
    
    def test_foo():
        ...

Alternative Solutions

Missing. All code to inspect fixtures is hidden under private API (in _pytest)

gryznar avatar Feb 07 '24 13:02 gryznar

the request.getfixturevaluehelper can help there

it was never valid to make a external instance of FixtureRequest

please outline the usecase

RonnyPfannschmidt avatar Feb 07 '24 16:02 RonnyPfannschmidt

Maybe I am unaware of different possibilities to get value of any fixture at hook level. Are there any?

gryznar avatar Feb 07 '24 16:02 gryznar

There is no way to just get fixtures at the hook level

Doing so is likely to compromise the consistency of the setup state and worked by accident

RonnyPfannschmidt avatar Feb 07 '24 17:02 RonnyPfannschmidt

Yeah, but worked and was very practical in my usecase ;) Access to fixtures at hook level could be very handy

śr., 7 lut 2024, 18:01 użytkownik Ronny Pfannschmidt < @.***> napisał:

There is no way to just get fixtures at the hook level

Doing so is likely to compromise the consistency of the setup state and worked by accident

— Reply to this email directly, view it on GitHub https://github.com/pytest-dev/pytest/issues/11944#issuecomment-1932489631, or unsubscribe https://github.com/notifications/unsubscribe-auth/AVR4OCFUJJTIIIAH7ZFHMSTYSOXOTAVCNFSM6AAAAABC5Z3AKGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZSGQ4DSNRTGE . You are receiving this because you authored the thread.Message ID: @.***>

gryznar avatar Feb 07 '24 17:02 gryznar

How does the driver fixture look like?

bluetech avatar Feb 08 '24 11:02 bluetech

Something like this:

from typing import Iterator
from pytest import fixture
from selenium.webdriver import Chrome

@fixture
def driver() -> Iterator[Chrome]:
    driver_ = Chrome()
    yield driver_
    driver_.quit()

gryznar avatar Feb 08 '24 11:02 gryznar

I have another use-case for this. It’s about committing all the database model instances created in fixtures to the database in one go before invoking the test method: https://stackoverflow.com/a/56013856

torotil avatar Mar 07 '24 17:03 torotil

Closing this as duplicate of #2471. :+1:

nicoddemus avatar Mar 08 '24 12:03 nicoddemus