检测姜戈测试模式

我正在编写一个可重用的 django 应用程序,我需要确保它的模型仅在应用程序处于测试模式时同步。我尝试过使用自定义 DjangoTestRunner,但是没有找到这样做的示例(文档只显示了如何定义自定义测试运行程序)。

So, does anybody have an idea of how to do it?

剪辑

我是这么做的:

#in settings.py
import sys
TEST = 'test' in sys.argv

希望能有帮助。

21496 次浏览

不太确定您的用例,但是我发现检测测试套件何时运行的一种方法是检查 django.core.mail是否具有 outbox属性,例如:

from django.core import mail


if hasattr(mail, 'outbox'):
# We are in test mode!
pass
else:
# Not in test mode...
pass

这个属性由 setup_test_environment中的 Django 测试运行程序添加,并在 teardown_test_environment中删除。你可以在这里检查源: https://code.djangoproject.com/browser/django/trunk/django/test/utils.py

编辑: 如果你只想测试定义的模型,那么你应该检查 姜戈票 # 7835,特别是 评论 # 24部分给出如下:

显然,您可以直接在 tests.py 中定义模型。 Syncdb 从不导入 tests.py,因此这些模型不会同步到 但是它们将被同步到测试数据库,并且可以 用于测试。

我认为这里提供的答案 https://stackoverflow.com/a/7651002/465673是一种干净得多的方式:

把这个放进你的设置里:

import sys


TESTING = sys.argv[1:2] == ['test']

选择的答案是大规模黑客攻击。 :)

一个简单的方法是创建您自己的 TestSuiteRunner 子类并更改设置,或者为应用程序的其余部分执行所需的任何其他操作。在设置中指定测试运行程序:

TEST_RUNNER = 'your.project.MyTestSuiteRunner'

一般情况下,你不想这么做,但是如果你绝对需要它,它会起作用。

from django.conf import settings
from django.test.simple import DjangoTestSuiteRunner


class MyTestSuiteRunner(DjangoTestSuiteRunner):
def __init__(self, *args, **kwargs):
settings.IM_IN_TEST_MODE = True
super(MyTestSuiteRunner, self).__init__(*args, **kwargs)

注意: 从 Django 1.8开始,DjangoTestSuiteRunner已被弃用。 你应该改用 DiscoverRunner:

from django.conf import settings
from django.test.runner import DiscoverRunner




class MyTestSuiteRunner(DiscoverRunner):
def __init__(self, *args, **kwargs):
settings.IM_IN_TEST_MODE = True
super(MyTestSuiteRunner, self).__init__(*args, **kwargs)

我正在使用设置 py 重写。我有一个全局设置.py,它包含了大部分内容,然后我重写了它。每个设置文件的开头是:

from myproject.settings import settings

然后覆盖一些设置。

  • Py-生产设置(例如,覆盖 DEBUG = False)
  • Py-开发设置(例如,更多日志记录)
  • Test _ sets. py

然后我可以在基础 setings.py 中定义 UNIT _ TESTS = False,并在 test _ setings.py 中将其覆盖为 UNIT _ TESTS = True。

然后,每当我运行一个命令时,我需要决定运行哪些设置(例如 DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test)。我喜欢这种清晰感。

可以这样简单地使用环境变量:

export MYAPP_TEST=1 && python manage.py test

然后在你的 settings.py文件:

import os


TEST = os.environ.get('MYAPP_TEST')


if TEST:
# Do something

我一直在使用 Django 基于类的设置。我使用包中的“切换器”并为 testing=True加载一个不同的配置/类:

switcher.register(TestingSettings, testing=True)

在我的配置中,我有一个 BaseSettingsProductionSettingsDevelopmentSettingsTestingSettings等。它们根据需要相互分类。在 BaseSettings中我有 IS_TESTING=False,然后在 TestingSettings中我把它设置为 True

如果您保持类继承的清洁,那么它会工作得很好。但是我发现它比 Django 开发人员通常使用的 import *方法工作得更好。

虽然这个页面上有很多好的答案,但我认为还有另一种方法来检查您的项目是否处于测试模式(如果在某些情况下您不能使用 sys.argv[1:2] == ["test"])。

你们可能都知道,当你处于测试模式时,DATABASE名称会变成类似于“ 测试 _ *”(DATABASE 默认名称将以 test 作为前缀)的东西(或者你可以简单地打印出来,在运行测试时找到你的数据库名称)。因为我在一个项目中使用了 pytest,所以不能使用

sys.argv[1:2] == ["test"]

因为这个争论不存在。所以我只是用这个作为我的快捷方式来检查我是否在测试环境中(你知道你的 DATABASE名字前缀是 测试,如果不仅仅是改变 测试到你的 DATABASE名字前缀部分) :

1)设定模组以外的任何地方

from django.conf import settings


TESTING_MODE = "test" in settings.DATABASES["default"]["NAME"]

2)在设置模块内

TESTING_MODE = "test" in DATABASES["default"]["NAME"]

或者

TESTING_MODE = DATABASES["default"]["NAME"].startswith("test")  # for more strict checks

如果这个解决方案是可行的,那么您甚至不需要 import sys来检查 settings.py模块中的这种模式。