-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Add a function to detect if pytest is running #9502
Comments
We currently just document how to do this, probably in a way similarly to what your plugin does. Note you could also just check We do have a |
Also see pytest-dev/pytest-django#333 which has some additional considerations and use-cases around this. |
I'm OK with this solution. It would also remove that env var from |
A while ago I had an idle thought that something like this should be a python feature. I was thinking a builtin constant In the Rust language for example it is very common to interleave unit tests with the code they're testing in the same file using an attribute. In Python this would be: def fibonacci(n): ...
if __test__:
import pytest
def test_fibonacci(n):
assert fibonacci(10) == 55
with pytest.raises(ValueError):
fibonacci(-1)
def factorial(n): ...
if __test__:
def test_factorial(n):
assert factorial(50) == 30414093201713378043612608166064768844377641568960512000000000000 Not for everyone, but I think there are cases I would have used this. |
after the drop of python 3.6 we can use https://docs.python.org/3/library/contextvars.html i would propose to use this for gathering whether pytest is running i woudl strictly oppose exposing sometihng like config as a contextvar however unless we had a stack for nested pytest session |
Yes, I noted in the description why this doesn't work for the case of the django settings file 😊 I like the idea of the A contextvars seem like they'd also require |
One can use Personally im -1 on adding easy and obvious fast paths to make it easy to keep messy global configuration around This stems from stuff going horrendously wrong every time a project uses that and then suddenly some tests need to run with different configurations or multiple configurations |
🤔 Idk why I didn't think of that, thanks for the hint. I think for now I will try Agree that it can go wrong as complexity creeps in. |
I stopped my overengineering when I arrived at: def we_are_running_via_pytest() -> bool:
"""Detect if we are running via pytest."""
# When we are running via pytest it is loaded to the sys modules dictionary.
_we_are_running_via_pytest: bool = 'pytest' in sys.modules
return _we_are_running_via_pytest Source: https://docs.python.org/3/library/sys.html#sys.modules Use it like so: def get_configuration() -> Configuration:
configuration: Configuration
if we_are_running_via_pytest():
print('Creating test configuration.')
configuration = _get_test_configuration()
else:
print('Creating runtime configuration.')
configuration = _get_runtime_configuration()
return configuration |
Thanks everyone! I'm closing this for now, with the recommended solution being: is_running_pytest = "pytest" in sys.modules If somebody wants to contribute that to the documentation, it would be great! |
But I think "pytest" in sys.modules returning True if theres a pytest import makes it kinda error prone |
This might be over engineered but I think this works better and helps to avoid one of the edge case with
Do let me know if theres a case where this will not work |
too many magic constants |
I archived my pytest-is-running project btw. |
What do you think about this This has been discussed above contexvar will not help as mentioned in this comment |
Also I think this will work with I dont think it inspect.stack being slow is an issue in this case unless it is noticeably slow , because we should only use it in places like django settings(which is only run once per server start, in every other cases(like when a ut is running) we can use |
I am using |
I am aware of cases where this doesnt work like |
Thanks @dheerajck for the PR. 👍 |
Thanks for reviewing my code and letting me know about some good coding practices :) |
What's the problem this feature will solve?
Django settings modules often load environment variables from a
.env
file:Loading from
.env
is not desirable during test runs. Environment variables added for local debugging may affect the test run in unexpected ways, such as making remote API calls.The settings module should therefore only load the
.env
file if pytest isn't running:Changing behaviour during tests is usually undesirable, but here it's done to isolate the test run, which is a good thing.
pytest documents a pattern to change behaviour using fixtures here: https://docs.pytest.org/en/latest/example/simple.html#detect-if-running-from-within-a-pytest-run . Unfortunately this techinque is incompatible with this particular problem. pytest-django's fixtures load the settings module early, before fixtures from
conftest.py
fixtures run, so the pattern cannot be applied. And environment variable changes cannot be undone after the fact.To solve this I made pytest-is-running, which can be used like so:
pytest-is-running works because plugin fixtures can load early, and it uses hooks with
tryfirst=True
.Describe the solution you'd like
Rather than have a documented workaround and plugin, I'd like to see a function in core pytest that provides the ability to check if pytest is running. It could simplify things for those using the both the documented pattern and the plugin.
It would also be good if the solution could somehow avoid the cost of doing
import pytest
, so that non-test pathways do not import the heap of stuff in pytest only to ignore it because pytest isn't running. The plugin is deliberately structured to avoid this.Alternative Solutions
I wrote the plugin.
Additional context
none
The text was updated successfully, but these errors were encountered: