我正在编写一个可重用的Django应用,我需要确保它的模型只在应用处于测试模式时才同步。我尝试过使用自定义DjangoTestRunner,但我没有找到如何做到这一点的示例(文档只显示了如何定义自定义测试运行程序)。有人知道怎么做吗?
我是这么做的:
#in settings.py import sys TEST = 'test' in sys.argv
希望有帮助。
anauzrmj1#
我认为这里提供的答案https://stackoverflow.com/a/7651002/465673是一种更简洁的方法:把这个放到你的网站上settings.py:
import sys TESTING = sys.argv[1:2] == ['test']
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:
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)
5f0d552i3#
我不太确定您的用例,但我看到的一种检测测试套件何时运行的方法是检查django.core.mail是否具有outbox属性,例如:
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,因此这些模型不会同步到普通数据库,但它们会同步到测试数据库,并可在测试中使用。
setup_test_environment
teardown_test_environment
bkkx9g8r4#
我使用的是settings.py覆盖,我有一个全局settings.py,它包含了大部分内容,然后我有覆盖它的设置文件,每个设置文件都以下列内容开头:
from myproject.settings import settings
然后继续覆盖某些设置。
然后我可以在基础www.example.com中定义UNIT_TESTS=Falsesettings.py,并在test_settings. py中将其覆盖为UNIT_TESTS=True。然后每当我运行一个命令时,我需要决定运行哪些设置(eidogg. DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test)。我喜欢这种清晰度。
DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test
zwghvu4y5#
那么,您可以简单地以这种方式使用环境变量:
export MYAPP_TEST=1 && python manage.py test
然后在settings.py文件中:
settings.py
import os TEST = os.environ.get('MYAPP_TEST') if TEST: # Do something
3xiyfsfu6#
尽管本页上有很多很好的答案,但我认为还有另一种方法可以检查您的项目是否处于测试模式(如果在某些情况下您不能使用sys.argv[1:2] == ["test"])。正如您所知道的,当您处于测试模式时,DATABASE名称将更改为类似于“test_*”(DATABASE默认名称将以test为前缀)(或者您可以在运行测试时简单地将其打印出来以查找数据库名称)。
sys.argv[1:2] == ["test"]
DATABASE
因为这个参数不存在,所以我只是使用这个参数作为检查是否在测试环境中的快捷方式(您知道您的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模块中的这个模式。
import sys
vlju58qv7#
我一直在使用Django class based settings,我使用了包中的'switcher'并为testing=True加载了一个不同的config/class:
testing=True
switcher.register(TestingSettings, testing=True)
在我的配置中,我有BaseSettings、ProductionSettings、DevelopmentSettings、TestingSettings等,它们根据需要相互子类化。在BaseSettings中,我有IS_TESTING=False,然后在TestingSettings中,我将其设置为True。如果你保持类继承的干净,它可以很好地工作。但是我发现它比Django开发人员通常使用的import *方法工作得更好。
BaseSettings
ProductionSettings
DevelopmentSettings
TestingSettings
IS_TESTING=False
True
import *
7条答案
按热度按时间anauzrmj1#
我认为这里提供的答案https://stackoverflow.com/a/7651002/465673是一种更简洁的方法:
把这个放到你的网站上settings.py:
iecba09b2#
选择的答案是大规模的黑客攻击。:)
一个规模较小的方法是创建自己的TestSuiteRunner子类,然后更改设置,或者对应用程序的其余部分做任何需要做的事情,在设置中指定测试运行程序:
一般来说,您并不想这样做,但如果您确实需要它,它会起作用。
注意:从Django 1.8开始,
DjangoTestSuiteRunner
已经被弃用,你应该使用DiscoverRunner
:5f0d552i3#
我不太确定您的用例,但我看到的一种检测测试套件何时运行的方法是检查
django.core.mail
是否具有outbox
属性,例如:这个属性由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,因此这些模型不会同步到普通数据库,但它们会同步到测试数据库,并可在测试中使用。
bkkx9g8r4#
我使用的是settings.py覆盖,我有一个全局settings.py,它包含了大部分内容,然后我有覆盖它的设置文件,每个设置文件都以下列内容开头:
然后继续覆盖某些设置。
然后我可以在基础www.example.com中定义UNIT_TESTS=Falsesettings.py,并在test_settings. py中将其覆盖为UNIT_TESTS=True。
然后每当我运行一个命令时,我需要决定运行哪些设置(eidogg.
DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test
)。我喜欢这种清晰度。zwghvu4y5#
那么,您可以简单地以这种方式使用环境变量:
然后在
settings.py
文件中:3xiyfsfu6#
尽管本页上有很多很好的答案,但我认为还有另一种方法可以检查您的项目是否处于测试模式(如果在某些情况下您不能使用
sys.argv[1:2] == ["test"]
)。正如您所知道的,当您处于测试模式时,
DATABASE
名称将更改为类似于“test_*”(DATABASE默认名称将以test为前缀)(或者您可以在运行测试时简单地将其打印出来以查找数据库名称)。因为这个参数不存在,所以我只是使用这个参数作为检查是否在测试环境中的快捷方式(您知道您的
DATABASE
名称带有前缀test,如果没有,只需将test更改为DATABASE
名称的前缀部分):1)设置模块以外的任何地方
2)设置模块内部
或
如果这个解决方案是可行的,你甚至不需要
import sys
来检查你的settings.py
模块中的这个模式。vlju58qv7#
我一直在使用Django class based settings,我使用了包中的'switcher'并为
testing=True
加载了一个不同的config/class:在我的配置中,我有
BaseSettings
、ProductionSettings
、DevelopmentSettings
、TestingSettings
等,它们根据需要相互子类化。在BaseSettings
中,我有IS_TESTING=False
,然后在TestingSettings
中,我将其设置为True
。如果你保持类继承的干净,它可以很好地工作。但是我发现它比Django开发人员通常使用的
import *
方法工作得更好。