python - Django 测试数据库使用本地 db.sqlite3,不在内存中运行
问题描述
当我运行将数据插入数据库的 Django 测试时,它将插入到我的本地db.sqlite3
并在测试完成时保留它。我不希望这种情况发生,也不应该根据文档:
无论测试通过还是失败,测试数据库都会在所有测试执行完毕后销毁。
我的单元测试:
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 数据库,以便在测试时不会影响我的本地数据库?
解决方案
TestCase
这里的问题,@Chris 在直接使用from模块时是如何提到的unitetest
,层次链看起来像这样:
TestCase->TransactionTestCase->SimpleTestCase->unittest.TestCase
文档摘要的方式:
[TestCase] - 这是在 Django 中编写测试最常用的类。它继承自 TransactionTestCase(并通过扩展 SimpleTestCase)。 如果您的 Django 应用程序不使用数据库,请使用 SimpleTestCase。
这里:
当我运行将数据插入数据库的 Django 测试时,它将插入到我的本地 db.sqlite3 并在测试完成时保留它。
注意:在您的情况下,测试使用的是实际数据库,这会导致数据丢失和模拟数据填充。永远不要使用这样的工作流程!
实际上,测试根本不能使用您的实际数据库,默认情况下,sqlite3
后端 Django 将处理内存数据库,可以使用 flag 控制数据库的破坏--keepdb
。一般来说,流程如下:
- 将使用与实际相同的凭据创建测试数据库,但名称为
test_<actual_db_name>
. 如果每次测试通过后都没有删除数据库,甚至可以在测试执行之间访问数据库(--keepdb
)。 - 在测试执行之前,测试数据库将处于实际执行状态,尽管您可以通过覆盖env 变量
python manage.py migrate
省略迁移执行。MIGRATION_MODULES
因此,解决方案是改用django.test.TestCase
用法。
推荐阅读
- python - 从 pandas 字典值系列中检索键集
- javascript - 我如何创建一个递增的对象数组,User1,User2 等,每个条目都附加了对象值?
- netflix-eureka - 尤里卡和领事
- terraform - Terraform - 如何在 terraform 脚本中避免 VM 的密码
- java - 票务系统+定时器
- reactjs - 更新数组对象中的一个值
- javascript - 从 Django 后端使用 Javascript 加载多个图像
- c - 为什么直接给出字符串和读取字符串时strlen返回不同的值?
- ios - 如何使用 Macaw iOS 库从 url 显示 svg
- python - 加入数据框的过滤器在 pyspark 中不起作用