2

SimpleTestCase.settings()当通过(https://docs.djangoproject.com/en/1.8/topics/testing/tools/#django.test.SimpleTestCase.settings)运行测试时,Django 允许覆盖设置。当我尝试覆盖 Django 的一项设置时,它工作得很好。

settings.py我要为其运行测试的应用程序在具有以下结构的应用程序特定中携带自己的设置,以允许覆盖项目范围内的特定于应用程序的设置settings.py

from django.conf import settings
APP_SETTING1 = getattr(settings, 'APP_SETTING1', 'foo')

测试中的以下虚拟代码显示了该问题:

from django.test import TestCase
from django.conf import settings as django_settings
from my_app import settings

class MyTestCase(TestCase):
    def test_something(self):
        with self.settings(APP_SETTING1='bar'):
            print(django_settings.APP_SETTING1)    # bar
            print(settings.APP_SETTING1)           # foo

为什么这不起作用,我怎样才能使它起作用?

4

5 回答 5

1

您可以使用django-zero-settings,它可以让您定义默认设置,并使用提供的用户设置更新它们,它在测试设置覆盖中也可以正常工作,此外它还可以自动导入字符串,让您定义已删除的设置并预先也检查用户设置。

与您的情况一样,您可以像这样定义应用程序设置:

from zero_settings import ZeroSettings

app_settings = ZeroSettings(
    key="APP",
    defaults={
        "SETTING1": "foo"
    },
)

然后在您的测试中,您可以像这样使用它:

from django.test import TestCase
from django.conf import settings as django_settings
from my_app import app_settings

class MyTestCase(TestCase):
    def test_something(self):
        with self.settings(APP={"SETTING1": "bar"}):
            print(django_settings.APP["SETTING1"])    # bar
            print(app_settings.SETTING1)              # bar
            self.assertEqual(django_settings.APP["SETTING1"], app_settings.SETTING1)

因为它ZeroSettings使用缓存并且会在第一次尝试获取密钥时缓存用户设置,所以您可能需要在获取密钥之前将其设置为关闭,以确保您获得最新更新:

app_settings = ZeroSettings(
    key="APP",
    defaults={
        "SETTING1": "foo"
    },
    use_cache=False,
)

或手动清除缓存:

class MyTestCase(TestCase):
    def test_something(self):
        print(app_settings.SETTING1)                  # foo
        with self.settings(APP={"SETTING1": "bar"}):
            app_settings._clear_cache()
            print(django_settings.APP["SETTING1"])    # bar
            print(app_settings.SETTING1)              # bar
            self.assertEqual(django_settings.APP["SETTING1"], app_settings.SETTING1)
于 2021-08-25T05:43:40.023 回答
0

实际上,处理多个设置文件有很好的做法。基本规则是:

1)不要settings.py直接从文件导入:

# BAD - avoid this
from app.settings import SOME_ENV

因为如果最终,有人会尝试使用自定义设置,旧设置的某些部分将在某处应用。

# GOOD
from django.conf import settings
print(settings.SOME_ENV)

在这种情况下,您可以确定使用了实际设置。

2)针对不同环境拆分设置文件,通常通过创建几个文件来完成:

settings/base.py

DEBUG = False
AWS_STORAGE_PREFIX = 'local'
...

settings/dev.py

from settings.base import *

DEBUG = True
AWS_STORAGE_PREFIX = 'dev'
DATABASE = {# your settings for dev env}
...

为测试运行程序创建一个单独的文件也很常见,因为它使您可以更强大地控制测试环境等等:

python manage.py test --settings=app.settings.testrunner

测试实例具有绑定设置的上下文管理器,因此您可以覆盖测试所需的任何变量:

class MyTestCase(TestCase):
    def test_something(self):
        # Old settings
        with self.settings(SOME_ENV_VAR='overridden'):
            # Overridden settings
            pass
        ... 
于 2019-11-27T13:23:50.000 回答
0

理想情况下,您应该使用 Django 中的 unittest 库来模拟设置。或者,您可以这样做,但最好修补这些:

https://docs.djangoproject.com/en/2.1/topics/settings/#custom-default-settings

于 2018-11-02T10:28:45.693 回答
-1

您可以使用特定设置直接在应用程序中执行此操作

设置.py:

TEST_ENVIRONMENT_SETTING = True  # Test setting for my app

应用程序.py:

from django.conf import settings

class MyAppConfig(AppConfig):
    def ready(self):
        if getattr(settings, 'TEST_ENVIRONMENT_SETTING', False):
            # Do stuff or not do stuff

或者您可以使用直接在您的 TestCase 中设置此设置

setattr(settings, 'TEST_ENVIRONMENT_SETTING', True)
于 2015-04-13T01:42:07.557 回答
-2

我正在努力解决同样的问题,我认为唯一的解决方案是改变方法并直接使用 django.conf.settings 。

原因是如果您使用自定义设置,您的自定义设置会在调用 override_settings 或 TestCase.settings 之前过早地从设置中获取。

于 2019-04-15T01:03:20.160 回答