Test Client
Note: To avoid hard-coding the URL, use reverse
, URL.
AJAX and Post
See sample below.
To pass raw data (rather than form fields) to a post request:
post_data = '[{"name": "East Anstey"}, {"name": "East Buckland"}]'
response = self.client.post(
'/my_screen_name/json/',
post_data,
content_type='application/json'
)
To make this into an AJAX request which will be recognised by is_ajax
,
add the HTTP_X_REQUESTED_WITH
parameter:
response = self.client.post(
'/my_screen_name/json/',
post_data,
content_type='application/json',
HTTP_X_REQUESTED_WITH='XMLHttpRequest'
)
Tip
I don’t think content_type
is required for AJAX views.
For details see Testing AJAX Views in Django
File Upload
I guess this will also work with image upload:
with open('test/data/about.jpg', 'rb') as fp:
data = {
'picture': fp,
}
response = self.client.post(
url,
data=data,
)
Sample
Create a tests.py
file inside your application folder:
from django.test import TestCase
class SimpleTest(TestCase):
def test_preview(self):
response = self.client.post('/wiki/preview/', {
'data': 'Heading\n=======',
})
self.assertTrue('<h1>Heading</h1>' in response.content)
Note:
To avoid hard-coding the URL, use
reverse
, URLThis code is using the Django test client which can be used to test views.
Don’t forget to put the leading slash on the URL.
Form fields are passed in as simple key/values in the dictionary. Debug the code at the point where the post is made to get some sample data e.g. for a formset:
self.client.post('/admin/product/option/1/', { 'form-INITIAL_FORMS': '2', 'form-TOTAL_FORMS': '2', 'form-0-group_name': 'Colour finishes', 'form-0-name': 'Orange', 'form-0-option_id': '6', 'form-0-price': '23', 'form-0-price_before': '3', 'form-1-group_name': 'Colour finishes', 'form-1-name': 'Green', 'form-1-option_id': '5', 'form-1-price': '25', 'form-1-price_before': '0', })
Assertions
assertContains
Asserts that a Response
instance produced the given status_code and
that text appears in the content of the response. If count is provided,
text must occur exactly count times in the response:
TestCase.assertContains(response, text, count=None, status_code=200)
e.g:
response = self.client.get('/')
self.assertContains(response, 'Latest News')
Note:
There is also a
assertNotContains
method.The
response
object must be the first parameter to theassertContains
method…
assertRedirects
response = self.client.get('/region/store/')
self.assertRedirects(response, '/region/choose/')
Tip
If fetch_redirect_response
is set to False
, the final page
won’t be loaded.
If you would to test a re-direct to an external URL (from Django’s assertRedirects little gotcha):
response = self.client.get('/region/store/')
self.assertEqual(
response._headers['location'],
('Location', 'http://orange.net/usa'))
self.assertEqual(response.status_code, 302)
Authentication
To test login and authentication, see Testing.
Request
From RequestFactory:
from django.utils import unittest
from django.test.client import RequestFactory
class SimpleTest(unittest.TestCase):
def setUp(self):
# Every test needs access to the request factory.
self.factory = RequestFactory()
def test_details(self):
# Create an instance of a GET request.
request = self.factory.get('/customer/details')
# Test my_view() as if it were deployed at /customer/details
response = my_view(request)
self.assertEqual(response.status_code, 200)
Response
The response
object in the example above has a context
attribute which
you can use to examine the context
returned from the view function. To
access context elements, use the following syntax:
response.context['category']
Note: If you examine the context
object, you will find it is a list (or a
list of lists). This can become very confusing, so just use the simple syntax
above to access dictionary elements. For more information see
Test client improvements.
URL
To use a test/temporary URL, put a urls.py
file into the tests
folder,
and reference it within the test:
class TestMyView(TestCase):
urls = 'myapp.tests.urls'
For details, see TestCase.urls