If you need to run tests under a "real" database but don't want to use your main database for it because it's too slow, you can use sqlite for the particular test.
import tempfile
from django.db import models, connections
from django.db.backends.sqlite3.base import DatabaseWrapper as SqliteConnection
@pytest.fixture(scope="function")
def sqlite_db(django_db_blocker):
"""
Runs tests inside a sqlite3, making it slightly faster.
When using this, avoid using the `@pytest.mark.django_db` and put the name `sqlite_db` as your
first function parameter.
Example:
def test_something(sqlite_db):
# This test will run inside a unique and isolated sqlite db
with connection.cursor() as c, connection.schema_editor() as editor:
editor.create_model(User) # c.execute('CREATE TABLE ...')
user = User.objects.create(username='test') # c.execute('INSERT INTO ...')
assert user.username == 'test'
editor.delete_model(User) # c.execute('DROP TABLE ...')
"""
# Tells pytest-django that it's ok to use the db
django_db_blocker.unblock()
# Create a backup of the current db connection
original_connection = connections['default']
with tempfile.NamedTemporaryFile() as f:
db_settings = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': f.name,
'TIME_ZONE': None,
'CONN_MAX_AGE': 0,
'OPTIONS': {},
'AUTOCOMMIT': True,
}
# Override the `default` connection with the sqlite one
connections['default'] = SqliteConnection(db_settings)
# Call your test
yield
# Clean up
connections['default'].close()
# Put back the connection
connections['default'] = original_connection
# Tell pytest-django to restore the db lock
django_db_blocker.restore()
Note: the lack of @pytest.mark.django_db
decorator on the example test (docstring).
Note: this will give you a brand new db with NOTHING inside, you need to create your models and populate it if you want to use it. See editor = connections['default'].schema_editor(); editor.create_model(User)
and don't forget to clean up after yourself: editor.delete_model(User)