The Django Test client is one of the more powerful testing tools in the Django test arsenal. However, in order to get the most out of the test client, it's important to understand what it is for - and what it isn't for.
This howto will give an overview of the Django test client - when to use it, what it can be used for, and when to use something else entirely.
2. What is it?
• A way to build unit tests of the full stack
• Acts “kinda-sorta” like a browser
• Stateful
• Default instance on django.test.TestCase
• Can be instantiated outside test framework
3. The test client isn’t
• A live browser test framework
• Selenium
• Twill
• Windmill
4. Why is it different?
• TestClient can’t do some things
• No JavaScript
• DOM validation or control
• Can do some things that browsers can’t
5. GET a page
c = TestClient()
c.get(‘/foo/’)
c.get(‘/foo/’, data={‘bar’:3})
c.get(‘/foo/?bar=3’)
7. ... and a little more
• response.template
• The template(s) used used in rendering
• response.context
• The context objects used in rendering
• response.context[‘foo’]
8. ... and it maintains state
• self.cookies
• self.session
12. A common gotcha
r = self.client.get(‘/foo’)
self.assertEquals(r.status_code, 200)
FAIL Assertion Error: 301 != 200
13. The fix
r = self.client.get(‘/foo’,
follow=True)
self.assertEquals(r.status_code, 200)
response.redirect_chain
➡ links visited before a non-redirect was found.
14. Extra Headers
c = TestClient(HTTP_HOST=‘foo.com’)
c.get(‘/foo/’, HTTP_HOST=‘foo.com’)
response['X-DJANGO-TEST']
15. Files
c = TestClient()
f = open(‘mydata.txt’)
c.post(‘/foo/’,
content_type=MULTIPART_CONTENT
data = {‘file’: f})
f.close()
17. Advice
• Don’t rely on assertContains
• Assertions on template content are weak
• Test at the source
• Is the context right?
• Are the forms correct?
• Django’s templates make this possible!
18. When to use TestClient
• When you need to test the full stack
• interaction of view and middleware
• Great for testing idempotency
19. Interesting hack
• Use Client as a factory for Request objects
• Ticket #9002, Snippet #963
• Then:
• Construct a request object
• Use to test a single view/middleware call