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

Posted

技术标签:

【中文标题】在测试期间,如何覆盖 urlconf 中使用的 Django 设置?【英文标题】:During tests, how to override a Django setting used in the urlconf? 【发布时间】:2018-03-10 09:47:50 【问题描述】:

在我的 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 似乎没有做任何事情 - urls.py 中使用的 MY_ROOT_DIR 值始终是 "phil",而不是 "terry" 的覆盖设置。我也试过@modify_settings,并在测试方法上使用它,而不是在类上。

我猜 urlconf 是在 @override_settings 生效之前由 Django 加载的?有没有解决的办法?还是完全有更好的解决方案?

【问题讨论】:

【参考方案1】:

正如您所猜测的,您已经在 url 中导入设置后覆盖了设置。如果您在某个方法中使用了 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

【讨论】:

啊,当然。我已经有一个单独的设置文件用于测试,但出于某种原因,我没有想到要使用它!我今天的大脑一定很累:)谢谢! 我不得不再等五分钟才让我这么做!

以上是关于在测试期间,如何覆盖 urlconf 中使用的 Django 设置?的主要内容,如果未能解决你的问题,请参考以下文章

Django:在中间件中用 request.urlconf 覆盖 ROOT_URLCONF

Spring Boot:@TestConfiguration 在集成测试期间不覆盖 Bean

在构建期间覆盖使用 automake/libtool 构建的共享库中的安装路径,以便在无法使用 DYLD_LIBRARY_PATH 时进行测试

如何在其上制作一个简单的 Django URLconf 和 reverse() 进行测试? (获取TypeError:不可散列的类型:'list')

如何:获取代码覆盖率数据

如何从覆盖范围中排除文件?