moo*_*eep 9 django validation django-forms django-authentication django-testing
我正在使用Django 1.6开发一个Web应用程序,我要求用户使用我的登录表单登录.我想编写一个测试用例来测试登录用户的过程.
我确实成功获得了一个工作登录页面,这意味着我能够登录.以下步骤解释了我的设置.但是,为此过程编写测试用例确实失败了.在这一点上,我既不能在测试中发现错误,也不确定这种方法是否有意义.有人能帮我吗?
更新:在此期间我注意到,我的表单错误消息太不明确了.该问题似乎是由表单字段验证步骤失败的空表单字段引起的.当我将错误添加{{ form.errors }}到模板时,响应包含以下内容(格式不太好):
<ul class="errorlist">
<li>username
<ul class="errorlist">
<li>This field is required.</li>
</ul>
</li>
<li>password
<ul class="errorlist">
<li>This field is required.</li>
</ul>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
我仍然不确定如何最合理地测试这个程序.我是Django的新手,也是它测试框架的哲学.可能是,这个问题不直接落入Django测试框架的范围,在这个框架中,模型,视图和表单(看似)是相互分离的(看似)?这个测试是否属于独立测试套件进行黑盒/功能测试的领域,例如,使用Selenium?
我开始是这样的:
开始了一个新项目,如下所示:
django-admin.py startproject login_test
Run Code Online (Sandbox Code Playgroud)添加了一个条目login_test/urls.py,像这样:
urlpatterns = patterns('',
url(r'^login/$', 'django.contrib.auth.views.login'),
url(r'^admin/', include(admin.site.urls)),
)
Run Code Online (Sandbox Code Playgroud)制作模板/home/moooeeeep/login_test/templates/registration/login.html,如下:
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if not user.is_active %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
<input type="hidden" name="next" value="{% url 'django.contrib.auth.views.login' %}" />
</form>
{% else %}
<p>You are logged in as <strong>{{ user.username }}</strong>.</p>
{% endif %}
Run Code Online (Sandbox Code Playgroud)将模板目录添加到TEMPLATE_DIRS中login_test/settings.py,如下所示:
TEMPLATE_DIRS = (
'/home/moooeeeep/login_test/templates/',
)
Run Code Online (Sandbox Code Playgroud)同步数据库以获取与auth相关的表,并添加了这样的超级用户:
python manage.py syncdb
Run Code Online (Sandbox Code Playgroud)如果我没有错过任何一步,此时我可以登录我的网站.登录后,我会显示我的用户名,如果没有,我会看到表单,如果登录失败,则会显示错误消息.
然而,我的测试用例在提交正确的帖子数据后,会看到失败的登录响应,用户没有登录.
这是我的login_test/tests.py:
from django.contrib.auth.models import User
from django.contrib.auth import SESSION_KEY
from django.test import TestCase
class LogInTest(TestCase):
def setUp(self):
self.credentials = {
'username': 'testuser',
'password': 'secret'}
User.objects.create_user(**self.credentials)
def test_login(self):
# login
response = self.client.post('/login/', **self.credentials)
# should be logged in now, fails however
self.assertTrue(response.context['user'].is_active)
Run Code Online (Sandbox Code Playgroud)
这是输出:
$ python manage.py test
Creating test database for alias 'default'...
F
======================================================================
FAIL: test_login (login_test.tests.LogInTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/moooeeeep/login_test/login_test/tests.py", line 16, in test_login
self.assertTrue(response.context['user'].is_active)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 1 test in 0.008s
FAILED (failures=1)
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)
这是我的login_test/settings.py:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '+6e-6t8dnl$75fx%=7y$+4ipo&i=kvw(p*963p37)7o$1-)30u'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = True
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
ROOT_URLCONF = 'login_test.urls'
WSGI_APPLICATION = 'login_test.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
TEMPLATE_DIRS = (
'/home/moooeeeep/login_test/templates/',
)
Run Code Online (Sandbox Code Playgroud)
moo*_*eep 11
我发现我传递的post参数是错误的(字典不能解压缩).我还需要了解,我需要在发送数据后遵循发布请求发出的重定向.然后我的登录测试工作(虽然重定向的目标页面尚不存在).
这是我更新的测试用例:
from django.contrib.auth.models import User
from django.test import TestCase
class LogInTest(TestCase):
def setUp(self):
self.credentials = {
'username': 'testuser',
'password': 'secret'}
User.objects.create_user(**self.credentials)
def test_login(self):
# send login data
response = self.client.post('/login/', self.credentials, follow=True)
# should be logged in now
self.assertTrue(response.context['user'].is_active)
Run Code Online (Sandbox Code Playgroud)
这是输出:
$ python manage.py test
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.196s
OK
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)
你不想检查"is_active"布尔值,你想要检查
response.context['user'].is_authenticated
Run Code Online (Sandbox Code Playgroud)
请参阅:https://docs.djangoproject.com/en/1.3/topics/auth/#django.contrib.auth.models.User.is_active
和:https://docs.djangoproject.com/en/1.3/topics/auth/#django.contrib.auth.models.User.is_authenticated
| 归档时间: |
|
| 查看次数: |
9470 次 |
| 最近记录: |