在 django 单元测试中加载固定装置
Posted
技术标签:
【中文标题】在 django 单元测试中加载固定装置【英文标题】:Loading fixtures in django unit tests 【发布时间】:2011-01-29 01:30:41 【问题描述】:我正在尝试开始为 django 编写单元测试,但我对固定装置有一些疑问:
我为我的整个项目数据库(不是某些应用程序)制作了一个夹具,我想为每个测试加载它,因为看起来只为某些应用程序加载夹具是不够的。
我想将夹具存储在/proj_folder/fixtures/proj_fixture.json
。
我在我的 settings.py 中设置了FIXTURE_DIRS = ('/fixtures/',)
。
然后在我的测试用例中我正在尝试
fixtures = ['proj_fixture.json']
但我的装置无法加载。 如何解决? 如何添加搜索灯具的地方? 一般来说,是否可以为每个应用程序中的每个测试加载整个 test_db 的夹具(如果它非常小)? 谢谢!
【问题讨论】:
也许你可以使用相对路径?喜欢["../../fixtures/proj_fixture.json"]
。
我试过了,但是没用。Django只在proj_folder/app_folder/fixtures中搜索fixtures
对于那些后来发现的...这里是文档:docs.djangoproject.com/en/2.0/topics/testing/tools/… -- 在我看来,这里的具体问题是 OP 为FIXTURE_DIRS
提供的值似乎是一个绝对路径,当它可能是项目根目录的相对路径时。
TestCase fixture loading docs
【参考方案1】:
我在 TestCase 中指定了相对于项目根目录的路径,如下所示:
from django.test import TestCase
class MyTestCase(TestCase):
fixtures = ['/myapp/fixtures/dump.json',]
...
它在不使用FIXTURE_DIRS
的情况下工作
【讨论】:
不知道为什么这个答案没有得到更多的爱。这是正确的答案...您不必担心绝对的夹具路径。 我的配置可能不同,但直到我删除了第一个/
字符后它才起作用。
如果您在一个应用程序中进行本地测试,使用dump.json
似乎是可行的,因为 Django 会自动查找fixtures 文件夹。
FIXTURE_DIRS 不是必需的。 os.path.join('/a/b','/c') -> '/c';所以当没有前导斜杠时它可以工作。【参考方案2】:
好的做法是在你的 settings.py 中使用 PROJECT_ROOT 变量:
import os.path
PROJECT_ROOT = os.path.dirname(os.path.realpath(__file__))
FIXTURE_DIRS = (os.path.join(PROJECT_ROOT, 'fixtures'),)
【讨论】:
【参考方案3】:你的硬盘上真的有文件夹/fixtures/
吗?
您可能打算使用:
FIXTURE_DIRS = ('/path/to/proj_folder/fixtures/',)
【讨论】:
我相信默认情况下 django 会查找 app/fixtures,因为manage.py loaddata fixture.json
将在没有设置 FIXTURE_DIRS
变量的情况下工作。【参考方案4】:
与其创建fixtures 文件夹并在其中放置fixtures(在每个应用程序中),更好更简洁的处理方法是将所有fixtures 放在项目级别的一个文件夹中并加载它们。
from django.core.management import call_command
class TestMachin(TestCase):
def setUp(self):
# Load fixtures
call_command('loaddata', 'fixtures/myfixture', verbosity=0)
调用call_command
相当于运行:
manage.py loaddata /path/to/fixtures
【讨论】:
我同意这一点,只是想指出docs 确实意味着将它们放在单独的每个应用程序的固定器目录中。也许这首先是这个问题的根源(对我来说)。【参考方案5】:假设您有一个名为 hello_django
的项目和 api
应用程序。
以下是为其创建固定装置的步骤:
-
可选步骤:从数据库创建夹具文件:
python manage.py dumpdata --format=json > api/fixtures/testdata.json
创建测试目录:api/tests
在api/tests
中创建空文件__init__.py
创建测试文件:test_fixtures.py
-
运行测试以将夹具加载到数据库中:
python manage.py test api.tests
【讨论】:
【参考方案6】:我这样做了,我不必提供路径参考,夹具文件名对我来说就足够了。
class SomeTest(TestCase):
fixtures = ('myfixture.json',)
【讨论】:
我还想指出,.json
扩展也是可选的。
请注意,如果您没有使用良好的实践,并且您在不同的应用程序中粘贴相同的夹具并具有相同名称的细微调整,如果您没有列出一个,django 可能会加载错误的夹具测试文件中正确夹具的显式路径。不要假设它只会查看您当前应用的夹具目录。【参考方案7】:
您有两种选择,具体取决于您是否有固定装置,或者您有一组 Python 代码来填充数据。
对于灯具,请使用cls.fixtures
,如an answer 中所示,
class MyTestCase(django.test.TestCase):
fixtures = ['/myapp/fixtures/dump.json',]
对于 Python,请使用 cls.setUpTestData
:
class MyTestCase(django.test.TestCase):
@classmethod
def setUpTestData(cls):
cls.create_fixture() # create_fixture is a custom function
setUpTestData
由TestCase.setUpClass
调用。
您可以同时使用两者,在这种情况下,首先加载固定装置,因为在加载固定装置之后会调用 setUpTestData
。
【讨论】:
create_fuxture
会有什么样的代码?我正在尝试使用固定装置。即使我正确指定了它,我的测试仍在调用 db.为什么?我错过了什么?是create_fixture
逻辑吗?【参考方案8】:
您需要导入from django.test import TestCase
而不是from unittest import TestCase
。这解决了我的问题。
【讨论】:
【参考方案9】:如果您已覆盖 setUpClass
方法,请确保将 super().setUpClass()
方法作为方法中的第一行调用。加载夹具的代码在 TestCase 类中。
【讨论】:
我知道它非常基本,但仍然犯了错误:(以上是关于在 django 单元测试中加载固定装置的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 @testable 导入无法在 xcode 单元测试中加载模块
如何在 Xcode 中加载本地 json 文件以进行单元测试?
茉莉花匹配器功能未在 angularjs/karma 单元测试中加载