在我的Django项目中,有一些应用程序,所有这些都有单元测试。我现在正在工作的其中一个应该只包含在dev / stage环境中,所以我使用环境变量来启用它。
当这个变量出现时,它被添加到INSTALLED_APPS并且它正常工作,问题是Django正在为这个应用程序执行测试,即使它不在INSTALLED_APPS中,并且它失败并显示以下消息:
ImportError:无法导入测试模块:debug.tests.unit.test_services`
...(追溯信息)......
RuntimeError:模型类debug.models.Email没有声明显式的app_label,也不在INSTALLED_APPS的应用程序中。
当我在此应用中的app_label
模型中定义class Meta
时,错误是不同的,它表示无法找到表格,我认为这是因为该应用不在INSTALLED_APPS,因此不会执行迁移。
OperationalError:没有这样的表:debug_email
我不确定为什么Django会对所有应用程序执行测试,但不会进行迁移。
我是否遗漏了Django配置中的测试内容?
答案 0 :(得分:1)
当你跑步时:
python manage.py test
对于工作目录中具有模式test*.py
的所有文件,该命令将按默认递归查找。它不受INSTALLED_APPS
中settings.py
的影响。
您可以指定某个应用来测试它:
python manage.py test app_label
或指定路径:
python manage.py test myapp/tests
如果要排除某些测试,可以标记它们并使用选项--exclude-tag
。
运行python manage.py test --help
以获取有关所有选项的信息。
官方documentation提供了很多关于如何运行测试的不同可能性的信息。
编辑:
如果您的应用仅在开发环境中需要,但在制作中不需要,则可以拆分settings.py
。一种可能的解决方案是将所有开发设置外包到文件local_settings.py
中,并将其从版本控制或生产分支中排除,即不要在生产环境中将其推送。
<强> local_settings.py
强>
DEBUG = True
INSTALLED_APPS += (
# Django Debug Toolbar would be for example
# used only in development
'debug_toolbar',
'your dev app',
)
<强> settings.py
强>
try:
from .local_settings import *
except ImportError:
pass
答案 1 :(得分:1)
您需要在 load_tests
中返回发现的测试。
所以,加上@DaveLawrence's answer,完整的代码是:
# your_dev_app/__init__.py
from django.apps import apps
from os.path import dirname, abspath
def load_tests(loader, tests, pattern):
"""
loads tests for your_dev_app if it is installed.
"""
from django.conf import settings
if apps.is_installed("your_dev_app"):
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
答案 2 :(得分:0)
https://docs.python.org/3/library/unittest.html#unittest.TestLoader.discover说:
如果load_tests存在,则发现不会递归到软件包中,load_tests负责加载软件包中的所有测试。
因此,在您并不总是希望运行的应用中最低的__init__.py
中:
from django.apps import apps
def load_tests(loader, tests, pattern):
from django.conf import settings
if apps.is_installed("your_dev_app"):
pass # Actually load the tests