如何在单元测试中覆盖django app设置?

时间:2015-04-12 16:09:49

标签: python django django-unittest

当通过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 个答案:

答案 0 :(得分:0)

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

settings.py:

TEST_ENVIRONMENT_SETTING = True  # Test setting for my app

apps.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)

答案 1 :(得分:0)

理想情况下,您应该使用Django中集成的unittest库模拟设置。或者,您可以执行此操作,但是最好对它们进行修补:

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

答案 2 :(得分:0)

我正在同一个问题上挣扎,我认为唯一的解决方案是更改方法并直接仅使用django.conf.settings。

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

答案 3 :(得分: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}
...

为测试运行者创建一个单独的文件也是很常见的,因为它为您提供了更多power来控制您的测试环境,等等:

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
        ...