mirror of https://github.com/django/django.git
Refs #2333 - Added documentation for the test Client, and removed a stray import.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@3711 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5a1d560fb3
commit
8192a808bd
|
@ -60,7 +60,6 @@ from django.conf import settings
|
|||
from django.template.context import Context, RequestContext, ContextPopException
|
||||
from django.utils.functional import curry
|
||||
from django.utils.text import smart_split
|
||||
from django.dispatch import dispatcher
|
||||
|
||||
__all__ = ('Template', 'Context', 'RequestContext', 'compile_string')
|
||||
|
||||
|
|
169
docs/testing.txt
169
docs/testing.txt
|
@ -159,20 +159,166 @@ Again, remember that you can use both systems side-by-side (even in the same
|
|||
app). In the end, most projects will eventually end up using both; each shines
|
||||
in different circumstances.
|
||||
|
||||
Testing utilities
|
||||
=================
|
||||
Testing Tools
|
||||
=============
|
||||
|
||||
To assist in testing various features of your application, Django provides
|
||||
tools that can be used to establish tests and test conditions.
|
||||
|
||||
* `Test Client`_
|
||||
* Fixtures_
|
||||
|
||||
Test Client
|
||||
-----------
|
||||
|
||||
A dummy browser; instruments the template generation process...
|
||||
The Test Client is a simple dummy browser. It allows you to simulate
|
||||
GET and POST requests on a URL, and observe the response that is received.
|
||||
This allows you to test that the correct view is executed for a given URL,
|
||||
and that the view constructs the correct response.
|
||||
|
||||
As the response is generated, the Test Client gathers details on the
|
||||
Template and Context objects that were used to generate the response. These
|
||||
Templates and Contexts are then provided as part of the response, and can be
|
||||
used as test conditions.
|
||||
|
||||
.. admonition:: Test Client vs Browser Automation?
|
||||
|
||||
The Test Client is not intended as a replacement for Twill_, Selenium_,
|
||||
or other browser automation frameworks - it is intended to allow
|
||||
testing of the contexts and templates produced by a view,
|
||||
rather than the HTML rendered to the end-user.
|
||||
|
||||
A comprehensive test suite should use a combination of both: Test Client
|
||||
tests to establish that the correct view is being called and that
|
||||
the view is collecting the correct context data, and Browser Automation
|
||||
tests to check that user interface behaves as expected.
|
||||
|
||||
.. _Twill: http://twill.idyll.org/
|
||||
.. _Selenium: http://www.openqa.org/selenium/
|
||||
|
||||
The Test Client is stateful; if a cookie is returned as part of a response,
|
||||
that cookie is provided as part of the next request. Expiry policies for these
|
||||
cookies are not followed; if you want a cookie to expire, either delete it
|
||||
manually from ``client.cookies``, or create a new Client instance (which will
|
||||
effectively delete all cookies).
|
||||
|
||||
Making requests
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Creating an instance of ``Client`` (``django.test.client.Client``) requires
|
||||
no arguments at time of construction. Once constructed, the following methods
|
||||
can be invoked on the ``Client`` instance.
|
||||
|
||||
``get(path, data={}):``
|
||||
|
||||
Make a GET request on the provided ``path``. The key-value pairs in the
|
||||
data dictionary will be used to create a GET data payload. For example::
|
||||
|
||||
c = Client()
|
||||
c.get('/customers/details/', {'name':'fred', 'age':7})
|
||||
|
||||
will result in the evaluation of a GET request equivalent to::
|
||||
|
||||
http://yoursite.com/customers/details/?name='fred'&age=7
|
||||
|
||||
``post(path, data={}):``
|
||||
|
||||
Make a POST request on the provided ``path``. The key-value pairs in the
|
||||
data dictionary will be used to create the POST data payload. This payload
|
||||
will be transmitted with the mimetype ```multipart/form-data``.
|
||||
|
||||
However submitting files is a special case. To POST a file, you need only
|
||||
provide the file field name as a key, and a file handle to the file you wish to
|
||||
upload as a value. The Test Client will populate the two POST fields (i.e.,
|
||||
``field`` and ``field_file``) required by FileField. For example::
|
||||
|
||||
c = Client()
|
||||
f = open('wishlist.doc')
|
||||
c.post('/customers/wishes/', {'name':'fred', 'attachment':f})
|
||||
f.close()
|
||||
|
||||
will result in the evaluation of a POST request on ``/customers/wishes/``,
|
||||
with a POST dictionary that contains `name`, `attachment` (containing the
|
||||
file name), and `attachment_file` (containing the file data). Note that you
|
||||
need to manually close the file after it has been provided to the POST.
|
||||
|
||||
``login(path, username, password):``
|
||||
|
||||
In a production site, it is likely that some views will be protected with
|
||||
the @login_required URL provided by ``django.contrib.auth``. Interacting
|
||||
with a URL that has been login protected is a slightly complex operation,
|
||||
so the Test Client provides a simple URL to automate the login process. A
|
||||
call to ``login()`` stimulates the series of GET and POST calls required
|
||||
to log a user into a @login_required protected URL.
|
||||
|
||||
If login is possible, the final return value of ``login()`` is the response
|
||||
that is generated by issuing a GET request on the protected URL. If login
|
||||
is not possible, ``login()`` returns False.
|
||||
|
||||
Note that since the test suite will be executed using the test database,
|
||||
which contains no users by default. As a result, logins for your production
|
||||
site will not work. You will need to create users as part of the test suite
|
||||
to be able to test logins to your application.
|
||||
|
||||
Testing Responses
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``get()``, ``post()`` and ``login()`` methods all return a Response
|
||||
object. This Response object has the following properties that can be used
|
||||
for testing purposes:
|
||||
|
||||
``status_code``
|
||||
|
||||
The HTTP status of the response. See RFC2616_ for a full list of HTTP status
|
||||
codes.
|
||||
|
||||
.. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
|
||||
``content``
|
||||
|
||||
The body of the response. The is the final page content as rendered by
|
||||
the view, or any error message (such as the URL for a 302 redirect).
|
||||
|
||||
``template``
|
||||
|
||||
The Template instance that was used to render the final content.
|
||||
Testing ``template.name`` can be particularly useful; if the
|
||||
template was loaded from a file, ``name`` will be the file name that
|
||||
was loaded.
|
||||
|
||||
If multiple templates were rendered, (e.g., if one template includes
|
||||
another template),``template`` will be a list of Template objects, in
|
||||
the order in which they were rendered.
|
||||
|
||||
``context``
|
||||
|
||||
The Context that was used to render the template that produced the
|
||||
response content.
|
||||
|
||||
As with ``template``, if multiple templates were rendered ``context``
|
||||
will be a list of Context objects, stored in the order in which they
|
||||
were rendered.
|
||||
|
||||
The following is a simple unit test using the Test Client::
|
||||
|
||||
import unittest
|
||||
from django.test.client import Client
|
||||
|
||||
class SimpleTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Every test needs a client
|
||||
self.client = Client()
|
||||
def test_details(self):
|
||||
response = self.client.get('/customer/details/')
|
||||
|
||||
self.failUnlessEqual(response.status_code, 200)
|
||||
self.failUnlessEqual(len(response.context['customers']), 5)
|
||||
|
||||
Fixtures
|
||||
--------
|
||||
|
||||
Feature still to come...
|
||||
|
||||
|
||||
Running tests
|
||||
=============
|
||||
|
||||
|
@ -245,11 +391,13 @@ When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
|
|||
setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django
|
||||
testing behaviour. This behaviour involves:
|
||||
|
||||
#. Performing global pre-test setup
|
||||
#. Creating the test database
|
||||
#. Running ``syncdb`` to install models and initial data into the test database
|
||||
#. Looking for Unit Tests and Doctests in ``models.py`` and ``tests.py`` file for each installed application
|
||||
#. Running the Unit Tests and Doctests that are found
|
||||
#. Destroying the test database.
|
||||
#. Performing global post-test teardown
|
||||
|
||||
If you define your own test runner method and point ``TEST_RUNNER``
|
||||
at that method, Django will execute your test runner whenever you run
|
||||
|
@ -263,7 +411,6 @@ can call it anything you want. The only requirement is that it accept two
|
|||
arguments:
|
||||
|
||||
``run_tests(module_list, verbosity=1)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The module list is the list of Python modules that contain the models to be
|
||||
tested. This is the same format returned by ``django.db.models.get_apps()``
|
||||
|
@ -278,8 +425,17 @@ Testing utilities
|
|||
To assist in the creation of your own test runner, Django provides
|
||||
a number of utility methods in the ``django.test.utils`` module.
|
||||
|
||||
``setup_test_environment()``
|
||||
|
||||
Performs any global pre-test setup, such as the installing the
|
||||
instrumentation of the template rendering system.
|
||||
|
||||
``teardown_test_environment()``
|
||||
|
||||
Performs any global post-test teardown, such as removing the instrumentation
|
||||
of the template rendering system.
|
||||
|
||||
``create_test_db(verbosity=1, autoclobber=False)``:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Creates a new test database, and run ``syncdb`` against it.
|
||||
|
||||
|
@ -295,7 +451,6 @@ will be destroyed without consulting the user.
|
|||
``settings.DATABASE_NAME`` to match the name of the test database.
|
||||
|
||||
``destroy_test_db(old_database_name, verbosity=1)``:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Destroys the database with the name ``settings.DATABASE_NAME`` matching,
|
||||
and restores the value of ``settings.DATABASE_NAME`` to the provided name.
|
||||
|
|
Loading…
Reference in New Issue