The Test Client
  Dr Russell Keith-Magee
     DjangoCon 2009
What is it?

• A way to build unit tests of the full stack
• Acts “kinda-sorta” like a browser
• Stateful
• Default instan...
The test client isn’t

• A live browser test framework
 • Selenium
 • Twill
 • Windmill
Why is it different?

• TestClient can’t do some things
 • No JavaScript
 • DOM validation or control
• Can do some things...
GET a page
c = TestClient()

c.get(‘/foo/’)

c.get(‘/foo/’, data={‘bar’:3})

c.get(‘/foo/?bar=3’)
Returns a response

• response.status_code
• response.content
• response.cookies
• response[‘Content-Disposition’]
... and a little more
• response.template
 • The template(s) used used in rendering
• response.context
 • The context obje...
... and it maintains state


• self.cookies
• self.session
Login/Logout

c.login(username='foo',
        password='password')

c.logout()
POST a page
c = TestClient()

c.post(‘/foo/’)

c.post(‘/foo/?bar=3’)

c.post(‘/foo/’, data={‘bar’: 3})

c.get(‘/foo/?whiz=...
Rest of HTTP
c.put(‘/foo/’)

c.options(‘/foo/’)

c.head(‘/foo/’)

c.delete(‘/foo/’)
A common gotcha
r = self.client.get(‘/foo’)

self.assertEquals(r.status_code, 200)

FAIL Assertion Error: 301 != 200
The fix
r = self.client.get(‘/foo’,
                    follow=True)
self.assertEquals(r.status_code, 200)

response.redire...
Extra Headers
c = TestClient(HTTP_HOST=‘foo.com’)

c.get(‘/foo/’, HTTP_HOST=‘foo.com’)

response['X-DJANGO-TEST']
Files
c = TestClient()

f = open(‘mydata.txt’)
c.post(‘/foo/’,
    content_type=MULTIPART_CONTENT
    data = {‘file’: f})
...
Assertions
• assertContains()
• assertNotContains()
• assertFormError()
• assertTemplateUsed()
• assertTemplateNotUsed()
•...
Advice
• Don’t rely on assertContains
 • Assertions on template content are weak
• Test at the source
 • Is the context ri...
When to use TestClient

• When you need to test the full stack
 • interaction of view and middleware
• Great for testing i...
Interesting hack

• Use Client as a factory for Request objects
 • Ticket #9002, Snippet #963
• Then:
 • Construct a reque...
Fin
Upcoming SlideShare
Loading in...5
×

DjangoCon09: The Test Client

3,230

Published on

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.

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,230
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
64
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

DjangoCon09: The Test Client

  1. 1. The Test Client Dr Russell Keith-Magee DjangoCon 2009
  2. 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. 3. The test client isn’t • A live browser test framework • Selenium • Twill • Windmill
  4. 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. 5. GET a page c = TestClient() c.get(‘/foo/’) c.get(‘/foo/’, data={‘bar’:3}) c.get(‘/foo/?bar=3’)
  6. 6. Returns a response • response.status_code • response.content • response.cookies • response[‘Content-Disposition’]
  7. 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. 8. ... and it maintains state • self.cookies • self.session
  9. 9. Login/Logout c.login(username='foo', password='password') c.logout()
  10. 10. POST a page c = TestClient() c.post(‘/foo/’) c.post(‘/foo/?bar=3’) c.post(‘/foo/’, data={‘bar’: 3}) c.get(‘/foo/?whiz=4’, data={‘bar’:3})
  11. 11. Rest of HTTP c.put(‘/foo/’) c.options(‘/foo/’) c.head(‘/foo/’) c.delete(‘/foo/’)
  12. 12. A common gotcha r = self.client.get(‘/foo’) self.assertEquals(r.status_code, 200) FAIL Assertion Error: 301 != 200
  13. 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. 14. Extra Headers c = TestClient(HTTP_HOST=‘foo.com’) c.get(‘/foo/’, HTTP_HOST=‘foo.com’) response['X-DJANGO-TEST']
  15. 15. Files c = TestClient() f = open(‘mydata.txt’) c.post(‘/foo/’, content_type=MULTIPART_CONTENT data = {‘file’: f}) f.close()
  16. 16. Assertions • assertContains() • assertNotContains() • assertFormError() • assertTemplateUsed() • assertTemplateNotUsed() • assertRedirects()
  17. 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. 18. When to use TestClient • When you need to test the full stack • interaction of view and middleware • Great for testing idempotency
  19. 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
  20. 20. Fin
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×