django - 如何检测测试环境(检查/确定是不是正在运行测试)

     2023-02-24     164

关键词:

【中文标题】django - 如何检测测试环境(检查/确定是不是正在运行测试)【英文标题】:django - how to detect test environment (check / determine if tests are being run)django - 如何检测测试环境(检查/确定是否正在运行测试) 【发布时间】:2011-05-04 13:08:18 【问题描述】:

如何检测是否正在测试环境中调用视图(例如,来自manage.py test)?

#pseudo_code
def my_view(request):
    if not request.is_secure() and not TEST_ENVIRONMENT:
        return HttpResponseForbidden()

【问题讨论】:

request 有什么属性?里面有提示吗? 当您说“测试环境”时,您的意思是“运行测试时”吗?如果是这样,你到底为什么要这样做?仅在您运行测试时才有效的特殊情况代码意味着您实际上根本没有测试您的真实代码,那么有什么意义呢? 值得注意的是,您可以为安全视图创建@https_only 包装器,而不是在视图中使用手动逻辑。在https_only 中,您可以在需要时使用https 发送重定向,或者在那里提出您的异常。 【参考方案1】:

如果您是针对不同环境的多个设置文件,您只需创建一个设置文件进行测试。

例如,您的设置文件是:

your_project/
      |_ settings/
           |_ __init__.py
           |_ base.py  <-- your original settings
           |_ testing.py  <-- for testing only

在您的 testing.py 中,添加 TESTING 标志:

from .base import *

TESTING = True

在您的应用程序中,您可以访问settings.TESTING 以检查您是否处于测试环境中。

要运行测试,请使用:

python manage.py test --settings your_project.settings.testing

【讨论】:

【参考方案2】:

虽然没有官方方法可以查看我们是否处于测试环境中,但 django 实际上为我们留下了一些线索。 默认情况下 Django 的测试运行器automatically redirects all Django-sent email to a dummy outbox。这是通过在名为setup_test_environment 的函数中替换EMAIL_BACKEND 来实现的,该函数又由DiscoverRunner 的method 调用。因此,我们可以检查 settings.EMAIL_BACKEND 是否设置为 'django.core.mail.backends.locmem.EmailBackend'。这意味着我们处于测试环境中。

一个不那么老套的解决方案是跟随开发人员的领导,通过子类化 DisoverRunner 添加我们自己的设置,然后覆盖 setup_test_environment 方法。

【讨论】:

【参考方案3】:

还有一种方法可以在 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 文档:https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.override_settings

【讨论】:

我在 django 2.2 上尝试了所有这 3 种方法,但似乎都没有工作(编辑:直到我意识到我正在导入 myapp.settings 而不是 django.conf.settings)。【参考方案4】:

把它放在你的 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 的模型和数据库连接。那么您可能需要知道何时调用生产服务和测试服务。

【讨论】:

如果有一些管理命令需要在sys.argv中放入参数test怎么办? @EmanuelePaolini 在这种情况下,您可以更具体并要求它是第二个参数(在 manage.py 之后):TESTING = len(sys.argv) &gt; 1 and sys.argv[1] == 'test' 是的,这就是我正在做的事情,我建议一般这样做。 这是一个脆弱的hack,如果有人使用nose 或py.test 来运行测试呢? @Tobia 他们是备用测试运行程序,广泛使用参见nose.readthedocs.org/en/latest 和pytest.org/latest 我不想修补,我认为查看 argv 的方法不够健壮和通用。其他解决方案最适合恕我直言(如 travis-jensen rednaw 或 pymarco)。【参考方案5】:

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

from local import *
TEST_MODE = True

然后进行ducktyping检查您是否处于测试模式。

try:
    if settings.TEST_MODE:
        print 'foo'
except AttributeError:
    pass

【讨论】:

【参考方案6】:

创建您自己的 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)

【讨论】:

