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