为什么Django重定向测试失败?

时间:2013-08-05 18:10:38

标签: django django-views django-testing

我有一个失败的视图单元测试,我无法弄清楚原因。我认为它与测试数据库有关。有问题的视图是默认的Django登录视图django.contrib.auth.views.login。在我的项目中,用户登录后,会将它们重定向到显示哪些成员已登录的页面。我只删除了该页面。

以下是单元测试:

from django.test import TestCase
from django.contrib.auth.models import User
from django.test.client import Client, RequestFactory
from django.core.urlresolvers import reverse
from utils.factories import UserFactory

class TestSignInView(TestCase):
    def setUp(self):
        self.client = Client()
        # self.user = UserFactory()
        self.user = User.objects.create_user(username='jdoe', password='jdoepass')

    def tearDown(self):
        self.user.delete()

    def test_user_enters_valid_data(self):
        response = self.client.post(reverse('login'), {'username': self.user.username, 'password': self.user.password}, follow=True)
        print response.context['form'].errors
        self.assertRedirects(response, reverse('show-members-online'))

这是我得到的错误:

File "/Users/me/.virtualenvs/sp/lib/python2.7/site-packages/django/test/testcases.py", line 576, in assertRedirects
(response.status_code, status_code))
AssertionError: Response didn't redirect as expected: Response code was 200 (expected 302)
<ul class="errorlist"><li>__all__<ul class="errorlist"><li>Please enter a correct username and password. Note that both fields may be case-sensitive.</li></ul></li></ul>

无论是使用create_user函数手动创建用户还是使用此factory_boy工厂,测试都会失败并出现相同的错误:

from django.contrib.auth.models import User
class UserFactory(factory.DjangoModelFactory):
    FACTORY_FOR = User
    username = 'jdoe'
    # password = 'jdoepass'
    password = factory.PostGenerationMethodCall('set_password', 'jdoepass')
    email = 'jdoe@example.com'  

以下是我在成功登录后将用户重定向到的视图:

from django.shortcuts import render
def show_members_online(request, template):
    return render(request, template)

我打印出错误,表明测试无法识别用户名/密码对。我还在测试中打印出用户名和密码,以确认它们与我在setUp中初始化它们的值相同。起初,当我使用用户工厂时,我认为这是因为我在创建用户时没有加密密码。那时我做了一些研究并得知我需要使用PostGenerationMethodCall来设置密码。

我还查看了Django的testcases.py文件。我不明白它正在做的一切,但它促使我在我做帖子时尝试设置'follow = True',但这并没有什么不同。谁能告诉我我做错了什么?顺便说一句,我正在使用测试作为我的测试跑步者。

谢谢!

2 个答案:

答案 0 :(得分:2)

在您的测试test_user_enters_valid_data中,您将密码作为self.user.password传递。这将是密码的SHA,因为Django在db上存储密码sha。这就是为什么你永远不能使用user.password读取特定用户的密码。

因此,请更改您的test_user_enters_valid_data

def test_user_enters_valid_data(self):
    response = self.client.post(reverse('login'), {'username': self.user.username, 'password': 'jdoepass'}, follow=True)
    #### 
    ####

然后就可以了。

答案 1 :(得分:1)

您的测试是在POST中发送{'username': self.user.username, 'password': self.user.password}。但是,self.user.password是散列密码而不是纯文本密码,这就是它们不匹配的原因,您看到的是表单错误而不是重定向。将此更改为{'username': self.user.username, 'password': 'jdoepass'}应验证用户名/密码组合。