pytest-dev / pytest-dev/pytest
API to get a test's fixture definitions during parametrization
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 14.5k
- Forks
- 3.4k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 35
Description
What's the problem this feature will solve?
During pytest_generate_tests, I want to be able to get the functions that define a test's fixture dependencies to determine whether and how to parametrize the test (including fixtures requested via other fixtures).
Specifically, pytest-asyncio can run tests with different event loop configurations. It needs to apply this parametrization to all tests that use its async fixtures, including sync tests.
Describe the solution you'd like
A public API on Metafunc to get the fixture definitions upon which a test depends, without running the fixtures.
pytest.FixtureDef is already public. What I am looking for is a way to get the definitions used by a particular test during pytest_generate_tests.
Something like this could work:
def pytest_generate_tests(metafunc):
funcs = [fd.func for fd in metafunc.fixturedefs] # proposed new metafunc.fixturedefs API
# use the above to decide whether to call metafunc.parametrize(...), etc.
Metafunc.fixturedefs could be a read-only property that returns a tuple of pytest.FixtureDef objects. My specific use case needs supported access to each definition's .func, though. The returned fixture definitions for a test should follow fixture resolution rules (i.e., handle the different ways to request a fixture, overrides, and fixture configuration via parametrization).
I don't need a fixed iteration order or for the API to pre-empt future changes to the dependencies (I'm not sure it'd even be possible to deal with future parametrization). It would be fine (and, IMO, intuitive) for each access to reflect the fixture definitions so far. I'd like the plugin to be able to read the dependencies after other hooks apply parametrization, and then apply further parametrization itself.
Alternative Solutions
There doesn't seem to be a solution at the moment other than attempting to re-implement fixture resolution via private APIs.
This mapping gives access to fixture definitions:
fixturedefs = metafunc._arg2fixturedefs["resource"]
functions = [fixturedef.func for fixturedef in fixturedefs]
However, it includes definitions that the test does not use.
# conftest.py
import pytest
@pytest.fixture
def resource():
return "base"
# test_example.py
import pytest
@pytest.fixture
def resource(resource):
return resource
def test_example(resource):
pass
Here, the mapping contains both resource definitions, and the proposed API should return both functions. If the local fixture takes no arguments and returns "replacement", the mapping still contains both definitions. The proposed API should then return only the local fixture function.
The private traverse_fixture_closure function resolves dependency names, but does not return the definitions it visits.
Additional context
This would help close https://github.com/pytest-dev/pytest-asyncio/issues/1501.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Metafunc during pytest_generate_tests and inspect _arg2fixturedefs alongside traverse_fixture_closure to understand current fixture resolution. Done means a supported, read-only API returns the definitions actually used by the test, including overrides and nested dependencies, without running fixtures; add coverage for the resolution examples in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100