gpt4 book ai didi

python - 使用 Sqlite3 运行 Django Unittest 时缺少表

转载 作者:IT老高 更新时间:2023-10-28 20:53:37 26 4
gpt4 key购买 nike

我正在尝试使用 Django 1.3 运行单元测试。通常,我使用 MySQL 作为我的数据库后端,但由于单个单元测试的启动速度非常慢,所以我使用的是 Sqlite3。

所以为了我的单元测试切换到 Sqlite3,在我的 settings.py 中我有:

import sys
if 'test' in sys.argv:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME':'/tmp/database.db',
'USER' : '',
'PASSWORD' : '',
'HOST' : '',
}
}

当我使用 python manage.py test myapp.Test.test_myfunc 运行我的单元测试时,我得到了错误:

DatabaseError: no such table: django_content_type

谷歌搜索显示有一个 fewpossible reasons为此error ,这些似乎都不适用于我。我没有运行 Apache,所以我看不出权限会是什么问题。正在创建文件/tmp/database.db,因此/tmp 是可写的。应用程序 django.contrib.contenttypes 包含在我的 INSTALLED_APPS 中。

我错过了什么?

编辑:我在 Django 1.5 中再次遇到了这个问题,但建议的解决方案都不起作用。

最佳答案

在 Django 1.4、1.5、1.6、1.7 或 1.8 中,应该足以使用:

if 'test' in sys.argv:
DATABASES['default']['ENGINE'] = 'django.db.backends.sqlite3'

不必重写 TEST_NAME1,也不必调用 syncdb 来运行测试。正如@osa 所指出的,SQLite 引擎的默认设置是在内存中创建测试数据库 (TEST_NAME=':memory:')。调用 syncdb 应该是不必要的,因为 Django 的测试框架将通过调用 syncdbmigrate 自动执行此操作,具体取决于 Django 版本。2 您可以使用 manage.py test -v [2|3] 观察这一点。

非常松散地说 Django 通过以下方式设置测试环境:

  1. 从您的 settings.py
  2. 加载常规数据库 NAME
  3. 发现并构建您的测试类(__init__() 被调用)
  4. 将数据库 NAME 设置为 TEST_NAME
  5. 的值
  6. 针对数据库 NAME
  7. 运行测试

问题来了:在第 2 步,NAME 仍然指向您的常规(非测试)数据库。如果您的测试包含类级查询或 __init__() 中的查询,它们将针对常规数据库运行,这可能不是您所期望的。这在 bug #21143 中确定.

不要这样做:

class BadFooTests(TestCase):
Foo.objects.all().delete() # <-- class level queries, and

def __init__(self):
f = Foo.objects.create() # <-- queries in constructor
f.save() # will run against the production DB

def test_foo(self):
# assert stuff

因为这些将针对 NAME 中指定的数据库运行。如果在此阶段 NAME 指向一个有效的数据库(例如您的生产数据库),则查询将运行,但可能会产生意想不到的后果。如果您已覆盖 ENGINE 和/或 NAME 使其不指向预先存在的数据库,则会引发异常,因为尚未创建测试数据库:

django.db.utils.DatabaseError: no such table: yourapp_foo  # Django 1.4
DatabaseError: no such table: yourapp_foo # Django 1.5
OperationalError: no such table: yourapp_foo # Django 1.6+

改为:

class GoodFooTests(TestCase):

def setUp(self):
f = Foo.objects.create() # <-- will run against the test DB
f.save() #

def test_foo(self):
# assert stuff

因此,如果您看到错误,请检查您的测试是否包含任何可能在您的测试类方法定义之外访问数据库的查询。


[1] 在 Django >= 1.7 中,DATABASES[alias]['TEST_NAME']deprecated赞成DATABASES[alias]['TEST']['NAME']
[2] 见db/backends/creation.py

中的 create_test_db()方法

关于python - 使用 Sqlite3 运行 Django Unittest 时缺少表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7336130/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com