I am setting up a very simple Django project and with a very simple test like:
def test_name(self):
t = Thing.objects.create(name='a')
print(t.id)
import time
time.sleep(30)
self.assertEqual('a', t.name)
The tests passes of course, but the database (TEST
database) doesn't get populated with my Thing
model information, even though I can actually see its id
as you can see my script.
When I connect into the database, the Thing
table is always empty (I also saw some comments about it in the documentation).
Now, how can I tell Django to actually populate the data? I am using mysql, and checking the complete logs I see Django is creating a SAVEPOINT
before populating data (that is not committed) and once the test passes, it goes back into that previous SAVEPOINT
.
I am using:
Django==2.0.1
mysqlclient==1.3.12
pytest==3.3.2
pytest-django==3.1.2
I would like Django to actually populate the TEST
database, with the information from my tests and at the end drop that database, that's why I am assuming Django is creating a completely new database just for tests.
The pendant to the django.test.TransactionTestCase
for pure function tests is the marker
pytest.mark.django_db(transaction=True)
from pytest-django
. Example (with the sqlite3
backend):
@pytest.mark.django_db(transaction=True)
def test_model_written_to_db():
obj = MyModel.objects.create(name='foo')
assert obj.id == 1
conn = sqlite3.connect('/tmp/mytestdatabase.sqlite3')
cur = conn.cursor()
cur.execute("SELECT * FROM backend_mymodel")
assert len(cur.fetchall()) == 1
If you want to apply the marker automatically to all tests, you can do that with a custom pytest_collection_modifyitems
hook. In your conftest.py
:
import pytest
def pytest_collection_modifyitems(items):
for item in items:
item.add_marker(pytest.mark.django_db(transaction=True))
Now you can remove the pytest.mark.django_db
marker from the above test and it will still behave the same.
However, custom hooks or pytest
fixtures don't work for the unittest
-style testcases subclassing django.test.TestCase
, so your best bet would be indeed subclassing django.test.TransactionTestCase
, as suggested Ghariani Mohamed in his answer.
if you are using the django TestCase class, which subclasses the TransactionTestCase class, the database will always be reset to the original state.
https://docs.djangoproject.com/en/2.0/topics/testing/tools/#django.test.TestCase
https://docs.djangoproject.com/en/2.0/topics/testing/tools/#django.test.TransactionTestCase
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With