-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
tox and pytest runs can behave differently when "-p something.conftest" is specified #3326
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
this is an attempt to workaround this issue: pytest-dev/pytest#3326
Just a note, my The proper workaround is to put the plugin into The original problem is that pytest treats |
I posted a question in the mailing list a few years back, and the conclusion for a workaround was the same. |
i wonder, however, how we could fix this properly so people don't run into this. What do you think about making "-p" force a nodeid of '', i.e. any import path you specified will be a global plugin for the test run? Probably also pytest_plugins=... definitions should behave this way. The only reason for using Maybe with a 4.0 we could see about making "-p" cause empty nodeids, and if it causes troubles, revert it in 4.0.1 (i somehow doubt it's going to cause troubles but who knows). |
Perhaps the proper solution would be to keep track explicitly of which plugins should be based on location and which plugins should be in the global namespace, instead of relying implicitly on the name |
yes, so far this "keeping track of which plugins are based on location" was done through checking the basename (basically conftest.py files are location dependent, all others are global). Here is a refined suggestion for what to change user-side:
This way, if people used "-p" or pytest_plugins to load a nested conftest early (they could do this i think but it's probably only done rarely -- in none of my projects FWIW) they could use preload_conftest instead which expresses the intent much clearner. Looking at the code of PytestPluginManager.register i think it's not too difficult (dragons non-withstanding). Adding a new flag to pytest_plugin_registered (..., as_conftest=False|True) or something similar should be doable without too much hassle. |
we dont need a new flag, we can check if pytest_configure did happen instead |
also lets please avoid bleeding internals in that way |
@RonnyPfannschmidt I was mostly describing things from the user perspective above. Can't make sense of your comments -- do you e.g. mean to imply with your "check if pytest_configure happened" the behaviour for plugin loading would behave differently before and afterwards? I invested a lot of words to be clear, as did Bruno, please try to be a bit more verbose so i don't have to guess/think so much of what you might mean. |
bascially we should parse fixtures of all plugins registred outside of the collection loop for all tests, and otherwise do the normal conftest logic for now if we want to differentiate metadata we should put the calls into more select places instead of side-channeling |
@RonnyPfannschmidt IIUC, you mean that we can already separate non-root conftest files from other plugins: Lines 372 to 374 in 6f95189
So we don't need any extra flag or marker to distinguish between non-local and global Lines 997 to 1011 in 6f95189
Is that it @RonnyPfannschmidt? |
correct |
If it's possible to do things automatically then it's of course preferable! I am still a bit skeptical because i think it's unclear that if someone specifies "-p somepackage.conftest" what the precise intention/expectation is, today. It might be for adding a nested plugin to get its command line options. It might be from a different package whose fixtures should become available. At the point of looking at the "-p" option pytest_configure has not happened so i am not sure how it could be used to distinguish the intentions. Or am i missing something? |
i would go as far as issuing a warning from the pluginmanager itself if anything named conftest is specified as normal plugin, its error prone, confusing, and extraction into a plugin is as trivial as renaming the file, and referring it in a fresh conftest |
What is error prone and confusing about having a plugin named conftest.py file, can you please elaborate? When we started using pytest more prominently at work it was very common for people to put their fixtures in |
conftests are path bound by initial design, plugins aren't as such we should keep it at that and warn peole when they use the bad pattern |
I see, thanks. TBH I'm not entirely convinced, can't we just tell people if they are using If the answer is no, then I think we should issue a deprecation warning and remove support for |
@nicoddemus we could support it, but to me it seems anything making the logic for that would end up as a fragile mess although we do have the option to go for changing the registration pattern from being implemented as a hook to being implemented in consider_* methods of pluginmanager personally i'd like ensure that conftests are local plugins, its relatively easy to provide plugin files after all and in case of something not wanting to do that, its stilll trivial to import in a local conftest instead of linking it as a plain plugin lets keep in mind that a large amount of todays maintenance issues are due to not keeping separate concerns separate |
I see, thanks. I may have a shallow view, but currently conftest files are special-cased in |
Did a little bit of debugging and wanted to share my findings here:
I have an sdist
muacrypt
which contains atest_muacrypt
package and a conftest file inside.In another project i have a
pytest.ini
containingaddopts = -p test_muacrypt.conftest
. This makes all fixtures and command line options available in a normal pytest run. fine.Problem: When i run tox the fixtures from that plugin are not loaded.
This is surprising from a pure user perspective (tox and pytest runs should not have such differences).
Turns out, the problematic code is in this FixtureManager method:
in my case,
test_muacrypt.conftest
has a basename ofconftest.py
and it's path (inside .tox) is relative to the project root. So the plugin gets a "nodeid" and lookups for fixtures from that plugin fail, because the requesting side will not be a child id of that '.tox/py27/.../conftest.py`. Without tox, Plugins which reside outside a project rootdir will get an empty nodeid and are thus found properly.Not sure how to fix this in pytest properly yet.
A work aground for me is to put the plugin into
test_muacrypt.testing_plugin
or so and import everything from the conftest file there.The text was updated successfully, but these errors were encountered: