pytest icon indicating copy to clipboard operation
pytest copied to clipboard

stabilizing fixture APIs (maybe specifically TopRequest)

Open eqvinox opened this issue 1 year ago • 0 comments

related prior reading: #3639

pytest's fixture mechanism is part of pytest's private APIs, to some degree understandably so: referring to a fixture in a test function's parameters is very specific to pytest "native" test functions.

However, there are plugins that could still benefit from having their own ways of referencing/using fixtures, in particular if they provide some kind of environment for tests to be created in that is still Python. (I don't believe there are significant issues with creating fixtures from plugins, at least I'm not seeing any. It is invoking/referencing fixtures I'm concerned with.)

What's the problem this feature will solve?

Since the API is private, it occasionally is changed (most recently a9d1f55a0f9b6f536967caf0f317cdbc8034a073), and all plugins that hook into fixtures need to be updated.

Describe the solution you'd like

In the long run, it would be nice for pytest's fixture API to stabilize. This is of course a bit of a moonshot, and there are good arguments that this might be very costly for pytest for very little gain to a small number of plugins.

As a more attainable step, I'd like to suggest removing the @final from _pytest.fixtures.TopRequest (or creating a related class that is part of the public API and can be used) to allow pytest plugins to request fixtures. I think this would fill 99% of plugin fixture request needs — the subrequest machinery feels far less useful to interact with in plugins.

Alternative Solutions

Using pytest internal APIs works, it just creates headaches when things change, and is particularly ugly to deal with if the plugin tries to support multiple versions of pytest (in my case I need to support 7.x and 8.x).

It might also be possible to use Python "meta-hackery", i.e. dynamically constructing functions with the needed fixtures as parameters and then feeding those into pytest's standard machinery to let it fill in fixtures. However, this would involve some quite arcane code and very odd "using things sideways upside-down" interactions with pytest. I've looked at this and given up on it for the time being.

eqvinox avatar Jul 18 '24 21:07 eqvinox