简体   繁体   English

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

[英]Overriding Settings for unit tests in Django doesn't work properly

I tried to unit test my Django program and I would like to check several values for a few variables in my settings.py file. 我试图对我的Django程序进行单元测试,我想在settings.py文件中检查几个变量的几个值。

In the documentation, the section " Overriding settings " is describing a way to do it. 在文档中,“ 覆盖设置 ”部分描述了一种方法。 But, despite all my attempts, I miserably fail to make the changes available in the program while the test is running. 但是,尽管我尝试了所有的尝试,但在测试运行时,我很难在程序中进行更改。 Here is a summary of what I do on a minimal example: 以下是我在最小示例上所做的总结:

First, create a new project: 首先,创建一个新项目:

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

Then, add the following files. 然后,添加以下文件。

File settings.py 文件settings.py

...

TEST_VALUE = 'a'

File tests.py 文件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')

When I run the tests, I get the following: 当我运行测试时,我得到以下内容:

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

As you may have noticed, the original value of TEST_VALUE is 'a' , and I try to modify it through the self.settings(TEST_VALUE='b') ... but, without success. 您可能已经注意到, TEST_VALUE的原始值是'a' ,我尝试通过self.settings(TEST_VALUE='b')修改它......但是没有成功。

You may try it through an empty project (Django is 1.6.5). 您可以尝试通过一个空项目(Django是1.6.5)。

So, what am I missing to get it work properly ? 那么,我错过了什么让它正常工作?

Just to sum up what I understood from the comment from Ismail Badawi, in fact, I was not calling properly the variable from the settings.py because I was using from myapp.settings import TEST_VALUE , where I should have call it using from django.conf import settings and then settings.TEST_VALUE . 只是为了总结我从Ismail Badawi的评论中理解的事实,我实际上并没有正确调用settings.py的变量,因为我使用的from myapp.settings import TEST_VALUE ,我应该使用from django.conf import settings调用它from django.conf import settings ,然后是settings.TEST_VALUE

So, here is a proper tests.py file: 所以,这是一个正确的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')

And, here is the result of ./manage.py test : 并且,这是./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'...

So, the lesson of this little story is to always get your settings values from django.conf and not from myapp.settings when you use it. 因此,这个小故事的教训是始终从django.conf获取设置值,而不是在使用它时从myapp.settings

Note also that if you are using a cache, some values of your settings.py may be stored in it and could be masked by their cached value. 另请注意,如果您使用的是缓存,则settings.py某些值可能会存储在其中,并且可能会被缓存的值屏蔽。 For that, the documentation of Django on " Overriding settings " gives a hint to solve this kind of problem: 为此,Django关于“ 覆盖设置 ”的文档提供了解决此类问题的提示:

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. Django提供了django.test.signals.setting_changed信号,该信号允许您在设置更改时注册回调以清除和重置状态。

Thought, the way to implement it for real is not given. 思想,没有给出实现它的方法。 It could be a good question to ask next... 接下来问这个问题可能是个好问题......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM