Refs #2333 - Added model test for the test Client.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3708 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d043200077
commit
826b9ff5e5
|
@ -0,0 +1,10 @@
|
|||
from django.dispatch import dispatcher
|
||||
from django.db.models import signals
|
||||
import models as test_client_app
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
def setup_test(app, created_models, verbosity):
|
||||
# Create a user account for the login-based tests
|
||||
User.objects.create_user('testclient','testclient@example.com', 'password')
|
||||
|
||||
dispatcher.connect(setup_test, sender=test_client_app, signal=signals.post_syncdb)
|
|
@ -0,0 +1,101 @@
|
|||
"""
|
||||
39. Testing using the Test Client
|
||||
|
||||
The test client is a class that can act like a simple
|
||||
browser for testing purposes.
|
||||
|
||||
It allows the user to compose GET and POST requests, and
|
||||
obtain the response that the server gave to those requests.
|
||||
The server Response objects are annotated with the details
|
||||
of the contexts and templates that were rendered during the
|
||||
process of serving the request.
|
||||
|
||||
Client objects are stateful - they will retain cookie (and
|
||||
thus session) details for the lifetime of the Client instance.
|
||||
|
||||
This is not intended as a replacement for Twill,Selenium, or
|
||||
other browser automation frameworks - it is here to allow
|
||||
testing against the contexts and templates produced by a view,
|
||||
rather than the HTML rendered to the end-user.
|
||||
|
||||
"""
|
||||
from django.test.client import Client
|
||||
import unittest
|
||||
|
||||
class ClientTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
"Set up test environment"
|
||||
self.client = Client()
|
||||
|
||||
def test_get_view(self):
|
||||
"GET a view"
|
||||
response = self.client.get('/test_client/get_view/')
|
||||
|
||||
# Check some response details
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context['var'], 42)
|
||||
self.assertEqual(response.template.name, 'GET Template')
|
||||
self.failUnless('This is a test.' in response.content)
|
||||
|
||||
def test_get_post_view(self):
|
||||
"GET a view that normally expects POSTs"
|
||||
response = self.client.get('/test_client/post_view/', {})
|
||||
|
||||
# Check some response details
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.template.name, 'Empty POST Template')
|
||||
|
||||
def test_empty_post(self):
|
||||
"POST an empty dictionary to a view"
|
||||
response = self.client.post('/test_client/post_view/', {})
|
||||
|
||||
# Check some response details
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.template.name, 'Empty POST Template')
|
||||
|
||||
def test_post_view(self):
|
||||
"POST some data to a view"
|
||||
post_data = {
|
||||
'value': 37
|
||||
}
|
||||
response = self.client.post('/test_client/post_view/', post_data)
|
||||
|
||||
# Check some response details
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context['data'], '37')
|
||||
self.assertEqual(response.template.name, 'POST Template')
|
||||
self.failUnless('Data received' in response.content)
|
||||
|
||||
def test_redirect(self):
|
||||
"GET a URL that redirects elsewhere"
|
||||
response = self.client.get('/test_client/redirect_view/')
|
||||
|
||||
# Check that the response was a 302 (redirect)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_unknown_page(self):
|
||||
"GET an invalid URL"
|
||||
response = self.client.get('/test_client/unknown_view/')
|
||||
|
||||
# Check that the response was a 404
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_view_with_login(self):
|
||||
"Request a page that is protected with @login_required"
|
||||
|
||||
# Get the page without logging in. Should result in 302.
|
||||
response = self.client.get('/test_client/login_protected_view/')
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
# Request a page that requires a login
|
||||
response = self.client.login('/test_client/login_protected_view/', 'testclient', 'password')
|
||||
self.assertTrue(response)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.context['user'].username, 'testclient')
|
||||
self.assertEqual(response.template.name, 'Login Template')
|
||||
|
||||
def test_view_with_bad_login(self):
|
||||
"Request a page that is protected with @login, but use bad credentials"
|
||||
|
||||
response = self.client.login('/test_client/login_protected_view/', 'otheruser', 'nopassword')
|
||||
self.assertFalse(response)
|
|
@ -0,0 +1,9 @@
|
|||
from django.conf.urls.defaults import *
|
||||
import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^get_view/$', views.get_view),
|
||||
(r'^post_view/$', views.post_view),
|
||||
(r'^redirect_view/$', views.redirect_view),
|
||||
(r'^login_protected_view/$', views.login_protected_view),
|
||||
)
|
|
@ -0,0 +1,35 @@
|
|||
from django.template import Context, Template
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
def get_view(request):
|
||||
"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')
|
||||
c = Context({'var': 42})
|
||||
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def post_view(request):
|
||||
"""A view that expects a POST, and returns a different template depending
|
||||
on whether any POST data is available
|
||||
"""
|
||||
if request.POST:
|
||||
t = Template('Data received: {{ data }} is the value.', name='POST Template')
|
||||
c = Context({'data': request.POST['value']})
|
||||
else:
|
||||
t = Template('Viewing POST page.', name='Empty POST Template')
|
||||
c = Context()
|
||||
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
def redirect_view(request):
|
||||
"A view that redirects all requests to the GET view"
|
||||
return HttpResponseRedirect('/test_client/get_view/')
|
||||
|
||||
@login_required
|
||||
def login_protected_view(request):
|
||||
"A simple view that is login protected."
|
||||
t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template')
|
||||
c = Context({'user': request.user})
|
||||
|
||||
return HttpResponse(t.render(c))
|
|
@ -6,6 +6,7 @@ import unittest
|
|||
MODEL_TESTS_DIR_NAME = 'modeltests'
|
||||
REGRESSION_TESTS_DIR_NAME = 'regressiontests'
|
||||
TEST_DATABASE_NAME = 'django_test_db'
|
||||
TEST_TEMPLATE_DIR = 'templates'
|
||||
|
||||
MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME)
|
||||
REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME)
|
||||
|
@ -71,17 +72,23 @@ class InvalidModelTestCase(unittest.TestCase):
|
|||
def django_tests(verbosity, tests_to_run):
|
||||
from django.conf import settings
|
||||
from django.db.models.loading import get_apps, load_app
|
||||
|
||||
old_installed_apps = settings.INSTALLED_APPS
|
||||
old_test_database_name = settings.TEST_DATABASE_NAME
|
||||
old_root_urlconf = settings.ROOT_URLCONF
|
||||
old_template_dirs = settings.TEMPLATE_DIRS
|
||||
|
||||
# Redirect some settings for the duration of these tests
|
||||
settings.TEST_DATABASE_NAME = TEST_DATABASE_NAME
|
||||
settings.INSTALLED_APPS = ALWAYS_INSTALLED_APPS
|
||||
|
||||
settings.ROOT_URLCONF = 'urls'
|
||||
settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), TEST_TEMPLATE_DIR),)
|
||||
|
||||
# load all the ALWAYS_INSTALLED_APPS
|
||||
get_apps()
|
||||
|
||||
test_models = []
|
||||
# Load all the test model apps
|
||||
test_models = []
|
||||
for model_dir, model_name in get_test_models():
|
||||
model_label = '.'.join([model_dir, model_name])
|
||||
try:
|
||||
|
@ -112,6 +119,9 @@ def django_tests(verbosity, tests_to_run):
|
|||
# Restore the old settings
|
||||
settings.INSTALLED_APPS = old_installed_apps
|
||||
settings.TESTS_DATABASE_NAME = old_test_database_name
|
||||
settings.ROOT_URLCONF = old_root_urlconf
|
||||
settings.TEMPLATE_DIRS = old_template_dirs
|
||||
|
||||
if __name__ == "__main__":
|
||||
from optparse import OptionParser
|
||||
usage = "%prog [options] [model model model ...]"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Django Internal Tests: 404 Error
|
|
@ -0,0 +1 @@
|
|||
Django Internal Tests: 500 Error
|
|
@ -0,0 +1,19 @@
|
|||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<h1>Django Internal Tests: Login</h1>
|
||||
{% if form.has_errors %}
|
||||
<p>Your username and password didn't match. Please try again.</p>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action=".">
|
||||
<table>
|
||||
<tr><td><label for="id_username">Username:</label></td><td>{{ form.username }}</td></tr>
|
||||
<tr><td><label for="id_password">Password:</label></td><td>{{ form.password }}</td></tr>
|
||||
</table>
|
||||
|
||||
<input type="submit" value="login" />
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# test_client modeltest urls
|
||||
(r'^test_client/', include('modeltests.test_client.urls')),
|
||||
|
||||
# Always provide the auth system login and logout views
|
||||
(r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
|
||||
(r'^accounts/logout/$', 'django.contrib.auth.views.login'),
|
||||
)
|
Loading…
Reference in New Issue