如何检测您是否处于测试环境中(检查/确定测试是否正在运行)

发布于 2024-09-30 14:43:45 字数 214 浏览 3 评论 0原文

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

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

How can I detect whether a view is being called in a test environment (e.g., from manage.py test)?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

蓝色星空 2024-10-07 14:43:45

将其放入 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 的模型和数据库连接。然后您可能需要知道何时调用生产服务与测试服务。

Put this in your settings.py:

import sys

TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'

This tests whether the second commandline argument (after ./manage.py) was test. Then you can access this variable from other modules, like so:

from django.conf import settings

if settings.TESTING:
    ...

There are good reasons to do this: suppose you're accessing some backend service, other than Django's models and DB connections. Then you might need to know when to call the production service vs. the test service.

戴着白色围巾的女孩 2024-10-07 14:43:45

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

Create your own TestSuiteRunner subclass and change a setting or do whatever else you need to for the rest of your application. You specify the test runner in your settings:

TEST_RUNNER = 'your.project.MyTestSuiteRunner'

In general, you don't want to do this, but it works if you absolutely need it.

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)
謌踐踏愛綪 2024-10-07 14:43:45

只需查看 request.META['SERVER_NAME']

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

Just look at request.META['SERVER_NAME']

def my_view(request):
    if request.META['SERVER_NAME'] == "testserver":
        print "This is test environment!"
绅士风度i 2024-10-07 14:43:45

还有一种方法可以临时覆盖 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

There's also a way to temporarily overwrite settings in a unit test in Django. This might be a easier/cleaner solution for certain cases.

You can do this inside a test:

with self.settings(MY_SETTING='my_value'):
    # test code

Or add it as a decorator on the test method:

@override_settings(MY_SETTING='my_value')
def test_my_test(self):
    # test code

You can also set the decorator for the whole test case class:

@override_settings(MY_SETTING='my_value')
class MyTestCase(TestCase):
    # test methods

For more info check the Django docs: https://docs.djangoproject.com/en/1.11/topics/testing/tools/#django.test.override_settings

尐籹人 2024-10-07 14:43:45

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

from local import *
TEST_MODE = True

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

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

I think the best approach is to run your tests using their own settings file (i.e. settings/tests.py). That file can look like this (the first line imports settings from a local.py settings file):

from local import *
TEST_MODE = True

Then do ducktyping to check if you are in test mode.

try:
    if settings.TEST_MODE:
        print 'foo'
except AttributeError:
    pass
相守太难 2024-10-07 14:43:45

如果您有多个设置文件用于不同的环境,您所需要做的就是创建一个设置文件用于测试。

例如,您的设置文件是:

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

If you are multiple settings file for different environment, all you need to do is to create one settings file for testing.

For instance, your setting files are:

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

In your testing.py, add a TESTING flag:

from .base import *

TESTING = True

In your application, you can access settings.TESTING to check if you're in testing environment.

To run tests, use:

python manage.py test --settings your_project.settings.testing
浪推晚风 2024-10-07 14:43:45

借鉴@Tobia的答案,我认为最好在settings.py中实现,如下所示:

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

这将防止它捕获诸如 ./manage.py loaddata test.json./管理.py i_am_not_running_a_test

Piggybacking off of @Tobia's answer, I think it is better implemented in settings.py like this:

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

This will prevent it from catching things like ./manage.py loaddata test.json or ./manage.py i_am_not_running_a_test

给妤﹃绝世温柔 2024-10-07 14:43:45

虽然没有官方的方法来查看我们是否处于测试环境中,但 django 实际上为我们留下了一些线索。
默认情况下,Django 的测试运行器 自动将所有 Django 发送的电子邮件重定向到一个虚拟发件箱。这是通过替换函数中的 EMAIL_BACKEND 来完成的称为 setup_test_environment,其中轮由 方法调用< DiscoverRunner 的 /a>。因此,我们可以检查 settings.EMAIL_BACKEND 是否设置为 'django.core.mail.backends.locmem.EmailBackend'。这意味着我们处于测试环境中。

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

While there's no official way to see whether we're in a test environment, django actually leaves some clues for us.
By default Django’s test runner automatically redirects all Django-sent email to a dummy outbox. This is accomplished by replacing EMAIL_BACKEND in a function called setup_test_environment, which in turn is called by a method of DiscoverRunner. So, we can check whether settings.EMAIL_BACKEND is set to 'django.core.mail.backends.locmem.EmailBackend'. That mean we're in a test environment.

A less hacky solution would be following the devs lead by adding our own setting by subclassing DisoverRunner and then overriding setup_test_environment method.

枕头说它不想醒 2024-10-07 14:43:45

我想排除一些数据迁移在测试中运行,并在 Django 3.2 项目上提出了这个解决方案:

class Migration(migrations.Migration):
    def apply(self, project_state, schema_editor, collect_sql=False):
        import inspect
        if 'create_test_db' in [i.function for i in inspect.stack()]:
            return project_state
        else:
            return super().apply(project_state, schema_editor, collect_sql=collect_sql)

我没有在其他地方看到过这个建议,就我的目的而言,它非常干净。当然,如果 Django 在某个时间点更改了 create_test_db 方法的名称(或 apply 方法的返回值),它可能会中断,但是修改它即可工作应该相当简单,因为堆栈中可能存在某些在非测试迁移运行期间不存在的方法。

I wanted to exclude some data migrations from being run in tests, and came up with this solution on a Django 3.2 project:

class Migration(migrations.Migration):
    def apply(self, project_state, schema_editor, collect_sql=False):
        import inspect
        if 'create_test_db' in [i.function for i in inspect.stack()]:
            return project_state
        else:
            return super().apply(project_state, schema_editor, collect_sql=collect_sql)

I haven't seen this suggested elsewhere, and for my purposes it's pretty clean. Of course, it might break if Django changes the name of the create_test_db method (or the return value of the apply method) at some point in time, but modifying this to work should be reasonably simple, since it's likely that some method exists in the stack that doesn't exist during non-test migration runs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文