1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

boulder-oracle-sprint: Merged to [5182]

git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@5183 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Boulder Sprinters 2007-05-10 15:51:59 +00:00
parent e5ded41f31
commit 12702bc683
11 changed files with 229 additions and 44 deletions

View File

@ -49,9 +49,12 @@ def build_suite(app_module):
pass pass
else: else:
# The module exists, so there must be an import error in the # The module exists, so there must be an import error in the
# test module itself. We don't need the module; close the file # test module itself. We don't need the module; so if the
# handle returned by find_module. # module was a single file module (i.e., tests.py), close the file
mod[0].close() # handle returned by find_module. Otherwise, the test module
# is a directory, and there is nothing to close.
if mod[0]:
mod[0].close()
raise raise
return suite return suite

View File

@ -56,32 +56,35 @@ class TestCase(unittest.TestCase):
self._pre_setup() self._pre_setup()
super(TestCase, self).run(result) super(TestCase, self).run(result)
def assertRedirects(self, response, expected_path): def assertRedirects(self, response, expected_path, status_code=302, target_status_code=200):
"""Assert that a response redirected to a specific URL, and that the """Assert that a response redirected to a specific URL, and that the
redirect URL can be loaded. redirect URL can be loaded.
""" """
self.assertEqual(response.status_code, 302, self.assertEqual(response.status_code, status_code,
"Response didn't redirect: Reponse code was %d" % response.status_code) "Response didn't redirect: Reponse code was %d (expected %d)" %
(response.status_code, status_code))
scheme, netloc, path, params, query, fragment = urlparse(response['Location']) scheme, netloc, path, params, query, fragment = urlparse(response['Location'])
self.assertEqual(path, expected_path, self.assertEqual(path, expected_path,
"Response redirected to '%s', expected '%s'" % (path, expected_path)) "Response redirected to '%s', expected '%s'" % (path, expected_path))
redirect_response = self.client.get(path) redirect_response = self.client.get(path)
self.assertEqual(redirect_response.status_code, 200, self.assertEqual(redirect_response.status_code, target_status_code,
"Couldn't retrieve redirection page '%s'" % path) "Couldn't retrieve redirection page '%s': response code was %d (expected %d)" %
(path, response.status_code, status_code))
def assertContains(self, response, text, count=1): def assertContains(self, response, text, count=1, status_code=200):
"""Assert that a response indicates that a page was retreived successfully, """Assert that a response indicates that a page was retreived successfully,
(i.e., the HTTP status code was 200), and that ``text`` occurs ``count`` (i.e., the HTTP status code was as expected), and that ``text`` occurs ``count``
times in the content of the response. times in the content of the response.
""" """
self.assertEqual(response.status_code, 200, self.assertEqual(response.status_code, status_code,
"Couldn't retrieve page'") "Couldn't retrieve page: Response code was %d (expected %d)'" %
(response.status_code, status_code))
real_count = response.content.count(text) real_count = response.content.count(text)
self.assertEqual(real_count, count, self.assertEqual(real_count, count,
"Could only find %d of %d instances of '%s' in response" % (real_count, count, text)) "Found %d instances of '%s' in response (expected %d)" % (real_count, text, count))
def assertFormError(self, response, form, field, errors): def assertFormError(self, response, form, field, errors):
"Assert that a form used to render the response has a specific field error" "Assert that a form used to render the response has a specific field error"
if not response.context: if not response.context:
@ -102,18 +105,21 @@ class TestCase(unittest.TestCase):
for i,context in enumerate(contexts): for i,context in enumerate(contexts):
if form in context: if form in context:
found_form = True found_form = True
try: for err in errors:
for err in errors: if field:
if field: if field in context[form].errors:
self.assertTrue(err in context[form].errors[field], self.assertTrue(err in context[form].errors[field],
"The field '%s' on form '%s' in context %d does not contain the error '%s' (actual errors: %s)" % "The field '%s' on form '%s' in context %d does not contain the error '%s' (actual errors: %s)" %
(field, form, i, err, list(context[form].errors[field]))) (field, form, i, err, list(context[form].errors[field])))
elif field in context[form].fields:
self.fail("The field '%s' on form '%s' in context %d contains no errors" %
(field, form, i))
else: else:
self.assertTrue(err in context[form].non_field_errors(), self.fail("The form '%s' in context %d does not contain the field '%s'" % (form, i, field))
"The form '%s' in context %d does not contain the non-field error '%s' (actual errors: %s)" % else:
(form, i, err, list(context[form].non_field_errors()))) self.assertTrue(err in context[form].non_field_errors(),
except KeyError: "The form '%s' in context %d does not contain the non-field error '%s' (actual errors: %s)" %
self.fail("The form '%s' in context %d does not contain the field '%s'" % (form, i, field)) (form, i, err, list(context[form].non_field_errors())))
if not found_form: if not found_form:
self.fail("The form '%s' was not used to render the response" % form) self.fail("The form '%s' was not used to render the response" % form)

