-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Instantiate fixtures by scope order in test function requests #3306
Instantiate fixtures by scope order in test function requests #3306
Conversation
testing/python/test_closures.py
Outdated
""") | ||
items, _ = testdir.inline_genitems() | ||
request = FixtureRequest(items[0]) | ||
assert request.fixturenames == 'm1 f1'.split() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might break suites by accident: even though the test function is declared (f1, m1)
, pytest will sort by scope so it will actually instantiate unrelated fixtures in m1, f1
order.
It seems this is actually our expectation and was the root cause for #2405.
testing/python/test_closures.py
Outdated
@@ -0,0 +1,145 @@ | |||
"""WIP: this test class will be moved to fixture.py in this module""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Temporarily using a separate module for those tests because it makes switching between master
and this branch to run tests.
testing/python/test_closures.py
Outdated
class TestScopeOrdering(object): | ||
|
||
@pytest.mark.parametrize('use_mark', [True, False]) | ||
def test_func_closure_module_auto(self, testdir, use_mark): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only test in this module which passes on master
is this one when use_mark=False
: in this case, both m1
and f1
are autouse
, which we do sort by scope on master
:
Lines 1017 to 1019 in 1b53538
autousenames.sort( | |
key=lambda x: self._arg2fixturedefs[x][-1].scopenum) | |
return autousenames |
I have not reviewed the code. The general mental model that people have for fixtures is that they are run in scope order. |
@okken thanks for the feedback! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to go in, its yet another indicator that fixtures have a really really bad internal base
It seems we are leaning on merging this, still needs changelog, doc updates to document the behavior and rebase it to @RonnyPfannschmidt do you think the tests I put in place are enough? |
@nicoddemus given what we are trying to model we can only aim for best efford, and it seems like the tests cover the behaviours we understand and want to have i would hope at some point we can have unittests for this, but right now what you did is great |
Was the order that fixtures were expected to run just not defined before? @okken, when you say "I think the current behavior of file order overriding scope order is insane and a bug," do you mean that fixtures are currently executed using file order? If so, how does that work exactly? Scope order is probably a good heuristic for how expensive a fixture is, as all else being equal, users will give more expensive fixtures higher scopes so they're run less often. Unfortunately, I can imagine situations where there are lower-scoped fixtures that are more expensive than session-scoped fixtures, say with a session-scoped fixture that makes a connection to a test database but class- or module-scoped fixtures that do some complicated and slow operations to get the test database into the right state. For an inexpensive fixture, though, there's always the option of tightening the scope so it gets run more often, which doesn't cost that much because it's cheap, so it doesn't take priority over a more-expensive fixture with a lower scope, while it may not be possible to broaden the scope of an expensive fixture. Since it makes the common use-case better while still allowing the uncommon use-case (with some additional work), I think this is a good compromise. Edited (had the wrong configuration on the toy example): |
Hey @ceridwen thanks for the feedback.
Yes, your guess sounds right to me.
I'm not planning to tackle #3161 here, it definitely should be a separate PR. Feel free to start working on it. The consensus so far here and in the mailing list is that the change is correct, so I will most likely finish this PR on Monday and we can merge it. |
I'll wait until the merge. The biggest thing I need is agreement on what the correct order should be. I don't know the history of reorder_atscope() but the function is overcomplicated and hard to understand, and I have no idea what order it's supposed to produce, if there ever was such a thing. |
"[1-a]" works fine using fnmatch_lines, but "[a-1]" breaks horribly inside `re`.
e6e29bf
to
59e7fd4
Compare
Folks I think this is now ready for another round of reviews. 👍 |
from my pov we can merge |
This is a stab at fixing #2405.
This fixes the reproducible example posted by @jaraco:
And also this one which I used to debug the problem:
All tests pass (which is encouraging), but given that this might alter the order of evaluation of fixtures (albeit it seems to actually fix it) we might want to target
features
instead.Still a WIP: needs more tests, changelog, some docstrings, etc.