我有一个Django应用程序需要 settings
属性的形式:
RELATED_MODELS = ('appname1.modelname1.attribute1',
'appname1.modelname2.attribute2',
'appname2.modelname3.attribute3', ...)
然后挂钩他们的post_save信号以更新一些其他固定模型,具体取决于定义的 attributeN
.
我想测试这种行为,测试应该工作,即使这个应用程序是项目中唯一的一个(除了它自己的依赖项,不需要安装其他包装应用程序) . 如何为测试数据库创建和附加/注册/激活模拟模型? (或者它可能吗?)
允许我使用测试夹具的解决方案会很棒 .
10 回答
您可以将测试放在应用程序的
tests/
子目录中(而不是tests.py
文件),并将tests/models.py
包含在仅测试模型中 .然后提供一个测试运行脚本(example),其中包含您在
INSTALLED_APPS
中的tests/
"app" . (这并没有INSTALLED_APPS
中的测试应用程序,但我很少发现从项目运行可重用的应用程序测试很有用,并且默认情况下不会使用Django 1.6 . )( NOTE :下面描述的替代动态方法仅适用于Django 1.1,如果您的测试用例子类
TransactionTestCase
- 这会显着降低您的测试速度 - 并且在Django 1.7中根本不再有效 . 它's left here only for historical interest; don' t使用它 . )在测试开始时(即在setUp方法中,或在一组doctests的开头),您可以动态地将
"myapp.tests"
添加到INSTALLED_APPS设置,然后执行以下操作:然后在测试结束时,您应该通过恢复旧版本的INSTALLED_APPS并再次清除应用缓存来进行清理 .
This class封装了模式,因此它不会使测试代码混乱不堪 .
@ paluh的答案需要在非测试文件中添加不需要的代码,根据我的经验,@ carl的解决方案不适用于使用灯具所需的django.test.TestCase . 如果你想使用django.test.TestCase,你需要确保在加载灯具之前调用syncdb . 这需要覆盖_pre_setup方法(将代码放入setUp方法是不够的) . 我使用自己的TestCase版本,让我用测试模型添加应用程序 . 它的定义如下:
此解决方案仅适用于
django
的早期版本(在1.7
之前) . 您可以轻松查看您的版本:原始回复:
这很奇怪,但形式我的作品非常简单:
将tests.py添加到您要测试的应用中,
在这个文件中只定义测试模型,
下面放了你的测试代码(doctest或TestCase定义),
下面我给出了一些定义了仅用于测试的Article模型的代码(它存在于someapp / tests.py中,我可以用以下方法测试它:./ manage.py test someapp):
单元测试也使用这种模型定义 .
我分享了我在项目中使用的solution . 也许它有助于某人 .
pip install django-fake-model
创建假模型的两个简单步骤:
1)在任何文件中定义模型(我通常在测试用例附近的测试文件中定义模型)
2)将装饰器
@MyFakeModel.fake_me
添加到TestCase或测试功能 .此装饰器在每次测试之前在数据库中创建表,并在测试后删除表 .
您也可以手动创建/删除表:
MyFakeModel.create_table()
/MyFakeModel.delete_table()
我选择了一种稍微不同的,虽然更加耦合的方法来动态创建仅用于测试的模型 .
我将所有测试保存在
files
应用程序中的tests
子目录中 .tests
子目录中的models.py
文件包含我的仅测试模型 . 耦合部分在这里,我需要将以下内容添加到我的settings.py
文件中:我还在我的测试模型中设置了db_table,因为否则Django会创建名为
tests_<model_name>
的表,这可能导致与另一个应用程序中的其他测试模型冲突 . 这是我的测试模型:引自a related answer:
我已经找到了django 1.7测试模型的方法 .
基本的想法是,让你的
tests
成为一个应用,并将tests
添加到INSTALLED_APPS
.这是一个例子:
我有不同的
settings
用于不同的目的(参考:splitting up the settings file),即:settings/default.py
:基本设置文件settings/production.py
:用于 生产环境settings/development.py
:用于开发settings/testing.py
:用于测试 .在
settings/testing.py
中,您可以修改INSTALLED_APPS
:settings/testing.py
:并确保为测试应用设置了适当的标签,即
common/tests/apps.py
common/tests/__init__.py
,设置正确的AppConfig
(参考号:Django Applications) .然后,生成db migration by
最后,您可以使用param
--settings=<your_project_name>.settings.testing
运行测试 .如果你使用py.test,你甚至可以删除一个
pytest.ini
文件和django的manage.py
.py.test
这是我用来做这个的模式 .
我编写了这个方法,我在TestCase的子类版本上使用 . 它如下:
然后,我创建了一个特殊的测试特定的models.py文件,类似于
myapp/tests/models.py
,它不包含在INSTALLED_APPS中 .在我的setUp方法中,我调用create_models_from_app('myapp.tests')并创建正确的表 .
这种方法唯一的"gotcha"是你真的不想创建模型时间
setUp
运行,这就是我捕获DatabaseError的原因 . 我想这个方法的调用可以放在测试文件的顶部,这样可以更好一些 .结合你的答案,特别是@ slacy's,我这样做了:
这样,您不会尝试多次创建数据库表,也不需要更改INSTALLED_APPS .
如果您正在编写可重用的django-app, create a minimal test-dedicated app for it !
将
myapp
和test_myapp
同时添加到INSTALLED_APPS
,在那里创建模型,这很好!我已经完成了所有这些答案以及django机票7835,我终于采用了完全不同的方法 . 我希望我的应用程序(以某种方式扩展queryset.values())能够独立测试;另外,我的软件包确实包含了一些模型,我希望测试模型和软件包之间有一个清晰的区别 .
就在那时我意识到在包中添加一个非常小的django项目更容易!这也允许更清晰的代码分离恕我直言:
在那里你可以干净利落,没有任何黑客定义你的模型,你知道它们将在你那里运行测试时创建!
如果您没有编写独立的,可重复使用的应用程序,您仍然可以这样:创建一个
test_myapp
应用程序,并将其添加到您的INSTALLED_APPS中,只能在单独的_1694694中!