基于设置的Django Pytest测试URL

bq9c1y66  于 2023-04-22  发布在  Go
关注(0)|答案(3)|浏览(145)

我在django中有一个端点/docs,我只想在设置中显示DEBUG = True-否则,它应该抛出404。
urls.py

urlpatterns = ...

if settings.DEBUG:
    urlpatterns += [
            url(r'^docs/$', SwaggerSchemaView.as_view(), name='api_docs'),
    ]

但是,在进行测试时,django不会自动重新加载urls.py,这意味着简单地将DEBUG重写为TrueFalse是不起作用的。
我的测试看起来像这样

@override_settings(DEBUG=True)
@override_settings(ROOT_URLCONF='config.urls')
class APIDocsTestWithDebug(APITestCase):
    # check for 200s
    ...

@override_settings(DEBUG=False)
@override_settings(ROOT_URLCONF='config.urls')
class APIDocsTestWithoutDebug(APITestCase):
    # check for 404s
    ...

奇怪的是当我使用pytest path/to/test.py::APIDocsTestWithDebugpytest path/to/test.py::APIDocsTestWithoutDebug分别运行测试时,两个测试都通过了。(pytest path/to/test.py),APIDocsTestWithDebug总是失败。* 它们单独工作 * 但不一起工作的事实告诉我 *url覆盖正在工作 *,但当测试串联时,我想知道是否有人遇到过类似的问题,或者有完全不同的解决方案,或者可以给予我一些提示,我做错了什么。

gmxoilav

gmxoilav1#

我也遇到了同样的问题,问题是Django在初始化时加载了urlpatterns一次-并且用装饰器覆盖设置并不会改变最初加载的内容。
以下是我的工作-尝试重新加载您的urls模块(基于this),并在失败的测试用例之前使用clear_url_caches()清除url缓存:

import sys

from importlib import reload, import_module

from django.conf import settings
from django.core.urlresolvers import clear_url_caches  # Or -> from django.urls import clear_url_caches

def reload_urlconf(urlconf=None):
    clear_url_caches()
    if urlconf is None:
        urlconf = settings.ROOT_URLCONF
    if urlconf in sys.modules:
        reload(sys.modules[urlconf])
    else:
        import_module(urlconf)

PS:您可能还想在以后恢复urlpatterns-只需在其他settings中运行reload_urlconf

9cbw7uwe

9cbw7uwe2#

可以使用@pytest.mark.urls:https://pytest-django.readthedocs.io/en/latest/helpers.html#pytest.mark.urls

@pytest.mark.urls('myapp.test_urls')
def test_something(client):
    assert 'Success!' in client.get('/some_url_defined_in_test_urls/').content

您甚至可以在同一个文件中定义URL:

def some_view(request):
    return HttpResponse(b"Success!")

urlpatterns = [
    path("some-url/", some_view)
]

@pytest.mark.urls(__name__)
def test_something(client):
    assert b'Success!' in client.get('/some-url/').content
j5fpnvbx

j5fpnvbx3#

基于Sergei Nikiforov的回答,我实现了一个Pypi包,其中包含一个上下文管理器,用于加载/重新加载URL
Github页面:https://github.com/karpyncho/reload-urls
安装:

pip install karpyncho_reload_urls

然后你就从TestCaseReloadableURL继承你的TestCase suit类
你可以简单地用途:

from karpyncho.reload_urls import TestCaseReloadableURL
 
class TestMyClass(TestCaseReloadableURL)
def my_test(self):
    with self.reload_urls(DEBUG=True):
        # put your checks here

这将只在上下文块中重新加载设置
你可以自由地提出改进意见。

相关问题