-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Description
What's the problem this feature will solve?
The problem to be solved here is how to organize families of fixtures with pure metadata to avoid looking up fixture values from their names to determine if the fixture belongs to a given family or not.
I'm looking for a way that I can mark up a bunch of fixtures spread around a bunch of plugin and conftest files etc some of which are marked up with the simple standard markers pytest.mark.metaFoo. I wish to then lookup those marks from the FixtureDef instances retained in the fixture manager to do some dynamic container creations from these fixture families identified by their markers alone. I wish to do this family identification via markers because fixture naming convention alone is inadequate for my use case where looking up fixture values for those fixtures which match a naming convention can cause recursion loops for those fixtures that hold dependencies on the fixture I'm trying to dynamically populate with the fixtures of a given family but not others. This is where marker metadata would be a powerful differentiator.
Describe the solution you'd like
I'd like to be able to decorate my fixtures with regular pytest markers as such (which is valid syntax today) but with that marker metadata able to be crawled and looked up from the request fixture object and ideally populated in the FixtureDef instances.
# plugin_1.py
import pytest
@pytest.mark.fixA
@pytest.mark.other
@pytest.fixture
def fixture_foo():
return "foo"
@pytest.mark.fixB
@pytest.fixture
def fixture_bar():
return "bar"
# plugin_2.py
import pytest
@pytest.mark.fixA
@pytest.fixture
def fixture_2foo():
return "2foo"
@pytest.mark.fixB
@pytest.fixture
def fixture_2bar():
return "2bar"From the above I need a fixture that dynamically returns a container of the fixture values ["foo", "2foo"] just by discovering the fixtures in scope and contributing to that container the values of all fixtures which match the family criteria corresponding to the pytest markers I wish to filter upon.
Alternative Solutions
So far I've been leaning on a combination of fixture naming conventions and value lookups to get this organization by families accomplished but that will not work when I get to the complex case where the different fixture subfamilies share the same naming convention and thus become undifferentiable. In that scenario the fixtures are given different definitions from alternate plugins where I don't want them to continue to be selected by name anymore because the naming convention then blurs between two families of fixtures that have no way to be differentiated by name alone (hence the need for the markers to do the job).
Here's the partial solution I've attempted so far that lets me organize fixtures by the naming convention pattern matching a suffix
@pytest.fixture(autouse=True)
def fix_list(request):
print("fix_list")
foo_fixtures = [request.getfixturevalue(fix_name) for fix_name in request._fixturemanager._arg2fixturedefs if fix_name.endswith("_foo")]
return foo_fixtureshttps://stackoverflow.com/a/77154959/1330381
Additional context
When I probe the fixture definition from a global scope I see that the fixtures have a pytestmark attribute, eg
fixture_foo.pytestmark
[Mark(name='fixA', args=(), kwargs={}), Mark(name='other', args=(), kwargs={})]
I can't see how to navigate to that data from the request fixture. If there is an existing means today that would solve all my problems and I could mark up my fixtures today and solve some gnarly problems.