在 Django 中覆盖单元测试的设置无法正常工作
Overriding Settings for unit tests in Django doesn't work properly
我试图对我的 Django 程序进行单元测试,我想检查 settings.py
文件中几个变量的几个值。
在文档中,“Overriding settings”部分描述了一种方法。但是,尽管我进行了所有尝试,但在测试 运行ning 期间,我无法使更改在程序中可用。以下是我在一个最小示例中所做的总结:
首先,创建一个新项目:
$ 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)。
那么,我缺少什么才能让它正常工作?
只是总结一下我从 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
的某些值可能会存储在其中,并且可能会被其缓存值掩盖。为此,Django 关于“Overriding settings”的文档给出了解决此类问题的提示:
When overriding settings, make sure to handle the cases in which your app’s code uses a cache or similar feature that retains state even if the setting is changed. Django provides the django.test.signals.setting_changed
signal that lets you register callbacks to clean up and otherwise reset state when settings are changed.
想了想,真正实现的方法没有给出。下一个问题可能是个好问题...
你应该使用@override_settings装饰器。 https://docs.djangoproject.com/en/1.4/topics/testing/#django.test.utils.override_settings
我试图对我的 Django 程序进行单元测试,我想检查 settings.py
文件中几个变量的几个值。
在文档中,“Overriding settings”部分描述了一种方法。但是,尽管我进行了所有尝试,但在测试 运行ning 期间,我无法使更改在程序中可用。以下是我在一个最小示例中所做的总结:
首先,创建一个新项目:
$ 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)。
那么,我缺少什么才能让它正常工作?
只是总结一下我从 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
的某些值可能会存储在其中,并且可能会被其缓存值掩盖。为此,Django 关于“Overriding settings”的文档给出了解决此类问题的提示:
When overriding settings, make sure to handle the cases in which your app’s code uses a cache or similar feature that retains state even if the setting is changed. Django provides the
django.test.signals.setting_changed
signal that lets you register callbacks to clean up and otherwise reset state when settings are changed.
想了想,真正实现的方法没有给出。下一个问题可能是个好问题...
你应该使用@override_settings装饰器。 https://docs.djangoproject.com/en/1.4/topics/testing/#django.test.utils.override_settings