【问题标题】:How do I unit test django urls?如何对 django url 进行单元测试?
【发布时间】:2013-09-29 23:46:08
【问题描述】:

除了urls.py 之外,我的应用程序在所有地方都实现了 100% 的测试覆盖率。对于如何为我的 URL 编写有意义的单元测试,您有什么建议吗?

FWIW 这个问题出现在我正在试验测试驱动开发并希望在我编写代码修复它们之前失败的测试。

【问题讨论】:

    标签: django unit-testing tdd django-urls


    【解决方案1】:

    一种方法是reverse URL 名称并验证

    例子

    urlpatterns = [
        url(r'^archive/(\d{4})/$', archive, name="archive"),
        url(r'^archive-summary/(\d{4})/$', archive, name="archive-summary"),
    ]
    

    现在,在测试中

    from django.urls import reverse
    
    url = reverse('archive', args=[1988])
    assertEqual(url, '/archive/1988/')
    
    url = reverse('archive-summary', args=[1988])
    assertEqual(url, '/archive-summary/1988/')
    

    无论如何,您可能正在测试视图。

    现在,要测试 URL 是否连接到正确的视图,您可以使用 resolve

    from django.urls import resolve
    
    resolver = resolve('/summary/')
    assertEqual(resolver.view_name, 'summary')
    

    现在在变量resolverResolverMatch 类实例)中,您有以下选项

     'app_name',
     'app_names',
     'args',
     'func',
     'kwargs',
     'namespace',
     'namespaces',
     'url_name',
     'view_name'
    

    【讨论】:

    • 仅供参考,我的同事已经接受了这个概念,并在our new unittest testing utils library 中为它创建了一个"assert"
    • 我正在使用:assertEqual(resolver.func.func_name, 'archive') 来测试解析器是否位于正确的视图上。据我了解resolver.view_name实际上是url规则的名称,而不是视图。
    • 您是否提倡在 Django 测试中使用reverse(...) 作为一般的 url 测试(即视图),或者只是在这种情况下专门用于单元测试 url?我看到它在视图测试中被大量使用,但感觉像是一种反模式。
    • 是什么让你认为这是一个反模式@tedmiston?
    • 因为我可以更改 url 中的 1 个字符来破坏我的 API,但所有测试仍然会通过。我想我们可以用一个简单的 assert equals 对每条路由进行单元测试......我只是以前没见过这样做。
    【解决方案2】:

    只是补充@karthikr 的答案(基于他的)

    ->你可以断言负责解析的视图是你期望使用resolver.func.cls的视图

    例子

    from unittest import TestCase
    from django.urls import resolve
    
    from foo.api.v1.views import FooView
    
    
    class TestUrls(TestCase):
        def test_resolution_for_foo(self):
            resolver = resolve('/api/v1/foo')
            self.assertEqual(resolver.func.cls, FooView)
    
    

    【讨论】:

    【解决方案3】:

    对不起,我发现这个地方是第一个在关键词“django url testing”下的地方。

    我完全同意我的前辈的观点,但我也确信有更好的方法来测试您的 URL。我们不应该使用“resolver = resolve('url/path')”的主要原因是当视图的名称更固定时,路径会比较流畅。

    简单来说,这样更好:

    class TestUrls(TestCase):
    
        def test_foo_url_resolves(self):
            url = reverse('bar:foo')
            self.assertEqual(resolve(url).func.view_class, FooBarView)
    

    'bar:foo' - bar 是命名空间,foo 是视图名称

    比这个

    class TestUrls(TestCase):
        def test_resolution_for_foo(self):
            resolver = resolve('/api/v1/foo')
            self.assertEqual(resolver.func.cls, FooView)
    

    【讨论】:

      猜你喜欢
      • 2010-11-24
      • 2011-02-23
      • 2018-10-09
      • 1970-01-01
      • 2013-06-14
      • 2011-02-07
      • 2012-01-08
      • 2019-11-02
      • 1970-01-01
      相关资源
      最近更新 更多