如何将 django 单元测试分布在多个文件上?
Posted
技术标签:
【中文标题】如何将 django 单元测试分布在多个文件上?【英文标题】:How to spread django unit tests over multiple files? 【发布时间】:2011-09-09 01:30:09 【问题描述】: 我有一个 python-django 应用程序 我正在使用unit testing framework 测试安排在模块目录下的“tests.py”文件中 我正在通过./manage.py test app
运行测试
现在..
tests.py
文件变得相当大/复杂/混乱
我想将tests.py
分解为更小的测试集合...
怎么做?
【问题讨论】:
【参考方案1】:请注意,这种方法从 Django 1.6 开始不再有效,请参阅此post。
您可以创建tests
文件夹,其中包含___init___.py
(使其成为一个包)。然后在此处添加拆分测试 .py 文件并将它们全部导入___init___.py
。
即:将test.py
文件替换为外观和行为类似于文件的模块:
在相关应用下创建tests
目录
将子模块导入app\tests\__init__.py
:
from bananas import *
from apples import *
现在您可以使用 ./manage.py,就好像它们都在一个文件中一样:
./manage.py test app.some_test_in_bananas
【讨论】:
多哈。您的意思是在我正在测试的应用程序下创建一个“测试”模块;不是称为测试的新应用程序。我现在明白了。惊人的。谢谢! @John:我再也认不出我的答案了! :-) 但是你完全正确,它太模糊了,即使是正确的——你的例子很清楚,与我原来的措辞相反。 @Tomasz.. 你的话还在那儿——完全完好无损。自从你让我走上正轨后,我才稍微充实了一点。 @John:如果这就是你的意思,我一点也不生气 :) 看到我自己的答案有点不同,这很有趣 @jMyles,如果您所说的“常规 django 测试运行器”是指python manage.py test myapp
,那么实际上这个答案确实可以正常工作。 (刚试过)【参考方案2】:
Django 1.6 中的行为发生了变化,因此不再需要创建包。只需将您的文件命名为 test*.py
。
From Django 1.7 documentation
运行测试时,测试实用程序的默认行为是 查找所有测试用例(即 unittest.TestCase 的子类) 在任何名称以 test 开头的文件中,自动构建一个测试 套件出这些测试用例,并运行该套件。
来自Django 1.6 documentation,
测试发现基于 unittest 模块的内置测试 发现。默认情况下,这将在任何名为的文件中发现测试 当前工作目录下的“test*.py”。
以前的行为,from Django 1.5 documentation:
运行测试时,测试实用程序的默认行为是 查找所有测试用例(即 unittest.TestCase 的子类) 在 models.py 和 tests.py 中,自动构建一个测试套件 那些测试用例,然后运行那个套件。
还有第二种方法可以为模块定义测试套件:如果你 在 models.py 或 tests.py 中定义一个名为 suite() 的函数, Django 测试运行器将使用该函数来构建测试套件 对于那个模块。这遵循建议的单位组织 测试。有关如何使用的更多详细信息,请参阅 Python 文档 构建一个复杂的测试套件。
【讨论】:
在 django 2.6 中它并没有真正发现任何东西...... 当前使用 Django 1.10,我想将我所有的test*.py
文件放在一个名为 tests
的文件夹中以保持文件夹清洁 - 这是可能的,但您必须运行 ./manage.py test app.tests
和所有相关文件进口需要上升一个级别(from .models
变为 from ..models
)。
将所有文件放入单个文件夹tests
,我只使用python manage.py test
开始测试。重要的是,用前缀 test 命名文件夹、类和方法。【参考方案3】:
Tomasz 所说的答案是正确的。但是,确保__init__.py
中的导入与您的文件结构匹配可能会变得乏味。
要自动检测文件夹中的所有测试,您可以将其添加到__init__.py
:
import unittest
def suite():
return unittest.TestLoader().discover("appname.tests", pattern="*.py")
这将允许您运行./manage.py test appname
,但不会处理运行特定测试。为此,您可以使用此代码(也在 __init__.py
中):
import pkgutil
import unittest
for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
module = loader.find_module(module_name).load_module(module_name)
for name in dir(module):
obj = getattr(module, name)
if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
exec ('%s = obj' % obj.__name__)
现在您可以通过manage.py test app
运行所有测试或通过manage.py test app.TestApples
运行特定测试
【讨论】:
第二块放在哪里? 这两部分都进入__init__.py
请注意,如果您的任何测试包名称与在测试运行期间导入的***模块名称一致,则 pkgutil sn-p 将导致导入失败,因为测试被添加为 @987654330 @。一个快速的解决方法是del
任何导致上述问题之后的问题。 (或者你可以重命名你的文件夹;))
这很好,但我遇到了一个错误,在运行应用程序级别测试 (python manage.py test appName
) 时,第二位代码会抛出一个错误,指出 __path__
不可用。我通过将第二个 sn-p 包装在 if '__path__' in locals():
检查中来避免它,这起到了作用。感谢您的回答!
+1 这也确保 init 文件符合通用编码标准,即没有 * 或未使用的导入【参考方案4】:
只要让你的目录结构像这样:
myapp/
__init__.py
tests/
__init__.py
test_one.py
test_two.py
...
...
python manage.py test myapp
将按预期工作。
【讨论】:
【参考方案5】:http://docs.python.org/library/unittest.html#organizing-tests 谈到将文件拆分为模块,上面的部分有一个示例。
【讨论】:
我在 rtfm 上寻找的 'bit extra' 是用于测试的 django 设置环境、数据库和固定装置。【参考方案6】:使用 Django 2.2 一个简单且相当好的解决方案可能是在应用程序中创建一个 test
文件夹,您可以将相关的 test_...py
文件放入,只需将 __init__.py
添加到 test
文件夹即可。
【讨论】:
【参考方案7】:无需在 init 中编写任何代码。 只需在您的应用程序中创建一个子目录。唯一的要求是不要称之为测试* 例如
app/
app/__init_.py
app/serializers.py
app/testing/
app/testing/__init__.py
app/testing/tests_serializers.py
【讨论】:
为什么不能称它为以“测试”开头的东西? 我在 Django 1.11.4 中使用这个答案。使用它的原因:(1)文件“app/testing/__init__.py”保持为空,(2)命令保持基本的“python manage.py test app”【参考方案8】:如果你有一个更复杂的设置,或者不想使用from ... import *
-type 语句,你可以在你的tests.py(或tests/__init__.py)中定义一个名为suite
的函数,它返回unittest.TestSuite
的一个实例。
【讨论】:
【参考方案9】:我有两个文件。一个是tests.py
,另一个是test_api.py
。我可以按如下方式单独运行这些。
manage.py test companies.tests
manage.py test companies.test_api
参考@osa 对文件命名约定的回复。
【讨论】:
【参考方案10】:我认为./manage.py test
只是运行所有测试技巧(在 django >= 1.7 中)。
如果您的组织测试是关于分组和樱桃采摘,并且你是nose
的粉丝,请使用django nose:
python manage.py test another.test:TestCase.test_method
如果您知道鼻子,那么您就知道如何更好地“通配符”您的所有文件。
PS
这只是一种更好的做法。希望有帮助。答案是从这里借来的:Running a specific test case in Django when your app has a tests directory
【讨论】:
【参考方案11】:在 django 中,您可以使用下面的命令或查看documentation。此外,使用此命令将获取具有您提供的模式的文件,而不仅仅是 test*.py
或 test_*
.py。
文档 如果您的测试文件的名称与 test*.py 模式不同,您可以使用 -p(或 --pattern)选项指定自定义文件名模式匹配:
$ ./manage.py test --pattern="tests_*.py"
【讨论】:
【参考方案12】:只需在您的应用中使用 tests_name 创建不同的测试文件
假设您有以下测试文件:
tests_admins.py
tests_staff.py
tests_others.py
# will run both test files
(venv)..yourapp$./manage.py test --keepdb -v 2 appname
【讨论】:
【参考方案13】:或者在 Windows 中,如果您不想创建一个包(即带有 __init__.py
的文件夹)并且只想创建一个名为“Tests”的文件夹并且该文件夹包含测试文件,那么在 cmd 中运行测试只需输入
python manage.py test your_app_name/Tests
因为需要路径
【讨论】:
以上是关于如何将 django 单元测试分布在多个文件上?的主要内容,如果未能解决你的问题,请参考以下文章