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

时间:2015-03-01 22:14:54

标签: python django unit-testing django-settings

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

在文档中," Overriding settings"正在描述一种方法。但是,尽管我尝试了所有的尝试,但在测试运行时,我很难在程序中进行更改。以下是我在最小例子上所做的工作的总结:

首先,创建一个新项目:

$ pyvenv virtualenv
$ cd virtualenv/
$ . bin/activate
(virtualenv) $ pip install django
(virtualenv) $ django-admin startproject myapp
(virtualenv) $ cd myapp/

然后,添加以下文件。

档案settings.py

...

TEST_VALUE = 'a'

档案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')

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

$ ./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'...

您可能已经注意到,TEST_VALUE的原始值为'a',我尝试通过self.settings(TEST_VALUE='b')进行修改...但是没有成功。

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

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

2 个答案:

答案 0 :(得分:9)

总结一下我从Ismail Badawi的评论中得到的理解,事实上,我没有正确地调用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')

而且,这是./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'...

因此,这个小故事的教训是始终从django.conf获取设置值,而不是从myapp.settings获取设置值。

另请注意,如果您使用的是缓存,则settings.py的某些值可能会存储在其中,并且可能会被缓存的值屏蔽。为此,关于“Overriding settings”的Django文档提供了解决此类问题的提示:

  

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

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

答案 1 :(得分:4)