Django 测试数据库使用的是本地 db.sqlite3,而不是内存中的 运行
Django test database is using local db.sqlite3, not running in memory
当我 运行 Django 测试将数据插入数据库时,它将插入到我的本地 db.sqlite3
并在测试完成后 保留 它。我不希望发生这种情况,也不应该 according to the docs:
Regardless of whether the tests pass or fail, the test databases are
destroyed when all the tests have been executed.
我的单元测试:
from unittest import TestCase
from web.constants import USER_TYPE_CONTRACTOR
from web.models import User
class LoginTestCase(TestCase):
def setUp(self):
self.demo_user_1_username = 'c2'
User.objects.create(username=self.demo_user_1_username, password='c12345678')
def test_user_defaults_to_contractor(self):
demo_user_1 = User.objects.get(username=self.demo_user_1_username)
self.assertEqual(demo_user_1.user_type, USER_TYPE_CONTRACTOR)
def doCleanups(self):
"""Delete demo data from database"""
# I needed to do this as workaround
# demo_user_1 = User.objects.get(username=self.demo_user_1_username)
# demo_user_1.delete()
用户 c2
现在在 db.sqlite3
中,所以当我 运行 再次测试时,它失败了,因为用户名 c2
已经存在。
我在 settings.py
中尝试过这样做:
DATABASES = {
'default': dj_database_url.config(conn_max_age=600)
}
DATABASES['default']['TEST'] = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'test_db.sqlite3'),
}
但是test_db.sqlite3
没有创建。
如何使用内存中的 sqlite3 数据库,以便在测试时不影响我的本地数据库?
这里的问题,@Chris 如何在直接使用 unitetest
模块中的 TestCase
中提到,层次链如下所示:
TestCase->TransactionTestCase->SimpleTestCase->unittest.TestCase
如何documentation总结:
[TestCase] - This is the most common class to use for writing tests in Django. It
inherits from TransactionTestCase (and by extension SimpleTestCase).
If your Django application doesn’t use a database, use SimpleTestCase.
这里:
When I run Django tests that inserts data into the database, it will
insert to my local db.sqlite3 and preserve it when the tests finishes.
注意:在您的情况下,测试使用的是实际数据库,这会导致数据丢失并填充模拟数据。 永远不要使用这样的工作流程!
实际上,测试根本不能使用您的实际数据库,默认情况下 sqlite3
后端 Django 将处理内存数据库,可以使用标志 --keepdb
控制数据库的销毁.一般来说,流程如下:
- 将使用与实际相同的凭据创建测试数据库
但名称将是
test_<actual_db_name>
。甚至可以在测试执行之间访问数据库,以防在测试通过后每次都没有删除它 (--keepdb
)。
- 测试执行前,测试数据库将处于实际状态
python manage.py migrate
已执行,但您可以通过覆盖 MIGRATION_MODULES
环境变量来省略迁移执行。
因此,解决方案是改用 django.test.TestCase
用法。
当我 运行 Django 测试将数据插入数据库时,它将插入到我的本地 db.sqlite3
并在测试完成后 保留 它。我不希望发生这种情况,也不应该 according to the docs:
Regardless of whether the tests pass or fail, the test databases are destroyed when all the tests have been executed.
我的单元测试:
from unittest import TestCase
from web.constants import USER_TYPE_CONTRACTOR
from web.models import User
class LoginTestCase(TestCase):
def setUp(self):
self.demo_user_1_username = 'c2'
User.objects.create(username=self.demo_user_1_username, password='c12345678')
def test_user_defaults_to_contractor(self):
demo_user_1 = User.objects.get(username=self.demo_user_1_username)
self.assertEqual(demo_user_1.user_type, USER_TYPE_CONTRACTOR)
def doCleanups(self):
"""Delete demo data from database"""
# I needed to do this as workaround
# demo_user_1 = User.objects.get(username=self.demo_user_1_username)
# demo_user_1.delete()
用户 c2
现在在 db.sqlite3
中,所以当我 运行 再次测试时,它失败了,因为用户名 c2
已经存在。
我在 settings.py
中尝试过这样做:
DATABASES = {
'default': dj_database_url.config(conn_max_age=600)
}
DATABASES['default']['TEST'] = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'test_db.sqlite3'),
}
但是test_db.sqlite3
没有创建。
如何使用内存中的 sqlite3 数据库,以便在测试时不影响我的本地数据库?
这里的问题,@Chris 如何在直接使用 unitetest
模块中的 TestCase
中提到,层次链如下所示:
TestCase->TransactionTestCase->SimpleTestCase->unittest.TestCase
如何documentation总结:
[TestCase] - This is the most common class to use for writing tests in Django. It inherits from TransactionTestCase (and by extension SimpleTestCase). If your Django application doesn’t use a database, use SimpleTestCase.
这里:
When I run Django tests that inserts data into the database, it will insert to my local db.sqlite3 and preserve it when the tests finishes.
注意:在您的情况下,测试使用的是实际数据库,这会导致数据丢失并填充模拟数据。 永远不要使用这样的工作流程!
实际上,测试根本不能使用您的实际数据库,默认情况下 sqlite3
后端 Django 将处理内存数据库,可以使用标志 --keepdb
控制数据库的销毁.一般来说,流程如下:
- 将使用与实际相同的凭据创建测试数据库
但名称将是
test_<actual_db_name>
。甚至可以在测试执行之间访问数据库,以防在测试通过后每次都没有删除它 (--keepdb
)。 - 测试执行前,测试数据库将处于实际状态
python manage.py migrate
已执行,但您可以通过覆盖MIGRATION_MODULES
环境变量来省略迁移执行。
因此,解决方案是改用 django.test.TestCase
用法。