我写了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 %}