Description
What's the problem this feature will solve?
Django settings modules often load environment variables from a .env
file:
from pathlib import Path
import dotenv
BASE_DIR = Path(__file__).resolve().parent.parent
dotenv.load_dotenv(dotenv_path=BASE_DIR / ".env")
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:
from pathlib import Path
import dotenv
BASE_DIR = Path(__file__).resolve().parent.parent
if ... # pytest is not running
dotenv.load_dotenv(dotenv_path=BASE_DIR / ".env")
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:
from pathlib import Path
import dotenv
import pytest_is_running
BASE_DIR = Path(__file__).resolve().parent.parent
if not pytest_is_running.is_running():
dotenv.load_dotenv(dotenv_path=BASE_DIR / ".env")
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