pytest-dev / pytest-dev/pytest-django
Customising `django_db_modify_db_settings` is superseeded by Django's own caching.
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.5k
- Forks
- 367
- PR merge metrics
- No merged PRs in 30d
Description
Hey all,
I ran into an issue trying to customize django_db_modify_db_settings.
In my root level conftest.py I tried to make the tests run a sqlite in-memory database using (instead of my project settings.py which point to a postgres database).
@pytest.fixture(scope='session')
def django_db_modify_db_settings():
from django.conf import settings
settings.DATABASES = {
'default': {
'ENGINE':'django.db.backends.sqlite3',
'NAME': ':memory:'
}
}
However, when the tests were run, any database interaction (Model's get, create, etc) would attempt to reach out to the original postgres database setting (aka
Doing a bit of digging, I think I can see what is happening.
When setup_databases (from here) is called, it in turn calls:
get_unique_databases_and_mirrors, which in turn calls:ConnectionHandlerwhich caches the databases from settings.
After ConnectionHandler is initalized, which I believe is at django.setup() it is fixed and stays pointed to whatever database settings it initalized with, even if they change down the line.
My current work around to this, is to override the DATABASE settings in my own pytest_configure in my project's conftest.py AND to set DJANGO_SETTINGS_MODULE there (e.g. no pytest.ini).
e.g.
os.environ['DJANGO_SETTINGS_MODULE'] = 'app.config.settings'
def pytest_configure():
settings.DATABASES = {
'default': {
'ENGINE':'django.db.backends.sqlite3',
'NAME': ':memory:'
}
}
I believe setting the DJANGO_SETTINGS_MODULE there causes the _setup_django in pytest_load_initial_conftests to be skipped over, thus the it is called later, in the plugin's pytest_configure.
Resource:
Here is a sample project with it in action. It's a bit big, so here are the important bits.
- conftest.py
- settings.py
- Sample test
- pytest outpyt showing test failures for db tests, unit tests pass
I'm using Python: 3.6.6 and the following package versions...
Django==2.1
pytest==3.7.4
pytest-django==3.0.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the sample project, starting with tests/conftest.py and the sample database test. Read pytest_django/plugin.py around pytest_load_initial_conftests and pytest_configure, then compat.py where setup_databases is called. Done means the documented django_db_modify_db_settings customization selects SQLite instead of the original PostgreSQL configuration for database tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- backend, databases, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100