Django测试中的URL解析问题

时间:2016-04-04 04:08:57

标签: django unit-testing python-3.x url-routing

我写了一个django模型,它有一个get_absolute_url方法,单元测试以确保一切都是犹太教。 get_absolute_url测试没有问题。 get_absolute_url方法写成如此

def get_absolute_url(self):
    return reverse("scheduling:klass", args=[self.pk])

这是url路由,用于提供有关网址流动方式的上下文。

#main.urls
urlpatterns = [
    url(r'^$', homepage, name="home"),
    url(r'^scheduling/', include('scheduling.urls', namespace="scheduling")),
    url(r'^profile/', include('user_profile.urls', namespace="profile")),
    url(r'^accounts/', include('allauth.urls')),
    url(r'^admin/', admin.site.urls),
]

#scheduling.urls
urlpatterns = [
    url(r'add-class/$', views.add_klass, name="add_klass"),
    url(r'class/(?P<pk>\d+)/$', views.klass, name="klass"),
]

我正在测试klass视图(它基本上只是一个klass详细视图),如下所示

def test_klass_detail_template_renders(self):
    print(self.klass.pk)
    response = self.client.get(self.klass.get_absolute_url())
    self.assertTemplateUsed(response, "scheduling/klass.html")

测试因以下堆栈跟踪而失败。

======================================================================
ERROR: test_klass_detail_template_renders (scheduling.tests.test_views.KlassViewTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/me/.virtualenvs/myproject/lib/python3.5/site-packages/django/core/urlresolvers.py", line 586, in reverse
    extra, resolver = resolver.namespace_dict[ns]
KeyError: 'myproject.profile'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/me/.virtualenvs/myproject/lib/python3.5/site-packages/django/template/defaulttags.py", line 507, in render
    current_app=current_app)
  File "/Users/me/.virtualenvs/myproject/lib/python3.5/site-packages/django/core/urlresolvers.py", line 596, in reverse
    key)
django.core.urlresolvers.NoReverseMatch: 'myproject.profile' is not a registered namespace

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/me/Documents/Development/myproject/src/scheduling/tests/test_views.py", line 60, in test_klass_detail_template_renders
    response = self.client.get(self.klass.get_absolute_url())
  File "/Users/me/.virtualenvs/myproject/lib/python3.5/site-packages/django/test/client.py", line 503, in get
    **extra)
  File "/Users/me/.virtualenvs/myproject/lib/python3.5/site-packages/django/test/client.py", line 304, in get
    return self.generic('GET', path, secure=secure, **r)

...
    File "/Users/me/.virtualenvs/myproject/lib/python3.5/site-packages/django/core/urlresolvers.py", line 508, in _reverse_with_prefix
        (lookup_view_s, args, kwargs, len(patterns), patterns))
    django.core.urlresolvers.NoReverseMatch: Reverse for 'profile' with arguments '('',)' and keyword arguments '{}' not found. 2 pattern(s) tried: ['profile/$', 'profile/(?
    P<username>[\\w+-.@]+)/$']

这意味着get_absolute_url正在将klass模型的pk值传递给url模式,但是当我手动测试它时它会起作用,并且它在其他所有情况下都能正常工作。

这......是... ...头部刮擦。任何帮助表示赞赏。

更新

我认为这可能与测试隔离有关。我做了一些打印调试,发现每个测试都创建了一个klass模型的新实例。

这是我的setUp和tearDown方法。

class KlassViewTests(TestCase):
def setUp(self):
    self.factory = ClassMateFactory()
    self.teacher = self.factory.create_teacher("Maria")
    self.linked_student = self.factory.create_student(
        "Milhouse",
        self.teacher.profile
    )
    self.klass = self.factory.create_klass(
        "Test Klass",
        teachers=self.teacher.profile,
        students=self.linked_student.profile
    )
    self.data = {
        "name": "New Test Class",
        "status": "A",
        "students": [self.linked_student.profile.pk],
        "teachers": [self.teacher.profile.pk]
    }
    super().setUp()

def tearDown(self):
    print(self.klass.get_absolute_url())
    self.teacher.delete()
    self.linked_student.delete()
    self.klass.delete()
    super().tearDown()

希望这有助于清理事情。

修改

添加了url conf以提供更多上下文

1 个答案:

答案 0 :(得分:1)

根据您问题的当前状态,它看起来像是复制粘贴错误。我为什么这么想:

Django将错误描述为:

django.core.urlresolvers.NoReverseMatch:
Reverse for 'profile' with arguments '('',)' and keyword arguments '{}' not found.
2 pattern(s) tried: ['profile/$', 'profile/(?P<username>[\\w+-.@]+)/$']

您已经省略了部分堆栈跟踪,因此我无法确定您的代码中导致此错误的行是:

response = self.client.get(self.klass.get_absolute_url())

有问题的模型似乎不是profile,而是名为klass

似乎 ...

此时self.klass实际上也可能是指(教师或学生)的个人资料,这就是为什么它使用profile&#39; s get_absolute_url

tl; dr我认为你只需要彻底阅读所有代码(可能会得到第二双眼睛)来找到小错误。