| 168 | | A dummy browser; instruments the template generation process... |
|---|
| | 174 | The Test Client is a simple dummy browser. It allows you to simulate |
|---|
| | 175 | GET and POST requests on a URL, and observe the response that is received. |
|---|
| | 176 | This allows you to test that the correct view is executed for a given URL, |
|---|
| | 177 | and that the view constructs the correct response. |
|---|
| | 178 | |
|---|
| | 179 | As the response is generated, the Test Client gathers details on the |
|---|
| | 180 | Template and Context objects that were used to generate the response. These |
|---|
| | 181 | Templates and Contexts are then provided as part of the response, and can be |
|---|
| | 182 | used as test conditions. |
|---|
| | 183 | |
|---|
| | 184 | .. admonition:: Test Client vs Browser Automation? |
|---|
| | 185 | |
|---|
| | 186 | The Test Client is not intended as a replacement for Twill_, Selenium_, |
|---|
| | 187 | or other browser automation frameworks - it is intended to allow |
|---|
| | 188 | testing of the contexts and templates produced by a view, |
|---|
| | 189 | rather than the HTML rendered to the end-user. |
|---|
| | 190 | |
|---|
| | 191 | A comprehensive test suite should use a combination of both: Test Client |
|---|
| | 192 | tests to establish that the correct view is being called and that |
|---|
| | 193 | the view is collecting the correct context data, and Browser Automation |
|---|
| | 194 | tests to check that user interface behaves as expected. |
|---|
| | 195 | |
|---|
| | 196 | .. _Twill: http://twill.idyll.org/ |
|---|
| | 197 | .. _Selenium: http://www.openqa.org/selenium/ |
|---|
| | 198 | |
|---|
| | 199 | The Test Client is stateful; if a cookie is returned as part of a response, |
|---|
| | 200 | that cookie is provided as part of the next request. Expiry policies for these |
|---|
| | 201 | cookies are not followed; if you want a cookie to expire, either delete it |
|---|
| | 202 | manually from ``client.cookies``, or create a new Client instance (which will |
|---|
| | 203 | effectively delete all cookies). |
|---|
| | 204 | |
|---|
| | 205 | Making requests |
|---|
| | 206 | ~~~~~~~~~~~~~~~ |
|---|
| | 207 | |
|---|
| | 208 | Creating an instance of ``Client`` (``django.test.client.Client``) requires |
|---|
| | 209 | no arguments at time of construction. Once constructed, the following methods |
|---|
| | 210 | can be invoked on the ``Client`` instance. |
|---|
| | 211 | |
|---|
| | 212 | ``get(path, data={}):`` |
|---|
| | 213 | |
|---|
| | 214 | Make a GET request on the provided ``path``. The key-value pairs in the |
|---|
| | 215 | data dictionary will be used to create a GET data payload. For example:: |
|---|
| | 216 | |
|---|
| | 217 | c = Client() |
|---|
| | 218 | c.get('/customers/details/', {'name':'fred', 'age':7}) |
|---|
| | 219 | |
|---|
| | 220 | will result in the evaluation of a GET request equivalent to:: |
|---|
| | 221 | |
|---|
| | 222 | http://yoursite.com/customers/details/?name='fred'&age=7 |
|---|
| | 223 | |
|---|
| | 224 | ``post(path, data={}):`` |
|---|
| | 225 | |
|---|
| | 226 | Make a POST request on the provided ``path``. The key-value pairs in the |
|---|
| | 227 | data dictionary will be used to create the POST data payload. This payload |
|---|
| | 228 | will be transmitted with the mimetype ```multipart/form-data``. |
|---|
| | 229 | |
|---|
| | 230 | However submitting files is a special case. To POST a file, you need only |
|---|
| | 231 | provide the file field name as a key, and a file handle to the file you wish to |
|---|
| | 232 | upload as a value. The Test Client will populate the two POST fields (i.e., |
|---|
| | 233 | ``field`` and ``field_file``) required by FileField. For example:: |
|---|
| | 234 | |
|---|
| | 235 | c = Client() |
|---|
| | 236 | f = open('wishlist.doc') |
|---|
| | 237 | c.post('/customers/wishes/', {'name':'fred', 'attachment':f}) |
|---|
| | 238 | f.close() |
|---|
| | 239 | |
|---|
| | 240 | will result in the evaluation of a POST request on ``/customers/wishes/``, |
|---|
| | 241 | with a POST dictionary that contains `name`, `attachment` (containing the |
|---|
| | 242 | file name), and `attachment_file` (containing the file data). Note that you |
|---|
| | 243 | need to manually close the file after it has been provided to the POST. |
|---|
| | 244 | |
|---|
| | 245 | ``login(path, username, password):`` |
|---|
| | 246 | |
|---|
| | 247 | In a production site, it is likely that some views will be protected with |
|---|
| | 248 | the @login_required URL provided by ``django.contrib.auth``. Interacting |
|---|
| | 249 | with a URL that has been login protected is a slightly complex operation, |
|---|
| | 250 | so the Test Client provides a simple URL to automate the login process. A |
|---|
| | 251 | call to ``login()`` stimulates the series of GET and POST calls required |
|---|
| | 252 | to log a user into a @login_required protected URL. |
|---|
| | 253 | |
|---|
| | 254 | If login is possible, the final return value of ``login()`` is the response |
|---|
| | 255 | that is generated by issuing a GET request on the protected URL. If login |
|---|
| | 256 | is not possible, ``login()`` returns False. |
|---|
| | 257 | |
|---|
| | 258 | Note that since the test suite will be executed using the test database, |
|---|
| | 259 | which contains no users by default. As a result, logins for your production |
|---|
| | 260 | site will not work. You will need to create users as part of the test suite |
|---|
| | 261 | to be able to test logins to your application. |
|---|
| | 262 | |
|---|
| | 263 | Testing Responses |
|---|
| | 264 | ~~~~~~~~~~~~~~~~~ |
|---|
| | 265 | |
|---|
| | 266 | The ``get()``, ``post()`` and ``login()`` methods all return a Response |
|---|
| | 267 | object. This Response object has the following properties that can be used |
|---|
| | 268 | for testing purposes: |
|---|
| | 269 | |
|---|
| | 270 | ``status_code`` |
|---|
| | 271 | |
|---|
| | 272 | The HTTP status of the response. See RFC2616_ for a full list of HTTP status |
|---|
| | 273 | codes. |
|---|
| | 274 | |
|---|
| | 275 | .. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html |
|---|
| | 276 | |
|---|
| | 277 | ``content`` |
|---|
| | 278 | |
|---|
| | 279 | The body of the response. The is the final page content as rendered by |
|---|
| | 280 | the view, or any error message (such as the URL for a 302 redirect). |
|---|
| | 281 | |
|---|
| | 282 | ``template`` |
|---|
| | 283 | |
|---|
| | 284 | The Template instance that was used to render the final content. |
|---|
| | 285 | Testing ``template.name`` can be particularly useful; if the |
|---|
| | 286 | template was loaded from a file, ``name`` will be the file name that |
|---|
| | 287 | was loaded. |
|---|
| | 288 | |
|---|
| | 289 | If multiple templates were rendered, (e.g., if one template includes |
|---|
| | 290 | another template),``template`` will be a list of Template objects, in |
|---|
| | 291 | the order in which they were rendered. |
|---|
| | 292 | |
|---|
| | 293 | ``context`` |
|---|
| | 294 | |
|---|
| | 295 | The Context that was used to render the template that produced the |
|---|
| | 296 | response content. |
|---|
| | 297 | |
|---|
| | 298 | As with ``template``, if multiple templates were rendered ``context`` |
|---|
| | 299 | will be a list of Context objects, stored in the order in which they |
|---|
| | 300 | were rendered. |
|---|
| | 301 | |
|---|
| | 302 | The following is a simple unit test using the Test Client:: |
|---|
| | 303 | |
|---|
| | 304 | import unittest |
|---|
| | 305 | from django.test.client import Client |
|---|
| | 306 | |
|---|
| | 307 | class SimpleTest(unittest.TestCase): |
|---|
| | 308 | def setUp(self): |
|---|
| | 309 | # Every test needs a client |
|---|
| | 310 | self.client = Client() |
|---|
| | 311 | def test_details(self): |
|---|
| | 312 | response = self.client.get('/customer/details/') |
|---|
| | 313 | |
|---|
| | 314 | self.failUnlessEqual(response.status_code, 200) |
|---|
| | 315 | self.failUnlessEqual(len(response.context['customers']), 5) |
|---|
| 282 | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 283 | | |
|---|
| 284 | | Creates a new test database, and run ``syncdb`` against it. |
|---|
| 285 | | |
|---|
| 286 | | ``verbosity`` has the same behaviour as in the test runner. |
|---|
| 287 | | |
|---|
| 288 | | ``Autoclobber`` describes the behavior that will occur if a database with |
|---|
| 289 | | the same name as the test database is discovered. If ``autoclobber`` is False, |
|---|
| 290 | | the user will be asked to approve destroying the existing database. ``sys.exit`` |
|---|
| 291 | | is called if the user does not approve. If autoclobber is ``True``, the database |
|---|
| 292 | | will be destroyed without consulting the user. |
|---|
| 293 | | |
|---|
| 294 | | ``create_test_db()`` has the side effect of modifying |
|---|
| 295 | | ``settings.DATABASE_NAME`` to match the name of the test database. |
|---|
| | 439 | |
|---|
| | 440 | Creates a new test database, and run ``syncdb`` against it. |
|---|
| | 441 | |
|---|
| | 442 | ``verbosity`` has the same behaviour as in the test runner. |
|---|
| | 443 | |
|---|
| | 444 | ``Autoclobber`` describes the behavior that will occur if a database with |
|---|
| | 445 | the same name as the test database is discovered. If ``autoclobber`` is False, |
|---|
| | 446 | the user will be asked to approve destroying the existing database. ``sys.exit`` |
|---|
| | 447 | is called if the user does not approve. If autoclobber is ``True``, the database |
|---|
| | 448 | will be destroyed without consulting the user. |
|---|
| | 449 | |
|---|
| | 450 | ``create_test_db()`` has the side effect of modifying |
|---|
| | 451 | ``settings.DATABASE_NAME`` to match the name of the test database. |
|---|