View File

@ -472,9 +472,9 @@ Normal Python unit tests have a wide range of assertions, such as
``django.TestCase`` adds to these, providing some assertions ``django.TestCase`` adds to these, providing some assertions
that can be useful in testing the behavior of web sites. that can be useful in testing the behavior of web sites.
``assertContains(response, text, count=1)`` ``assertContains(response, text, count=1, status_code=200)``
Assert that a response indicates that a page was retrieved successfully, Assert that a response indicates that a page could be retrieved and
(i.e., the HTTP status code was 200), and that ``text`` occurs ``count`` produced the nominated status code, and that ``text`` occurs ``count``
times in the content of the response. times in the content of the response.
``assertFormError(response, form, field, errors)`` ``assertFormError(response, form, field, errors)``
@ -493,9 +493,10 @@ that can be useful in testing the behavior of web sites.
Assert that the template with the given name was *not* used in rendering Assert that the template with the given name was *not* used in rendering
the response. the response.
``assertRedirects(response, expected_path)`` ``assertRedirects(response, expected_path, status_code=302, target_status_code=200)``
Assert that the response received redirects the browser to the provided Assert that the response received produced the nominated status code,
path, and that the expected_path can be retrieved. redirects the browser to the provided path, and that retrieving the provided
path yields a response with the target status code.
``assertTemplateUsed(response, template_name)`` ``assertTemplateUsed(response, template_name)``
Assert that the template with the given name was used in rendering the Assert that the template with the given name was used in rendering the

View File

