-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
How to mark up fixtures with metadata for segregating collections of fixtures in scope #11462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Taking a look at the callstack for where pytest/src/_pytest/fixtures.py Lines 1698 to 1708 in 1a16bac
I'll see if snooping around any of these objects at this point in the
|
Aha, just found it, so obj still has the
presumably I could extract the markers list before the call to |
I went ahead and printed any fixture which doesn't have
Perhaps one approach would be to default to the empty list if the pytestmark attribute is missing. fixture_makers = obj.pytestmark if hasattr(obj,"pytestmark") else []
obj = get_real_method(obj, holderobj)
...
fixture_def = FixtureDef(
fixturemanager=self,
baseid=nodeid,
argname=name,
func=obj,
scope=marker.scope,
params=marker.params,
markers = fixture_markers,
unittest=unittest,
ids=marker.ids,
) perhaps there's a better way to map this information that could be looked up in an alternate structure beside the fixture manager where I could take the names of the fixtures present in the keys of the fixture manager and just lookup in this alternate datasource the fixtures and their markers, |
Markers intentionally do not work on fixtures and do not transfer Its not correctly manageable in quite a number of edge cases surrounding fixtures, fixture overrides and scoping/Parameterization |
can you elaborate on the terminology of 'work on' and 'do not transfer' here please. If I'm not mistaken I recall a really good rich conversation over in #1368 that I was keen to tune in on that brought up this transferring terminology in the context of test cases that used a particular marked fixture. If I recall correctly that notion of transferring was the concept of taking markers from fixtures and transitively applying them to any test case which happened to use the marked up fixtures. That's not quite the use case I'm wrestling with however. I want the markers on the fixtures not to produce a convenience marker test case filtering scheme but form a basis for organizing and filtering the fixtures themselves. My focus isn't about the test cases which may or may not use those fixtures I hope to organize but basically I want metadata to be used to produce a transcendent derivative fixture from other fixtures that are already in scope. In a nutshell Fixtures created by other fixtures. Maybe I can get some insight into the commit that added There's a curious comment over there...
for sure the
would you say markers on fixtures is still a grey area or something more rejected at this later date from the time of those above exchanges? Maybe another syntax that could possibly accomplish this organizational attribute I wish to get access to is to use custom kwargs within the fixtures, such as...
Is that syntax that I could tie into somehow and fetch from |
looks like there's no pytest/src/_pytest/fixtures.py Lines 1259 to 1269 in 1a16bac
Snooping around that class pytest/src/_pytest/fixtures.py Lines 1209 to 1210 in 1a16bac
at which point I can see the connection to deprecated code pytest/src/_pytest/deprecated.py Lines 125 to 128 in 1a16bac
but interestingly enough that link doesn't have any hits to this subject any longer, maybe it did in the past? This is a bit surprising https://docs.pytest.org/en/stable/deprecations.html#applying-a-mark-to-a-fixture-function |
It was never support,but people still wrote code as if it was |
Another angle I may be able to map against is the This may be by design perhaps for reasons unclear to me For other plugins, the baseid is the empty string (always matches). what is the matching constraint being discussed here? pytest/src/_pytest/fixtures.py Lines 987 to 1000 in 1a16bac
|
come to think of it more generally, baseids, markers, whatever the source, I just need some metadata orthogonal to the fixture name which I can form associations with. |
Looks like with import inspect
@pytest.fixture
def fix_list(request):
matching_fixtures = []
for fixture_name, fixture_def in request._fixturemanager._arg2fixturedefs.items():
if inspect.getabsfile(fixture_def.func).endswith("_my_naming_convention.py"):
matching_fixtures.append(request.getfixturevalue(fixture_name))
yield matching_fixtures |
I think we never intended such code to work, and may deliberately break it in future. Probably the best approach to identifying families of fixtures is to track your metadata in some way unrelated to the pytest internals! |
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 theFixtureDef
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 theFixtureDef
instances.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
https://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, egI 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.The text was updated successfully, but these errors were encountered: