I want a test database created for my default database in Django latest version, for that I configured in project settings.py
file as below.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'TEST': {
'NAME': BASE_DIR / 'test_db.sqlite3',
}
}
}
I have a model Topic
in my models.py
file and have run makemigrtions
& migrate
cmds to have table in sqlite db. I have created TestTopic
class in my app(first_app) tests.py
file as below
from django.test import TestCase,SimpleTestCase
from .models import Topic
class TestTopic(TestCase):
def setUp(self):
Topic.objects.create(top_name='Test topic1')
Topic.objects.create(top_name='Test topic2')
Topic.objects.create(top_name='Test topic3')
def test_create_topic(self):
all_topics = Topic.objects.count()
self.assertEqual(all_topics, 3)
def tearDown(self) -> None:
return super().tearDown()
I am executing cmd below to run my app(first_app) tests. Passing --keepdb
for preserving test_db
.
py manage.py test first_app --keepdb
After this I see test case pass. But when I am checking test_db.sqlite
in sqlite db browser app to see test topics I created in test case, I do not see them. I want to have those records in test_db
until I clear them manually or in tearDown
method of my test case. ( Below is sqlite db browser of test_db.sqlite
topics table.
the -keepdb
option will only keep the schema of the database but not the data inside. The data created on each test is never committed to the database, Django creates a database transaction before executing one test method and at the end of the test that transaction gets rolled back if you're using the TestCase class.
A TestCase, on the other hand, does not truncate tables after a test. Instead, it encloses the test code in a database transaction that is rolled back at the end of the test. This guarantees that the rollback at the end of the test restores the database to its initial state. (It's not a good idea to save data on the database during the tests, that migh break the idempotence of the tests. Meaning that you might get different results if you execute the same test twice)
if you use the setUpTestData
then the data will be preserved during the whole set of tests of the class:
class TestFoo(TestCase):
@classmethod
def setUpTestData(cls):
User.objects.create(...)
User.objects.create(...)
User.objects.create(...)
def test_something(self):
self.assertEqual(1 + 1, 2)
def tearDown(self) -> None:
print(User.objects.count()) # you'll have the 3 users here
return super().tearDown()