django - 如何检测测试环境

tba*_*ack 47 django unit-testing

问题似乎很简单,但不幸的是谷歌有点难以实现.

我的问题是:如何在一个视图中检测到它是否在测试环境中被调用?

#pseudo_code
def my_view(request):
    if not request.is_secure() and not TEST_ENVIRONMENT:
        return HttpResponseForbidden()
Run Code Online (Sandbox Code Playgroud)

Tob*_*bia 111

把它放在您的settings.py中:

import sys

TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
Run Code Online (Sandbox Code Playgroud)

这将测试第二个命令行参数(后./manage.py)是否为test.然后你可以从其他模块访问这个变量,如下所示:

from django.conf import settings

if settings.TESTING:
    ...
Run Code Online (Sandbox Code Playgroud)

有充分的理由这样做:假设你正在访问一些后端服务,而不是Django的模型和数据库连接.然后,您可能需要知道何时调用生产服务与测试服务.

  • 这是一个脆弱的黑客,如果有人使用nose或py.test来运行测试呢? (5认同)
  • @Tobia他们是备用测试跑者,广泛使用请参阅https://nose.readthedocs.org/en/latest/和http://pytest.org/latest/我不想修补,我认为看的方法在argv不够强大和普遍.其他解决方案最适合恕我直言(如travis-jensen rednaw或pymarco). (3认同)

Tra*_*sen 16

创建自己的TestSuiteRunner子类并更改设置或为应用程序的其余部分执行任何其他操作.您在设置中指定了测试运行器:

TEST_RUNNER = 'your.project.MyTestSuiteRunner'
Run Code Online (Sandbox Code Playgroud)

一般情况下,您不希望这样做,但如果您绝对需要它,它会起作用.

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)
Run Code Online (Sandbox Code Playgroud)

  • 在 Django 1.8+ 中,使用 `from django.test.runner import DiscoverRunner as DjangoTestSuiteRunner` (3认同)
  • 虽然对问题有不同的解决方案是件好事,但在运行时更改 django 设置似乎并不是一个明智的选择 (2认同)

小智 14

看看吧 request.META['SERVER_NAME']

def my_view(request):
    if request.META['SERVER_NAME'] == "testserver":
        print "This is test environment!"
Run Code Online (Sandbox Code Playgroud)

  • 我不会依赖攻击者可以访问的东西,我认为这可以通过标头以某种方式进行配置,并且可以进行操作以让人相信来源来自测试套件,而实际上它是外部的东西 (2认同)

pym*_*rco 6

我认为最好的方法是使用自己的设置文件(即settings/tests.py)运行测试.该文件可能如下所示(第一行从local.py设置文件导入设置):

from local import *
TEST_MODE = True
Run Code Online (Sandbox Code Playgroud)

然后做鸭脸检查以确定您是否处于测试模式.

try:
    if settings.TEST_MODE:
        print 'foo'
except AttributeError:
    pass
Run Code Online (Sandbox Code Playgroud)


git*_*rik 5

还有一种方法可以暂时覆盖Django中单元测试中的设置.对于某些情况,这可能是更容易/更清洁的解决方案.

你可以在测试中做到这一点:

with self.settings(MY_SETTING='my_value'):
    # test code
Run Code Online (Sandbox Code Playgroud)

或者在测试方法中将其添加为装饰器:

@override_settings(MY_SETTING='my_value')
def test_my_test(self):
    # test code
Run Code Online (Sandbox Code Playgroud)

您还可以为整个测试用例类设置装饰器:

@override_settings(MY_SETTING='my_value')
class MyTestCase(TestCase):
    # test methods
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看Django文档:https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.override_settings