覆盖Django中单元测试的设置无法正常工作

per*_*ror 5 python django unit-testing django-settings

我试图对我的Django程序进行单元测试,我想在我的settings.py文件中检查一些变量的几个值.

在文档中," 覆盖设置 "部分描述了一种方法.但是,尽管我尝试了所有的尝试,但在测试运行时,我很难在程序中进行更改.以下是我在最小示例上所做的总结:

首先,创建一个新项目:

$ pyvenv virtualenv
$ cd virtualenv/
$ . bin/activate
(virtualenv) $ pip install django
(virtualenv) $ django-admin startproject myapp
(virtualenv) $ cd myapp/
Run Code Online (Sandbox Code Playgroud)

然后,添加以下文件.

文件 settings.py

...

TEST_VALUE = 'a'
Run Code Online (Sandbox Code Playgroud)

文件 tests.py

from django.test import TestCase
from myapp.settings import TEST_VALUE

class CheckSettings(TestCase):

  def test_settings(self):
    self.assertEqual(TEST_VALUE, 'a')

  def test_modified_settings(self):
    with self.settings(TEST_VALUE='b'):
      self.assertEqual(TEST_VALUE, 'b')
Run Code Online (Sandbox Code Playgroud)

当我运行测试时,我得到以下内容:

$ ./manage.py test
Creating test database for alias 'default'...
F.
======================================================================
FAIL: test_modified_settings (myapp.tests.CheckSettings)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/virtualenv/myapp/tests.py", line 12, in test_modified_settings
    self.assertEqual(TEST_VALUE, 'b')
AssertionError: 'a' != 'b'
----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)

正如您可能已经注意到的那样,原始值TEST_VALUE'a',并且我尝试通过self.settings(TEST_VALUE='b')... 修改它,但是没有成功.

您可以尝试通过一个空项目(Django是1.6.5).

那么,我错过了什么让它正常工作?

per*_*ror 9

只是为了总结一下我从伊斯梅尔巴达维注释理解,其实,我是不是要求正确地从该变量settings.py,因为我用from myapp.settings import TEST_VALUE,我应该有把它用from django.conf import settings,然后settings.TEST_VALUE.

所以,这是一个适当的tests.py文件:

from django.test import TestCase
from django.conf import settings

class CheckSettings(TestCase):

  def test_settings(self):
    self.assertEqual(settings.TEST_VALUE, 'a')

  def test_modified_settings(self):
    with self.settings(TEST_VALUE='b'):
      self.assertEqual(settings.TEST_VALUE, 'b')
Run Code Online (Sandbox Code Playgroud)

而且,这是结果./manage.py test:

$ ./manage.py test
Creating test database for alias 'default'...
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)

因此,这个小故事的教训是始终django.confmyapp.settings您使用它时获取设置值,而不是从中获取设置值.

另请注意,如果您使用缓存,则settings.py可能会将某些值存储在缓存中,并且可能会被缓存的值掩盖.为此,Django关于" 覆盖设置 " 的文档提供了解决此类问题的提示:

覆盖设置时,请确保处理应用程序代码使用缓存或类似功能的情况,即使设置已更改,也会保留状态.Django提供的django.test.signals.setting_changed信号允许您在更改设置时注册回调以清除和重置状态.

思想,没有给出实现它的方法.接下来问这个问题可能是个好问题......