检测django测试模式

aoyhnmkz  于 2023-02-05  发布在  Go
关注(0)|答案(7)|浏览(152)

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

    • 编辑**

我是这么做的:

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

希望有帮助。

anauzrmj

anauzrmj1#

我认为这里提供的答案https://stackoverflow.com/a/7651002/465673是一种更简洁的方法:
把这个放到你的网站上settings.py:

import sys

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

iecba09b2#

选择的答案是大规模的黑客攻击。:)
一个规模较小的方法是创建自己的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)
5f0d552i

5f0d552i3#

我不太确定您的用例,但我看到的一种检测测试套件何时运行的方法是检查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

这个属性由Django测试运行器在setup_test_environment中添加,在teardown_test_environment中删除。https://code.djangoproject.com/browser/django/trunk/django/test/utils.py
编辑:如果你只想为测试定义模型,那么你应该查看Django ticket #7835,特别是注解#24,其部分如下所示:
显然,您可以直接在www.example.com中定义模型tests.py。Syncdb从不导入tests.py,因此这些模型不会同步到普通数据库,但它们会同步到测试数据库,并可在测试中使用。

bkkx9g8r

bkkx9g8r4#

我使用的是settings.py覆盖,我有一个全局settings.py,它包含了大部分内容,然后我有覆盖它的设置文件,每个设置文件都以下列内容开头:

from myproject.settings import settings

然后继续覆盖某些设置。

  • prod_settings.py -生产设置(例如覆盖DEBUG=False)
  • dev_settings.py -开发设置(例如更多日志记录)
  • 测试设置.py

然后我可以在基础www.example.com中定义UNIT_TESTS=Falsesettings.py,并在test_settings. py中将其覆盖为UNIT_TESTS=True。
然后每当我运行一个命令时,我需要决定运行哪些设置(eidogg. DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test)。我喜欢这种清晰度。

zwghvu4y

zwghvu4y5#

那么,您可以简单地以这种方式使用环境变量:

export MYAPP_TEST=1 && python manage.py test

然后在settings.py文件中:

import os

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

if TEST:
    # Do something
3xiyfsfu

3xiyfsfu6#

尽管本页上有很多很好的答案,但我认为还有另一种方法可以检查您的项目是否处于测试模式(如果在某些情况下您不能使用sys.argv[1:2] == ["test"])。
正如您所知道的,当您处于测试模式时,DATABASE名称将更改为类似于“test_*”(DATABASE默认名称将以test为前缀)(或者您可以在运行测试时简单地将其打印出来以查找数据库名称)。

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

因为这个参数不存在,所以我只是使用这个参数作为检查是否在测试环境中的快捷方式(您知道您的DATABASE名称带有前缀test,如果没有,只需将test更改为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模块中的这个模式。

vlju58qv

vlju58qv7#

我一直在使用Django class based settings,我使用了包中的'switcher'并为testing=True加载了一个不同的config/class:

switcher.register(TestingSettings, testing=True)

在我的配置中,我有BaseSettingsProductionSettingsDevelopmentSettingsTestingSettings等,它们根据需要相互子类化。在BaseSettings中,我有IS_TESTING=False,然后在TestingSettings中,我将其设置为True
如果你保持类继承的干净,它可以很好地工作。但是我发现它比Django开发人员通常使用的import *方法工作得更好。

相关问题