django-如何检测测试环境(检查/确定测试是否正在运行)
如何检测是否在测试环境中调用视图(例如,从django-如何检测测试环境(检查/确定测试是否正在运行),django,unit-testing,Django,Unit Testing,如何检测是否在测试环境中调用视图(例如,从manage.py test) 将其放入您的settings.py: import sys TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test' 这将测试第二个命令行参数(在/manage.py之后)是否为test。然后您可以从其他模块访问此变量,如下所示: from django.conf import settings if settings.TESTING: ... 这样做
manage.py test
)
将其放入您的settings.py:
import sys
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
这将测试第二个命令行参数(在/manage.py
之后)是否为test
。然后您可以从其他模块访问此变量,如下所示:
from django.conf import settings
if settings.TESTING:
...
这样做有很好的理由:假设您正在访问一些后端服务,而不是Django的模型和DB连接。然后您可能需要知道何时调用生产服务和测试服务。只需查看
request.META['SERVER\u NAME']
def my_view(request):
if request.META['SERVER_NAME'] == "testserver":
print "This is test environment!"
借助@Tobia的答案,我认为在settings.py中更好地实现它,如下所示:
import sys
try:
TESTING = 'test' == sys.argv[1]
except IndexError:
TESTING = False
这将阻止它捕获诸如
/manage.py loaddata test.json
或/manage.py i_\u未运行a_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)
我认为最好的方法是使用自己的设置文件(即settings/tests.py)运行测试。该文件可以如下所示(第一行从local.py设置文件导入设置): 然后输入检查您是否处于测试模式
try:
if settings.TEST_MODE:
print 'foo'
except AttributeError:
pass
还有一种方法可以临时覆盖Django中单元测试中的设置。对于某些情况,这可能是一个更容易/更干净的解决方案 您可以在测试中执行此操作:
with self.settings(MY_SETTING='my_value'):
# test code
或者将其添加为测试方法上的装饰器:
@override_settings(MY_SETTING='my_value')
def test_my_test(self):
# test code
您还可以为整个测试用例类设置装饰器:
@override_settings(MY_SETTING='my_value')
class MyTestCase(TestCase):
# test methods
要了解更多信息,请查看Django文档:虽然没有官方方法可以确定我们是否处于测试环境中,但Django实际上为我们留下了一些线索。 默认情况下,Django的测试运行程序。这是通过在名为的函数中替换来实现的,而该函数又由DiscoveryRunner的函数调用。因此,我们可以检查settings.EMAIL\u BACKEND是否设置为“django.core.mail.backends.locmem.EmailBackend”。这意味着我们在一个测试环境中
一个不太老套的解决方案是遵循开发人员的指导,通过子类化DisoverRunner添加我们自己的设置,然后覆盖setup\u test\u environment方法。如果您是不同环境的多个设置文件,则只需创建一个设置文件进行测试 例如,您的设置文件是:
your_project/
|_ settings/
|_ __init__.py
|_ base.py <-- your original settings
|_ testing.py <-- for testing only
在应用程序中,您可以访问设置。测试以检查您是否处于测试环境中
要运行测试,请使用:
python manage.py test --settings your_project.settings.testing
请求
有哪些属性?这里有什么指示吗?当你说“测试环境”时,你的意思是“运行测试时”?如果是这样,你到底为什么要这样做?只有在运行测试时才起作用的特殊大小写代码意味着您根本没有实际测试真正的代码,那么有什么意义呢?值得注意的是,您可以为安全视图创建一个@https\u only
包装器,而不是在视图中使用手动逻辑。在https\u only
中,您可以在需要时使用https
发送重定向,或者在那里引发异常。这不是很灵活,因为test
参数可以位于另一个索引上。例如,作为python manage.py test运行
它位于索引2。@gertvdijk然后将其更改为'test'==sys.argv[2]
:)@glarrain当然,但我的观点是,您事先并不知道它,因为它取决于用户如何调用测试运行程序。“这将阻止它捕获类似/manage.py loaddata test.json
”的内容。”. 该命令不会导致sys.argv中的'test
为真,因为[''./manage.py','loaddata','test.json']==False中的'test'。所有这些在Tobia的答案中都是False
。似乎是这里唯一不依赖于知道某个变量值的解决方案,就像sys.argv或测试服务器的名称一样……虽然有不同的问题解决方案很好,但在运行时更改django设置似乎不是明智的选择这是最稳定、通用和灵活的解决方案。但django.test.simple已被弃用。现在应该使用django.test.runner.DiscoverRunner作为测试运行的父类,因此最好更改设置\u测试\u环境
方法中的设置,而不是django 1.8+中的\u初始化
,使用django.test.runner中的将DiscoveryRunner导入为DjangoTestSuiteRunner
如果有一些管理命令要求将参数test
放入sys.argv?@EmanuelePaolini,那么您可以更具体地要求它作为第二个参数(在manage.py之后):TESTING=len(sys.argv)>1和sys.argv[1]=='test'
是的,这就是我正在做的,我建议一般都这样做。这是一个脆弱的黑客,有人用nose或py.test来运行测试呢?@Tobia他们是替代的测试运行者,被广泛使用,请参见,我不想修补,我认为查看argv的方法不够健壮和通用。其他解决方案最适合IMHO(如travis jensen rednaw或pymarco)。我不会依赖攻击者可以访问的东西,我假设这是通过标头进行配置的,并且可以被操纵以使其相信来源于测试套件,而实际上它是此解决方案之外的东西,在我看来,是最干净、最实用的解决方案。我在django 2.2上尝试了所有这三种方法,但都不起作用(编辑:直到我意识到我导入的是myapp.settings而不是django.conf.settings)。
your_project/
|_ settings/
|_ __init__.py
|_ base.py <-- your original settings
|_ testing.py <-- for testing only
from .base import *
TESTING = True
python manage.py test --settings your_project.settings.testing