似乎是这里唯一不依赖于知道一些变量值的解决方案,比如 sys.argv 或测试服务器的名称...... 虽然对问题有不同的解决方案很好,但在运行时更改 django 设置似乎不是一个明智的选择 这是最稳定、最通用、最灵活的解决方案。但是 django.test.simple 已被弃用。现在应该使用 django.test.runner.DiscoverRunner 作为测试运行器的父类 另外,最好在setup_test_environment 方法中更改设置而不是__init__ 在 Django 1.8+ 中,使用from django.test.runner import DiscoverRunner as DjangoTestSuiteRunner【参考方案7】:

借鉴@Tobia 的回答,我认为最好在 settings.py 中像这样实现:

import sys
try:
    TESTING = 'test' == sys.argv[1]
except IndexError:
    TESTING = False

这将防止它捕获诸如./manage.py loaddata test.json./manage.py i_am_not_running_a_test 之类的东西

【讨论】:

这不是很灵活,因为test 参数可以在另一个索引上。例如。以python manage.py test 运行,它位于索引 2 处。 @gertvdijk 然后将其更改为 'test' == sys.argv[2] :) @glarrain 当然,但我的意思是,您事先并不知道它,因为这取决于用户如何调用测试运行器。 “这将阻止它捕获像./manage.py loaddata test.json这样的东西”。自从'test' in ['./manage.py', 'loaddata', 'test.json'] == False 以来,该命令无论如何都不会导致'test' in sys.argv 为真。 托比亚的回答中的所有这些都是False【参考方案8】:

看看request.META['SERVER_NAME']

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

【讨论】:

我不会依赖攻击者可以访问的东西,我认为这可以通过标题以某种方式进行配置,并且可以被操纵以使人们相信它实际上来自测试套件外部的东西

如何检测是不是启用了屏幕自动锁定

】如何检测是不是启用了屏幕自动锁定【英文标题】:Howtodetectifscreenautolockisenabled如何检测是否启用了屏幕自动锁定【发布时间】:2017-01-0507:18:14【问题描述】:我想知道用户是否将自动锁定时间设置为与从未设置不同的时间。... 查看详情

如何检查当前语言环境是不是等于字符串

】如何检查当前语言环境是不是等于字符串【英文标题】:Howtocheckifcurrentlocaleisequaltoastring如何检查当前语言环境是否等于字符串【发布时间】:2013-06-1016:57:30【问题描述】:我正在尝试确定是在我的Web应用程序上显示Spanish还是... 查看详情

如何检查 Django 版本

】如何检查Django版本【英文标题】:HowtocheckDjangoversion【发布时间】:2011-09-2201:00:33【问题描述】:我必须为我们的应用程序使用Python和Django。所以我有两个版本的Python,2.6和2.7。现在我已经安装了Django。我可以运行示例应用程... 查看详情

django表如何检测表是不是为空

】django表如何检测表是不是为空【英文标题】:djangotableshowtodetectiftableisemptydjango表如何检测表是否为空【发布时间】:2017-08-0310:00:53【问题描述】:我是django和Web开发的新手,基于SO上的示例和帮助,我拼凑了一些东西,它采用... 查看详情

如何检测测试是不是在 GitLab CI 服务器上运行

】如何检测测试是不是在GitLabCI服务器上运行【英文标题】:HowtodetectiftestisrunningonGitLabCIserver如何检测测试是否在GitLabCI服务器上运行【发布时间】:2019-05-1411:14:02【问题描述】:我有一个测试,它使用在gitlabCI服务器(gitlab-ci.yml)... 查看详情

Django ClearableFileInput - 如何检测是不是删除文件

】DjangoClearableFileInput-如何检测是不是删除文件【英文标题】:DjangoClearableFileInput-howtodetectwhethertodeletethefileDjangoClearableFileInput-如何检测是否删除文件【发布时间】:2015-08-3022:04:31【问题描述】:我正在为我的表单使用DjangoCrispyFor... 查看详情

如何检查Django中是不是存在模板?

】如何检查Django中是不是存在模板?【英文标题】:HowtocheckifatemplateexistsinDjango?如何检查Django中是否存在模板?【发布时间】:2011-04-1622:58:55【问题描述】:检查Django中是否存在模板最有效的方法是什么?我正在考虑捕捉TemplateD... 查看详情

检查 Django CMS 中是不是存在页面