@ -34,13 +34,6 @@ class ClientTest(TestCase):
self.assertEqual(response.context['var'], 42) self.assertEqual(response.context['var'], 42)
self.assertEqual(response.template.name, 'GET Template') self.assertEqual(response.template.name, 'GET Template')
def test_no_template_view(self):
"Check that template usage assersions work then templates aren't in use"
response = self.client.get('/test_client/no_template_view/')
# Check that the no template case doesn't mess with the template assertions
self.assertTemplateNotUsed(response, 'GET Template')
def test_get_post_view(self): def test_get_post_view(self):
"GET a view that normally expects POSTs" "GET a view that normally expects POSTs"
response = self.client.get('/test_client/post_view/', {}) response = self.client.get('/test_client/post_view/', {})
@ -75,6 +68,7 @@ class ClientTest(TestCase):
self.failUnless('Data received' in response.content) self.failUnless('Data received' in response.content)
def test_raw_post(self): def test_raw_post(self):
"POST raw data (with a content type) to a view"
test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>""" test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>"""
response = self.client.post("/test_client/raw_post_view/", test_doc, response = self.client.post("/test_client/raw_post_view/", test_doc,
content_type="text/xml") content_type="text/xml")
@ -89,6 +83,28 @@ class ClientTest(TestCase):
# Check that the response was a 302 (redirect) # Check that the response was a 302 (redirect)
self.assertRedirects(response, '/test_client/get_view/') self.assertRedirects(response, '/test_client/get_view/')
def test_permanent_redirect(self):
"GET a URL that redirects permanently elsewhere"
response = self.client.get('/test_client/permanent_redirect_view/')
# Check that the response was a 301 (permanent redirect)
self.assertRedirects(response, '/test_client/get_view/', status_code=301)
def test_redirect_to_strange_location(self):
"GET a URL that redirects to a non-200 page"
response = self.client.get('/test_client/double_redirect_view/')
# Check that the response was a 302, and that
# the attempt to get the redirection location returned 301 when retrieved
self.assertRedirects(response, '/test_client/permanent_redirect_view/', target_status_code=301)
def test_notfound_response(self):
"GET a URL that responds as '404:Not Found'"
response = self.client.get('/test_client/bad_view/')
# Check that the response was a 404, and that the content contains MAGIC
self.assertContains(response, 'MAGIC', status_code=404)
def test_valid_form(self): def test_valid_form(self):
"POST valid data to a form" "POST valid data to a form"
post_data = { post_data = {

View File

@ -1,12 +1,15 @@
from django.conf.urls.defaults import * from django.conf.urls.defaults import *
from django.views.generic.simple import redirect_to
import views import views
urlpatterns = patterns('', urlpatterns = patterns('',
(r'^no_template_view/$', views.no_template_view),
(r'^get_view/$', views.get_view), (r'^get_view/$', views.get_view),
(r'^post_view/$', views.post_view), (r'^post_view/$', views.post_view),
(r'^raw_post_view/$', views.raw_post_view), (r'^raw_post_view/$', views.raw_post_view),
(r'^redirect_view/$', views.redirect_view), (r'^redirect_view/$', views.redirect_view),
(r'^permanent_redirect_view/$', redirect_to, { 'url': '/test_client/get_view/' }),
(r'^double_redirect_view/$', views.double_redirect_view),
(r'^bad_view/$', views.bad_view),
(r'^form_view/$', views.form_view), (r'^form_view/$', views.form_view),
(r'^form_view_with_template/$', views.form_view_with_template), (r'^form_view_with_template/$', views.form_view_with_template),
(r'^login_protected_view/$', views.login_protected_view), (r'^login_protected_view/$', views.login_protected_view),

View File

@ -1,16 +1,12 @@
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
from django.core.mail import EmailMessage, SMTPConnection from django.core.mail import EmailMessage, SMTPConnection
from django.template import Context, Template from django.template import Context, Template
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.newforms.forms import Form from django.newforms.forms import Form
from django.newforms import fields from django.newforms import fields
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
def no_template_view(request):
"A simple view that expects a GET request, and returns a rendered template"
return HttpResponse("No template used")
def get_view(request): def get_view(request):
"A simple view that expects a GET request, and returns a rendered template" "A simple view that expects a GET request, and returns a rendered template"
t = Template('This is a test. {{ var }} is the value.', name='GET Template') t = Template('This is a test. {{ var }} is the value.', name='GET Template')
@ -54,6 +50,14 @@ def redirect_view(request):
"A view that redirects all requests to the GET view" "A view that redirects all requests to the GET view"
return HttpResponseRedirect('/test_client/get_view/') return HttpResponseRedirect('/test_client/get_view/')
def double_redirect_view(request):
"A view that redirects all requests to a redirection view"
return HttpResponseRedirect('/test_client/permanent_redirect_view/')
def bad_view(request):
"A view that returns a 404 with some error content"
return HttpResponseNotFound('Not found!. This page contains some MAGIC content')
TestChoices = ( TestChoices = (
('a', 'First Choice'), ('a', 'First Choice'),
('b', 'Second Choice'), ('b', 'Second Choice'),

View File

@ -0,0 +1,136 @@
"""
Regression tests for the Test Client, especially the customized assertions.
"""
from django.test import Client, TestCase
from django.core import mail
class AssertTemplateUsedTests(TestCase):
fixtures = ['testdata.json']
def test_no_context(self):
"Template usage assertions work then templates aren't in use"
response = self.client.get('/test_client_regress/no_template_view/')
# Check that the no template case doesn't mess with the template assertions
self.assertTemplateNotUsed(response, 'GET Template')
try:
self.assertTemplateUsed(response, 'GET Template')
except AssertionError, e:
self.assertEquals(str(e), "No templates used to render the response")
def test_single_context(self):
"Template assertions work when there is a single context"
response = self.client.get('/test_client/post_view/', {})
#
try:
self.assertTemplateNotUsed(response, 'Empty GET Template')
except AssertionError, e:
self.assertEquals(str(e), "Template 'Empty GET Template' was used unexpectedly in rendering the response")
try:
self.assertTemplateUsed(response, 'Empty POST Template')
except AssertionError, e:
self.assertEquals(str(e), "Template 'Empty POST Template' was not used to render the response. Actual template was 'Empty GET Template'")
def test_multiple_context(self):
"Template assertions work when there are multiple contexts"
post_data = {
'text': 'Hello World',
'email': 'foo@example.com',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view_with_template/', post_data)
self.assertContains(response, 'POST data OK')
try:
self.assertTemplateNotUsed(response, "form_view.html")
except AssertionError, e:
self.assertEquals(str(e), "Template 'form_view.html' was used unexpectedly in rendering the response")
try:
self.assertTemplateNotUsed(response, 'base.html')
except AssertionError, e:
self.assertEquals(str(e), "Template 'base.html' was used unexpectedly in rendering the response")
try:
self.assertTemplateUsed(response, "Valid POST Template")
except AssertionError, e:
self.assertEquals(str(e), "Template 'Valid POST Template' was not one of the templates used to render the response. Templates used: ['form_view.html', 'base.html']")
class AssertFormErrorTests(TestCase):
def test_unknown_form(self):
"An assertion is raised if the form name is unknown"
post_data = {
'text': 'Hello World',
'email': 'not an email address',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "Invalid POST Template")
try:
self.assertFormError(response, 'wrong_form', 'some_field', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The form 'wrong_form' was not used to render the response")
def test_unknown_field(self):
"An assertion is raised if the field name is unknown"
post_data = {
'text': 'Hello World',
'email': 'not an email address',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "Invalid POST Template")
try:
self.assertFormError(response, 'form', 'some_field', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The form 'form' in context 0 does not contain the field 'some_field'")
def test_noerror_field(self):
"An assertion is raised if the field doesn't have any errors"
post_data = {
'text': 'Hello World',
'email': 'not an email address',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "Invalid POST Template")
try:
self.assertFormError(response, 'form', 'value', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The field 'value' on form 'form' in context 0 contains no errors")
def test_unknown_error(self):
"An assertion is raised if the field doesn't contain the provided error"
post_data = {
'text': 'Hello World',
'email': 'not an email address',
'value': 37,
'single': 'b',
'multi': ('b','c','e')
}
response = self.client.post('/test_client/form_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "Invalid POST Template")
try:
self.assertFormError(response, 'form', 'email', 'Some error.')
except AssertionError, e:
self.assertEqual(str(e), "The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [u'Enter a valid e-mail address.'])")

View File

@ -0,0 +1,7 @@
from django.conf.urls.defaults import *
from django.views.generic.simple import redirect_to
import views
urlpatterns = patterns('',
(r'^no_template_view/$', views.no_template_view),
)

View File

@ -0,0 +1,8 @@
from django.core.mail import EmailMessage, SMTPConnection
from django.http import HttpResponse
from django.shortcuts import render_to_response
def no_template_view(request):
"A simple view that expects a GET request, and returns a rendered template"
return HttpResponse("No template used")

View File

@ -3,6 +3,7 @@ from django.conf.urls.defaults import *
urlpatterns = patterns('', urlpatterns = patterns('',
# test_client modeltest urls # test_client modeltest urls
(r'^test_client/', include('modeltests.test_client.urls')), (r'^test_client/', include('modeltests.test_client.urls')),
(r'^test_client_regress/', include('regressiontests.test_client_regress.urls')),
# Always provide the auth system login and logout views # Always provide the auth system login and logout views
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}), (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),