在测试期间,如何覆盖urlconf中使用的Django设置?

时间:2017-09-28 15:15:35

标签: django django-urls django-testing django-settings

在我的Django项目的urlconf中,我有类似的东西:

from django.conf import settings
from django.conf.urls import include, url

urlpatterns = [
    url(r'^{}/blog'.format(settings.MY_ROOT_DIR),
        include('weblogs.urls')),
    # ...
]

在我的settings.py我会有类似的内容:

MY_ROOT_DIR = 'phil'

这样我就可以在一个地方(设置)设置在多个地方使用的根目录。

当我来测试网址时,我使用了@override_settings decorator

from django.test import TestCase, override_settings
from django.urls import reverse

@override_settings(MY_ROOT_DIR='terry')
class WeblogUrlsTestCase(TestCase):

        def test_post_detail_url(self):
            self.assertEqual(
                reverse('post_detail', kwargs={'slug': 'my-post'}),
                '/terry/blog/my-post/'
            )

但是,@override_settings似乎无法执行任何操作 - MY_ROOT_DIR中使用的urls.py值始终为"phil",绝不会覆盖"terry"的设置。我也尝试了@modify_settings,并在测试方法上使用它,而不是在类。

我想在@override_settings生效之前,Django会加载urlconf吗?有没有解决的办法?还是一个更好的解决方案?

1 个答案:

答案 0 :(得分:3)

正如您所猜测的那样,您已经在网址中导入后重置设置。如果您在某个方法中使用了settings变量,而不是在urls.py的全局范围内,那么这将起作用。

虽然在运行时覆盖设置配置似乎很方便,但在我看来,您应该创建一个单独的文件进行测试。这样可以节省大量的测试配置,这可以确保您永远不会做出不可逆转的事情(比如清理登台数据库)。

# test_settings.py

MY_ROOT_DIR = 'terry'

假设您的测试文件存在于' my_project / test_settings.py',添加

settings = 'my_project.test_settings' if 'test' in sys.argv else 'my_project.settings'
在您的manage.py中

。这将确保您在运行python manage.py test时仅使用test_settings。如果您正在使用其他测试客户端,例如pytest,您可以轻松地将其添加到pytest.ini