】检查DjangoCMS中是不是存在页面【英文标题】:CheckwhetherapageexistsinDjangoCMS检查DjangoCMS中是否存在页面【发布时间】:2013-11-2016:23:06【问题描述】:我正在DjangoCMS的管理区域中创建一个页面,并且我在高级设置下有redirect字段。如... 查看详情

Django:如何检查用户是不是已经在 ManyToManyField 上投票?

】Django:如何检查用户是不是已经在ManyToManyField上投票?【英文标题】:Django:HowtocheckifuserhasalreadyvotedonManyToManyField?Django:如何检查用户是否已经在ManyToManyField上投票?【发布时间】:2013-03-1314:13:46【问题描述】:classPunch(models.M... 查看详情

如何检查一个元素是不是存在于 Django 查询集中?

】如何检查一个元素是不是存在于Django查询集中?【英文标题】:HowtocheckifanelementispresentinaDjangoqueryset?如何检查一个元素是否存在于Django查询集中?【发布时间】:2015-11-0705:54:24【问题描述】:它像普通的python集吗?假设我有以... 查看详情

如何测试 Django QuerySets 是不是相等?

】如何测试DjangoQuerySets是不是相等?【英文标题】:HowdoItestDjangoQuerySetsareequal?如何测试DjangoQuerySets是否相等?【发布时间】:2013-07-1503:13:45【问题描述】:我正在尝试测试我的Django视图。此视图将QuerySet传递给模板:defmerchant_hom... 查看详情

如何在javascript中检查Django对象是不是为None?

】如何在javascript中检查Django对象是不是为None?【英文标题】:HowtocheckifDjangoobjectisNoneinjavascript?如何在javascript中检查Django对象是否为None?【发布时间】:2016-12-2916:36:00【问题描述】:js中如何判断一个Django对象是否为None?我目... 查看详情

在 Django 中,如何检查用户是不是在某个组中?

】在Django中,如何检查用户是不是在某个组中?【英文标题】:InDjango,howdoIcheckifauserisinacertaingroup?在Django中,如何检查用户是否在某个组中?【发布时间】:2011-06-1421:53:35【问题描述】:我在Django的管理站点中创建了一个自定义... 查看详情

使用赛普拉斯,我将如何编写一个简单的测试来检查页面上是不是存在徽标图像

】使用赛普拉斯,我将如何编写一个简单的测试来检查页面上是不是存在徽标图像【英文标题】:UsingCypress,howwouldIwriteasimpletesttocheckthatalogoimageexistsonapage使用赛普拉斯,我将如何编写一个简单的测试来检查页面上是否存在徽标图... 查看详情

Django:如何检查自定义小部件定义中是不是存在字段错误?

】Django:如何检查自定义小部件定义中是不是存在字段错误?【英文标题】:Django:Howtocheckiftherearefielderrorsfromwithincustomwidgetdefinition?Django:如何检查自定义小部件定义中是否存在字段错误?【发布时间】:2011-03-1322:07:13【问题描... 查看详情

它可能检测用户是不是在 django 后端使用 pwa

】它可能检测用户是不是在django后端使用pwa【英文标题】:Itspossibledetectiftheuserusepwaindjangobackend它可能检测用户是否在django后端使用pwa【发布时间】:2022-01-0809:55:23【问题描述】:在javascript中可以检查类似:(window.matchMedia(\'(displ... 查看详情

检测django测试模式

】检测django测试模式【英文标题】:Detectdjangotestingmode【发布时间】:2011-10-2021:13:09【问题描述】:我正在编写一个可重用的django应用程序,我需要确保它的模型仅在应用程序处于测试模式时同步。我尝试使用自定义的DjangoTestRun... 查看详情

如何使用 django 检查 postgresql 数据库中是不是存在某些内容?

】如何使用django检查postgresql数据库中是不是存在某些内容?【英文标题】:Howtocheckifsomethingexistsinapostgresqldatabaseusingdjango?如何使用django检查postgresql数据库中是否存在某些内容?【发布时间】:2012-03-2214:32:27【问题描述】:我想... 查看详情