Django不在INSTALLED_APPS中执行app的测试

时间:2018-03-05 18:50:09

标签: django django-apps django-unittest

在我的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配置中的测试内容?

3 个答案:

答案 0 :(得分:1)

当你跑步时:

python manage.py test

对于工作目录中具有模式test*.py的所有文件,该命令将按默认递归查找。它不受INSTALLED_APPSsettings.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