Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更改“的”值的最佳方法;“设置”;在Python测试用例中?_Python_Django_Unit Testing_Namespaces - Fatal编程技术网

更改“的”值的最佳方法;“设置”;在Python测试用例中?

更改“的”值的最佳方法;“设置”;在Python测试用例中?,python,django,unit-testing,namespaces,Python,Django,Unit Testing,Namespaces,我第一次用Python为Django应用程序编写单元测试。我遇到了一个问题。为了测试特定的功能,我需要更改应用程序设置之一的值。这是我的第一次尝试: def test_in_list(self): mango.settings.META_LISTS = ('tags',) tags = Document(filepath).meta['tags'] self.assertEqual(tags, [u'Markdown', u'Django', u'Mango']) 我试

我第一次用Python为Django应用程序编写单元测试。我遇到了一个问题。为了测试特定的功能,我需要更改应用程序设置之一的值。这是我的第一次尝试:

def test_in_list(self):
    mango.settings.META_LISTS = ('tags',)
    tags = Document(filepath).meta['tags']
    self.assertEqual(tags, [u'Markdown', u'Django', u'Mango'])
我试图做的是更改
META_list
的值,以便在创建
文档
对象时使用新值。相关进口商品是

# tests.py
from mango.models import Document
import mango.settings

# models.py
from mango.settings import *
如果我理解正确,因为
models.py
已经从
mango.settings
导入了名称,所以在
mango.settings
中更改
META\u列表的值不会更改
mango.models
中的
META\u列表的值

有可能——甚至有可能——我的做法完全错误。在测试用例中改变这样一个“设置”值的正确方法是什么


Edit:我没有提到文件
models.py
包含普通Python类,而不是Django模型。我当然需要重命名这个文件

在models.py中,使用
导入mango.settings
。然后,您可以在测试代码中设置一个变量,就像其他变量一样:

mango.settings.foo = 'bar'
模块是一个单体。您可以从代码中的任何位置更改其命名空间中的值


但是,如果使用mango.settings import*
中的
,这将不起作用,因为该表达式将模块中的值复制到当前名称空间中。

在整个测试过程中是否会使用此设置?在这种情况下,一个解决方案是创建一个用于测试的设置文件。例如,为测试添加
设置\u.py

# settings_for_tests.py
from settings import * # Get everything from default settings file.

# Override just what is required.
META_LISTS = ('tags',)
然后运行测试,如下所示:

$ python ./manage.py test mango --settings=settings_for_tests
这将确保使用测试设置而不是默认设置创建测试数据库中的模型

如果要这样做,将设置文件移动到目录中也是有意义的。例如

project
  |
  |_ settings
  |    |
  |    |_ __init__.py # Contains merely from settings import *
  |    |_ settings.py
  |    |_ settings_for_tests.py
  |
  |_ apps
       |

有一种更简单的方法可以做到这一点

使用多个设置文件——每个文件都在适当的配置控制下

我们这样做

  • 我们有一个主
    设置
    模块,该模块具有“始终应用”设置。中间件、已安装的应用程序、我们的应用程序特有的其他设置

  • 我们有“子类”设置,(a)导入主设置,然后(b)引入特定于平台(或特定于阶段,或特定于客户)的设置。这就是我们的Windows文件路径隔离的地方。加上静态媒体文件的位置。加上特定于客户的模板路径等

  • 我们将测试脚本分成几个部分。“default”
    tests.py
    进行基本的模型、表单和视图功能测试,这些测试必须在所有平台、所有开发阶段(开发、测试、质量保证等)和所有客户上进行

  • 我们有单独的单元测试脚本,需要对特别复杂的装置进行特殊设置。这些脚本不在
    tests.py
    中,并且不会自动运行。它们需要显式调用Django的实用程序来设置和拆卸测试环境


  • 您如何建议测试一个愚蠢的函数,当特定设置为truthy时返回“hello”,当falsy时返回“再见”

    这可能表明设计很差。测试驱动设计(TDD)建议您应该将其设计为无需复杂的设置即可进行测试

    如果你必须通过设置来实现,你到底在测试什么?设置值会传播到你的代码中?这很愚蠢。你应该相信框架是有效的。事实上,你必须假设框架是有效的,否则,你必须测试框架的每一个功能


    你应该有一个接受
    设置的函数。一些设置作为参数,这样你就可以把它作为一个独立的单元来测试,而不必费心去修改整个环境。你必须相信环境和框架确实可以工作。

    对于在测试用例中更改设置,我使用这个snipp的修改版本et

    下面是我对这个片段的修改

    然后使用测试设置创建文件,然后使用(来自项目的示例):

    它将跟踪原始设置并让
    测试完成后,可以轻松地将它们还原回去。

    谢谢,Andrew,我认为可能是这样。目前,
    models.py
    在许多地方引用了这些设置,为了可读性,我希望保持导入语句的原样(
    MARKDOWN_EXTENSIONS
    mango.settings.MARKDOWN_EXTENSIONS
    更容易让人眼前一亮)。这是一个很好的答案,我喜欢你对
    导入模块
    自模块导入*
    之间的功能差异所作的解释。你也可以使用mango导入设置
    中的
    ,这两种设置都让你受益匪浅。是的,尽管在这个特殊情况下,我也在使用django.conf导入setti中的
    ngs
    ,so“设置"已经被使用了。mongo的
    作为
    如何?
    导入设置作为m_设置
    是可行的,但是如果要使用
    m_设置
    为什么不使用额外的四个字符并使用
    mango.settings
    ?这只是一个美学问题,真的。最后我可能会咬紧牙关,改变
    导入语句,但我仍然渴望了解是否存在替代方案(即,在保留
    import*
    语句的同时是否可能实现相同的结果)。非常感谢你的回答,Manoj。我意识到我应该在几个方面更清楚一些。首先,
    models.py
    中定义的类实际上不是Django模型(并且不以任何方式与数据库交互)。也许这个文件有更好的名称?其次,我需要
    class SerializationTestCase(SettingsTestCase):
        fixtures = ['test_users.json', 'test_moderation.json']
        test_settings = 'moderation.tests.settings.generic'
    
        def setUp(self):
            self.user = User.objects.get(username='moderator')
            self.profile = UserProfile.objects.get(user__username='moderator')
    
        def test_serialize_of_object(self):
            """Test if object is propertly serialized to json"""
    
            json_field = SerializedObjectField()
    
            self.assertEqual(json_field._serialize(self.profile),
                        '[{"pk": 1, "model": "test_app.userprofile", "fields": '\
                        '{"url": "http://www.google.com", "user": 1, '\
                        '"description": "Old description"}}]',
                             )