тестовый клиент django не работает, но URL работает

У меня странная проблема с некоторыми модульными тестами, которые довольно просты, но не работают. Странно то, что это работает с runserver, т. е. я могу отображать представление perfil_usuario, но в модульных тестах это не работает с NoReverseMatch.

Прежде всего, это мой основной urlconf:

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

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r"^$", include("traxx.hotsite.urls", namespace="hotsite")),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^imperavi/', include('imperavi.urls')),
    url(r"^app/", include("traxx.sistema.urls", namespace="app")),
    url(r"^usuarios/", include("traxx.usuarios.urls", namespace="usuarios")),
    url(r"^notificacoes/", include("traxx.notificacoes.urls", namespace="notificacoes")),
    url(r"^clientes/", include("traxx.clientes.urls", namespace="clientes")),
)

Мой usuarios (4-й URL-адрес в основной конфигурации) urlconf выглядит следующим образом:

# coding: utf-8
from django.conf.urls import patterns, include, url

urlpatterns = patterns("traxx.usuarios.views",
                       url(r"^perfil/(?P<id>\d+)/$", "perfil_usuario", name="perfil"),
                       url(r"^configuracoes/(?P<id>\d+)/$", "configuracoes_usuario", name="configuracoes"),
                       url(r"^login/$", "login", name="login"),
                       url(r"^logout/$", "logout", name="logout"),
)

Это вид:

def perfil_usuario(request, id):
    usuario = get_object_or_404(Usuario, pk=id)
    return render(request, "usuarios/perfil_usuario.html", {"usuario": usuario})

И это неудачный модульный тест:

class PerfilUsuarioViewTestCase(TransactionTestCase):

    """Testes para a view home"""

    def setUp(self):

        pass

    def test_get_perfil_usuario(self):

        usuario_fake = mommy.make(Usuario, nome_usuario="teste")

        c = Client()
        resposta = c.get(reverse("usuarios:perfil", kwargs={"id": usuario_fake.pk}))

        self.assertEqual(200, resposta.status_code)

Обратный вызов reverse("usuarios:perfil", kwargs={"id": usuario_fake.pk}) отлично работает, выводя /usuarios/perfil/1/.

Позвоните, чтобы изменить

>>> from django.core.urlresolvers import reverse
>>> reverse("usuarios:perfil", kwargs={"id":1})
/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/imperavi/views.py:1: DeprecationWarning: the md5 module is deprecated; use hashlib instead
  import md5

'/usuarios/perfil/1/'

Я использую Джанго 1.6.

Полная трассировка

Traceback (most recent call last):
  File "/home/george/projetos/traxx/src/traxx/testes/usuarios/views.py", line 21, in test_get_perfil_usuario
    resposta = c.get(reverse("usuarios:perfil", kwargs={"id": usuario_fake.pk}))
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/test/client.py", line 473, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/test/client.py", line 280, in get
    return self.request(**r)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/test/client.py", line 444, in request
    six.reraise(*exc_info)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/george/projetos/traxx/src/traxx/usuarios/views.py", line 12, in perfil_usuario
    return render(request, "usuarios/perfil_usuario.html", {"usuario": usuario})
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/shortcuts/__init__.py", line 53, in render
    return HttpResponse(loader.render_to_string(*args, **kwargs),
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/loader.py", line 169, in render_to_string
    return t.render(context_instance)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/base.py", line 140, in render
    return self._render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/test/utils.py", line 85, in instrumented_test_render
    return self.nodelist.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/test/utils.py", line 85, in instrumented_test_render
    return self.nodelist.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 155, in render
    return self.render_template(self.template, context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 137, in render_template
    output = template.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/base.py", line 140, in render
    return self._render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/test/utils.py", line 85, in instrumented_test_render
    return self.nodelist.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/defaulttags.py", line 447, in render
    six.reraise(*exc_info)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/template/defaulttags.py", line 433, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app)
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 509, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/home/george/projetos/.virtualenvs/traxx/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 429, in _reverse_with_prefix
    (lookup_view_s, args, kwargs, len(patterns), patterns))
NoReverseMatch: Reverse for 'perfil' with arguments '(None,)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'usuarios/perfil/(?P<id>\\d+)/$']

person George Silva    schedule 24.06.2014    source источник
comment
Не могли бы вы показать полную трассировку ошибок? Спасибо.   -  person alecxe    schedule 24.06.2014
comment
Конечно, сейчас выложу.   -  person George Silva    schedule 24.06.2014


Ответы (1)


Как видно из трассировки, id, переданное в kwargs, оценивается как None. Вот почему он не соответствует шаблону URL-адреса usuarios/perfil/(?P<id>\\d+)/$.

Другими словами, значение usuario_fake.pk равно None.

УПД:

проблема была на самом деле в шаблоне, на который жаловалась трассировка.

person alecxe    schedule 24.06.2014
comment
Я проверю это. Спасибо за просмотр всего этого кода. Иногда мы не можем видеть самые очевидные вещи. - person George Silva; 24.06.2014
comment
@George, хорошо, я лично не использовал model_mommy, но в темноте можно было бы заменить usuario_fake.pk на usuario_fake.id.. - person alecxe; 24.06.2014
comment
Я пробовал именно это. Я добавил в тест операторы печати, печатающие pk и id. Оба выводят 1. Я даже жестко запрограммировал 1 для этого теста. Обратный метод работает отлично, проверьте обновленный вопрос. - person George Silva; 24.06.2014
comment
@ Джордж, хорошо, спасибо, так что, если вы жестко запрограммируете 1, тест сработает, верно? - person alecxe; 24.06.2014
comment
@ Джордж, не могли бы вы также попробовать использовать self.client вместо создания экземпляра Client вручную? self.client.get(reverse("usuarios:perfil", kwargs={"id": usuario_fake.pk})) - person alecxe; 24.06.2014
comment
Нет, обратный вызов работает. Я пытался использовать c.get с результатом, но все равно не получается. Вызов self.client.get также не работает с тем же исключением. - person George Silva; 24.06.2014