我正在使用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>
我仍然不确定如何最合理地测试此程序。我是Django的新手,也是它测试框架的哲学。可能是,这个问题不直接落入Django测试框架的范围,在这个框架中,模型,视图和表单(看似)是打算相互分离测试的?这个测试是否属于独立测试套件进行黑盒/功能测试的领域,例如,使用Selenium?
我是这样开始的:
开始了一个新项目,如下:
django-admin.py startproject login_test
在login_test/urls.py
添加了一个条目,如下所示:
urlpatterns = patterns('',
url(r'^login/$', 'django.contrib.auth.views.login'),
url(r'^admin/', include(admin.site.urls)),
)
在/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 %}
将模板目录添加到TEMPLATE_DIRS
中的login_test/settings.py
,如下所示:
TEMPLATE_DIRS = (
'/home/moooeeeep/login_test/templates/',
)
同步数据库以获取与auth相关的表,并添加了这样的超级用户:
python manage.py syncdb
如果我没有错过任何一步,此时我可以登录我的网站。登录后我会显示我的用户名,如果没有,我会看到表单,如果登录失败,它会显示错误信息。
我的测试用例在提交正确的帖子数据后,可以看到失败的登录响应,用户没有登录。
这是我的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)
这是输出:
$ 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'...
这是我的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/',
)
答案 0 :(得分:9)
我发现我传递的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)
这是输出:
$ python manage.py test
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.196s
OK
Destroying test database for alias 'default'...
答案 1 :(得分:6)
你不想检查&#34; is_active&#34;布尔值,你想要检查
response.context['user'].is_authenticated
请参阅: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