django单元测试用户登录似乎未经授权



我写了3个测试,这些测试是基于我阅读的文档编写的,目的是了解对用户登录页面进行单元测试的最佳方法。他们都有相同的目的,只是为了学习。所有这些都失败了,我想找出原因并修复它们。

登录页面重定向到根页面,如果用户经过身份验证,根页面将显示一个表。

test_login1:返回一个200,但页面内容表明登录失败,这来自login.html 的{%if form.errors%}

test_login2:返回一个200,但页面内容显示一个空表,指示request.user.is_authenticated必须为false

test_login3:返回一个302并使失败

我的测试.py

class MyPage(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.user = User.objects.create_user(
            username='jacob', email='jacob@hotmail.com', password='top_secret')
    def test_login1(self):
        response = self.client.post(reverse('login'), {'username': 'mark', 'password': 'mark'}, follow=True)
        self.assertEqual(response.status_code, 200)
        assert not "Failed to login" in response.content, "Failed to login!"
    def test_login2(self):
        request = self.factory.get(reverse('login'))
        request.user = self.user
        response = views.index(request)
        self.assertEqual(response.status_code, 200)
        assert "Pie" in response.content, "User is not authenticated!"
class AccountTests(APITestCase):
    def test_login3(self):
        self.client.login(username='jaconb', password='top_secret')
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)
        assert "Pie" in response.content, "Missing content. Actual content: %s" % response.content
        self.client.logout()

views.py:

from django.shortcuts import render_to_response
from bookstore.models import Book
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import csrf_protect 
@login_required
def index(request):
    entries = Book.objects.all()
    return render_to_response('index.html', locals())

login.html:

{% extends "index.html" %}
{% block content %}
    {% if form.errors %}
        <p>Failed to login.</p>
    {% endif %}

    <form method="post" action="{% url 'django.contrib.auth.views.login' %}">
        {% csrf_token %}
        <table>
            <tr>
                <td>{{ form.username.label_tag }}</td>
                <td>{{ form.username }}</td>
            </tr>
            <tr>
                <td>{{ form.password.label_tag }}</td>
                <td>{{ form.password }}</td>
            </tr>
       </table>
       <input type="submit" value="login" />
       <input type="hidden" name="next" value="/" />
   </form>
{% endblock %}

更新

我做了一些更正,也没有在索引页面中显示数据,而是将其移动到mybooks.html页面,但我仍然面临同样的问题:

设置.py

LOGIN_REDIRECT_URL = '/mybooks'
LOGIN_URL = '/login/'

urls.py:

urlpatterns = patterns('',
    url(r'^$', 'bookstore.views.index'),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', 'bookstore.views.index'),
    url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
    url(r'^login/$', 'django.contrib.auth.views.login', {
        'template_name': 'login.html', 'redirect_field_name': '/mybooks'
       }, name='login'),
    url(r'^mybooks/$', 'bookstore.views.mybooks'),
)

views.py:

def index(request):
    return render_to_response('index.html', locals())

@login_required
def mybooks(request):
    entries = Book.objects.all()
    return render_to_response('mybooks.html', locals())

tests.py:

class MyPage(TestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.user = User.objects.create_user(
            username='jacob', email='jacob@hotmail.com', password='top_secret')
    def test_login1(self):
        response = self.client.post(reverse('login'), {'username': self.user.username, 'password': self.user.password}, follow=True)
        self.assertEqual(response.status_code, 200)
        assert not "Failed to login" in response.content, "Failed to login!"
    def test_login2(self):
        request = self.factory.post(reverse('login'))
        request.user = self.user
        response = views.mybooks(request)
        self.assertEqual(response.status_code, 200)
        assert "Pie" in response.content, "Missing content. Actual content: %s" % response.content
class AccountTests(APITestCase):
    def setUp(self):
        self.factory = RequestFactory()
        self.user = User.objects.create_user(
            username='jacob', email='jacob@hotmail.com', password='top_secret')

    def test_login3(self):
        self.client.login(username=self.user.username, password=self.user.password)
        response = self.client.get('/mybooks', follow=True)
        self.assertEqual(response.status_code, 200)
        assert "Pie" in response.content, "Missing content. Actual content: %s" % response.content
        self.client.logout()

mybooks.html:

{% extends "index.html" %}
{% block content %}
    {% if form.errors %}
        <p>Failed to login.</p>
    {% endif %}
      <div align="right"><a href="/">home</a></div>
      <br/>
      <table border="1">
      <tr><td><strong>Title</strong></td><td><strong>Author</strong></td><td><strong>Description</strong></td></tr></strong>
      {% for book in entries %}
        <tr>
          <td>{{ book.title }}</td>
          <td>{{ book.author }}</td>
          <td>{{ book.description }}</td>
        </tr>
      {% endfor %}
      </table>
{% endblock %}

test_login1:您正试图使用不存在的用户登录,请先创建用户(或者只使用self.user凭据!):

    def test_login1(self):
            User.objects.create_user(
                username='mark',
                email='mark@something.xy',
                password='mark'
                )
        response = self.client.post(reverse('login'), {'username': 'mark', 'password': 'mark'}, follow=True)
        self.assertEqual(response.status_code, 200)
        assert not "Failed to login" in response.content, "Failed to login!"

test_login2:您的登录表单使用POST方法而不是GET!试试这个:

request = self.factory.post(reverse('login'))

test_login3:用户名错误,请注意jaconb而不是jacob
此外,该测试还需要重定向,因为它正在测试登录页面上不存在的一些内容
(注意:assert "Pie" in response.content,其中"Pie"永远不会出现在登录页面上!您可能应该在settings.py中检查LOGIN_REDIRECT_URL

我希望这能有所帮助!


要让"馅饼"显示给经过身份验证的用户,请尝试此模板标签:

{% if user.is_authenticated %} <a>Pie</a> {% endif %}

最新更新