A few fixes for the testing documentation:
* Removed an extra semicolon that was preventing the rendering of a Sphinx class directive for the `Client()` class. * Indented `Client` class's methods. * Added linebreaks after attribute directives of `Response` class so Sphinx rendenders them correctly. * Removed trailing whitespace. git-svn-id: http://code.djangoproject.com/svn/django/trunk@8567 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5485e0d97f
commit
b2c2c3a2ed
|
@ -131,21 +131,20 @@ Here is an example model doctest::
|
|||
def speak(self):
|
||||
return 'The %s says "%s"' % (self.name, self.sound)
|
||||
|
||||
When you :ref:`run your tests <running-tests>`, the test runner will find this docstring, notice
|
||||
that portions of it look like an interactive Python session, and execute those
|
||||
lines while checking that the results match.
|
||||
When you :ref:`run your tests <running-tests>`, the test runner will find this
|
||||
docstring, notice that portions of it look like an interactive Python session,
|
||||
and execute those lines while checking that the results match.
|
||||
|
||||
In the case of model tests, note that the test runner takes care of
|
||||
creating its own test database. That is, any test that accesses a
|
||||
database -- by creating and saving model instances, for example --
|
||||
will not affect your production database. Each doctest begins with a
|
||||
"blank slate" -- a fresh database containing an empty table for each
|
||||
model. (See the section on fixtures, below, for more on this.) Note
|
||||
that to use this feature, the database user Django is connecting as
|
||||
must have ``CREATE DATABASE`` rights.
|
||||
In the case of model tests, note that the test runner takes care of creating
|
||||
its own test database. That is, any test that accesses a database -- by
|
||||
creating and saving model instances, for example -- will not affect your
|
||||
production database. Each doctest begins with a "blank slate" -- a fresh
|
||||
database containing an empty table for each model. (See the section on
|
||||
fixtures, below, for more on this.) Note that to use this feature, the database
|
||||
user Django is connecting as must have ``CREATE DATABASE`` rights.
|
||||
|
||||
For more details about how doctest works, see the `standard library
|
||||
documentation for doctest`_
|
||||
documentation for doctest`_.
|
||||
|
||||
.. _doctest: http://docs.python.org/lib/module-doctest.html
|
||||
.. _standard library documentation for doctest: doctest_
|
||||
|
@ -182,17 +181,17 @@ in the doctest section above::
|
|||
self.assertEquals(self.lion.speak(), 'The lion says "roar"')
|
||||
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
|
||||
|
||||
When you :ref:`run your tests <running-tests>`, the default behavior of the test utility is
|
||||
to find all the test cases (that is, subclasses of ``unittest.TestCase``)
|
||||
in ``models.py`` and ``tests.py``, automatically build a test suite out of
|
||||
those test cases, and run that suite.
|
||||
When you :ref:`run your tests <running-tests>`, the default behavior of the
|
||||
test utility is to find all the test cases (that is, subclasses of
|
||||
``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a
|
||||
test suite out of those test cases, and run that suite.
|
||||
|
||||
In the Django development version, there is a second way to define the test
|
||||
suite for a module: if you define a function called ``suite()`` in either
|
||||
``models.py`` or ``tests.py``, the Django test runner will use that function
|
||||
to construct the test suite for that module. This follows the
|
||||
`suggested organization`_ for unit tests. See the Python documentation for
|
||||
more details on how to construct a complex test suite.
|
||||
to construct the test suite for that module. This follows the `suggested
|
||||
organization`_ for unit tests. See the Python documentation for more details on
|
||||
how to construct a complex test suite.
|
||||
|
||||
For more details about ``unittest``, see the `standard library unittest
|
||||
documentation`_.
|
||||
|
@ -242,7 +241,8 @@ in different circumstances.
|
|||
Running tests
|
||||
=============
|
||||
|
||||
Once you've written tests, run them using your project's ``manage.py`` utility::
|
||||
Once you've written tests, run them using your project's ``manage.py``
|
||||
utility::
|
||||
|
||||
$ ./manage.py test
|
||||
|
||||
|
@ -273,18 +273,18 @@ a test case, add the name of the test method to the label::
|
|||
The test database
|
||||
-----------------
|
||||
|
||||
Tests that require a database (namely, model tests) will not use
|
||||
your "real" (production) database. A separate, blank database is created
|
||||
for the tests.
|
||||
Tests that require a database (namely, model tests) will not use your "real"
|
||||
(production) database. A separate, blank database is created for the tests.
|
||||
|
||||
Regardless of whether the tests pass or fail, the test database is destroyed
|
||||
when all the tests have been executed.
|
||||
|
||||
By default this test database gets its name by prepending ``test_`` to the value
|
||||
of the :setting:`DATABASE_NAME` setting. When using the SQLite database engine
|
||||
the tests will by default use an in-memory database (i.e., the database will be
|
||||
created in memory, bypassing the filesystem entirely!). If you want to use a
|
||||
different database name, specify the :setting:`TEST_DATABASE_NAME` setting.
|
||||
By default this test database gets its name by prepending ``test_`` to the
|
||||
value of the :setting:`DATABASE_NAME` setting. When using the SQLite database
|
||||
engine the tests will by default use an in-memory database (i.e., the database
|
||||
will be created in memory, bypassing the filesystem entirely!). If you want to
|
||||
use a different database name, specify the :setting:`TEST_DATABASE_NAME`
|
||||
setting.
|
||||
|
||||
Aside from using a separate database, the test runner will otherwise use all of
|
||||
the same database settings you have in your settings file:
|
||||
|
@ -466,11 +466,12 @@ Making requests
|
|||
~~~~~~~~~~~~~~~
|
||||
|
||||
Use the ``django.test.client.Client`` class to make requests. It requires no
|
||||
arguments at time of construction::
|
||||
arguments at time of construction:
|
||||
|
||||
.. class:: Client()
|
||||
|
||||
Once you have a ``Client`` instance, you can call any of the following methods:
|
||||
Once you have a ``Client`` instance, you can call any of the following
|
||||
methods:
|
||||
|
||||
.. method:: Client.get(path, data={})
|
||||
|
||||
|
@ -489,8 +490,8 @@ Once you have a ``Client`` instance, you can call any of the following methods:
|
|||
|
||||
.. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT)
|
||||
|
||||
Makes a POST request on the provided ``path`` and returns a ``Response``
|
||||
object, which is documented below.
|
||||
Makes a POST request on the provided ``path`` and returns a
|
||||
``Response`` object, which is documented below.
|
||||
|
||||
The key-value pairs in the ``data`` dictionary are used to submit POST
|
||||
data. For example::
|
||||
|
@ -506,14 +507,15 @@ Once you have a ``Client`` instance, you can call any of the following methods:
|
|||
|
||||
name=fred&passwd=secret
|
||||
|
||||
If you provide ``content_type`` (e.g., ``text/xml`` for an XML payload),
|
||||
the contents of ``data`` will be sent as-is in the POST request, using
|
||||
``content_type`` in the HTTP ``Content-Type`` header.
|
||||
If you provide ``content_type`` (e.g., ``text/xml`` for an XML
|
||||
payload), the contents of ``data`` will be sent as-is in the POST
|
||||
request, using ``content_type`` in the HTTP ``Content-Type`` header.
|
||||
|
||||
If you don't provide a value for ``content_type``, the values in
|
||||
``data`` will be transmitted with a content type of ``multipart/form-data``.
|
||||
In this case, the key-value pairs in ``data`` will be encoded as a
|
||||
multipart message and used to create the POST data payload.
|
||||
``data`` will be transmitted with a content type of
|
||||
``multipart/form-data``. In this case, the key-value pairs in ``data``
|
||||
will be encoded as a multipart message and used to create the POST data
|
||||
payload.
|
||||
|
||||
To submit multiple values for a given key -- for example, to specify
|
||||
the selections for a ``<select multiple>`` -- provide the values as a
|
||||
|
@ -522,9 +524,9 @@ Once you have a ``Client`` instance, you can call any of the following methods:
|
|||
|
||||
{'choices': ('a', 'b', 'd')}
|
||||
|
||||
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. For example::
|
||||
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. For example::
|
||||
|
||||
>>> c = Client()
|
||||
>>> f = open('wishlist.doc')
|
||||
|
@ -534,58 +536,60 @@ Once you have a ``Client`` instance, you can call any of the following methods:
|
|||
(The name ``attachment`` here is not relevant; use whatever name your
|
||||
file-processing code expects.)
|
||||
|
||||
Note that you should manually close the file after it has been provided to
|
||||
``post()``.
|
||||
Note that you should manually close the file after it has been provided
|
||||
to ``post()``.
|
||||
|
||||
.. method:: Client.login(**credentials)
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
If your site uses Django's :ref:`authentication system<topics-auth>` and you deal with
|
||||
logging in users, you can use the test client's ``login()`` method to
|
||||
simulate the effect of a user logging into the site.
|
||||
If your site uses Django's :ref:`authentication system<topics-auth>`
|
||||
and you deal with logging in users, you can use the test client's
|
||||
``login()`` method to simulate the effect of a user logging into the
|
||||
site.
|
||||
|
||||
After you call this method, the test client will have all the cookies and
|
||||
session data required to pass any login-based tests that may form part of
|
||||
a view.
|
||||
After you call this method, the test client will have all the cookies
|
||||
and session data required to pass any login-based tests that may form
|
||||
part of a view.
|
||||
|
||||
The format of the ``credentials`` argument depends on which
|
||||
:ref:`authentication backend <authentication-backends>` you're using (which is configured by your
|
||||
:setting:`AUTHENTICATION_BACKENDS` setting). If you're using the standard
|
||||
authentication backend provided by Django (``ModelBackend``),
|
||||
``credentials`` should be the user's username and password, provided as
|
||||
keyword arguments::
|
||||
:ref:`authentication backend <authentication-backends>` you're using
|
||||
(which is configured by your :setting:`AUTHENTICATION_BACKENDS`
|
||||
setting). If you're using the standard authentication backend provided
|
||||
by Django (``ModelBackend``), ``credentials`` should be the user's
|
||||
username and password, provided as keyword arguments::
|
||||
|
||||
>>> c = Client()
|
||||
>>> c.login(username='fred', password='secret')
|
||||
|
||||
# Now you can access a view that's only available to logged-in users.
|
||||
|
||||
If you're using a different authentication backend, this method may require
|
||||
different credentials. It requires whichever credentials are required by
|
||||
your backend's ``authenticate()`` method.
|
||||
If you're using a different authentication backend, this method may
|
||||
require different credentials. It requires whichever credentials are
|
||||
required by your backend's ``authenticate()`` method.
|
||||
|
||||
``login()`` returns ``True`` if it the credentials were accepted and login
|
||||
was successful.
|
||||
``login()`` returns ``True`` if it the credentials were accepted and
|
||||
login was successful.
|
||||
|
||||
Finally, you'll need to remember to create user accounts before you can use
|
||||
this method. As we explained above, the test runner is executed using a
|
||||
test database, which contains no users by default. As a result, user
|
||||
accounts that are valid on your production site will not work under test
|
||||
conditions. You'll need to create users as part of the test suite -- either
|
||||
manually (using the Django model API) or with a test fixture.
|
||||
Finally, you'll need to remember to create user accounts before you can
|
||||
use this method. As we explained above, the test runner is executed
|
||||
using a test database, which contains no users by default. As a result,
|
||||
user accounts that are valid on your production site will not work
|
||||
under test conditions. You'll need to create users as part of the test
|
||||
suite -- either manually (using the Django model API) or with a test
|
||||
fixture.
|
||||
|
||||
.. method:: Client.logout()
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
If your site uses Django's :ref:`authentication system<topics-auth>`, the ``logout()``
|
||||
method can be used to simulate the effect of a user logging out of
|
||||
your site.
|
||||
If your site uses Django's :ref:`authentication system<topics-auth>`,
|
||||
the ``logout()`` method can be used to simulate the effect of a user
|
||||
logging out of your site.
|
||||
|
||||
After you call this method, the test client will have all the cookies and
|
||||
session data cleared to defaults. Subsequent requests will appear to
|
||||
come from an AnonymousUser.
|
||||
After you call this method, the test client will have all the cookies
|
||||
and session data cleared to defaults. Subsequent requests will appear
|
||||
to come from an AnonymousUser.
|
||||
|
||||
Testing responses
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
@ -599,36 +603,42 @@ Specifically, a ``Response`` object has the following attributes:
|
|||
|
||||
.. class:: Response()
|
||||
|
||||
.. attribute:: Response.client``
|
||||
.. attribute:: client
|
||||
|
||||
The test client that was used to make the request that resulted in the
|
||||
response.
|
||||
|
||||
.. attribute:: Response.content
|
||||
.. attribute:: content
|
||||
|
||||
The body of the response, as a string. This is the final page content as
|
||||
rendered by the view, or any error message.
|
||||
|
||||
.. attribute:: Response.context
|
||||
.. attribute:: context
|
||||
|
||||
The template ``Context`` instance that was used to render the template that
|
||||
produced the response content.
|
||||
|
||||
If the rendered page used multiple templates, then ``context`` will be a
|
||||
list of ``Context`` objects, in the order in which they were rendered.
|
||||
|
||||
.. attribute:: Response.request``
|
||||
.. attribute:: request
|
||||
|
||||
The request data that stimulated the response.
|
||||
|
||||
.. attribute:: Response.status_code
|
||||
The HTTP status of the response, as an integer. See RFC2616_ for a full list
|
||||
of HTTP status codes.
|
||||
.. attribute:: status_code
|
||||
|
||||
The HTTP status of the response, as an integer. See RFC2616_ for a full
|
||||
list of HTTP status codes.
|
||||
|
||||
.. attribute:: template
|
||||
|
||||
The ``Template`` instance that was used to render the final content. Use
|
||||
``template.name`` to get the template's file name, if the template was
|
||||
loaded from a file. (The name is a string such as ``'admin/index.html'``.)
|
||||
|
||||
If the rendered page used multiple templates -- e.g., using :ref:`template
|
||||
inheritance<template-inheritance>` -- then ``template`` will be a list of ``Template`` instances,
|
||||
in the order in which they were rendered.
|
||||
inheritance<template-inheritance>` -- then ``template`` will be a list of
|
||||
``Template`` instances, in the order in which they were rendered.
|
||||
|
||||
You can also use dictionary syntax on the response object to query the value
|
||||
of any settings in the HTTP headers. For example, you could determine the
|
||||
|
@ -669,8 +679,8 @@ can access these properties as part of a test condition.
|
|||
|
||||
.. attribute:: Client.session
|
||||
|
||||
A dictionary-like object containing session information. See the :ref:`session
|
||||
documentation<topics-http-sessions>` for full details.
|
||||
A dictionary-like object containing session information. See the
|
||||
:ref:`session documentation<topics-http-sessions>` for full details.
|
||||
|
||||
.. _Cookie module documentation: http://docs.python.org/lib/module-Cookie.html
|
||||
|
||||
|
@ -772,9 +782,9 @@ A fixture is a collection of data that Django knows how to import into a
|
|||
database. For example, if your site has user accounts, you might set up a
|
||||
fixture of fake user accounts in order to populate your database during tests.
|
||||
|
||||
The most straightforward way of creating a fixture is to use the
|
||||
``manage.py dumpdata`` command. This assumes you already have some data in
|
||||
your database. See the :djadmin:`dumpdata documentation<dumpdata>` for more details.
|
||||
The most straightforward way of creating a fixture is to use the ``manage.py
|
||||
dumpdata`` command. This assumes you already have some data in your database.
|
||||
See the :djadmin:`dumpdata documentation<dumpdata>` for more details.
|
||||
|
||||
.. note::
|
||||
If you've ever run ``manage.py syncdb``, you've already used a fixture
|
||||
|
@ -810,12 +820,12 @@ Here's specifically what will happen:
|
|||
|
||||
* Then, all the named fixtures are installed. In this example, Django will
|
||||
install any JSON fixture named ``mammals``, followed by any fixture named
|
||||
``birds``. See the :djadmin:`loaddata documentation<loaddata>` for more details on defining
|
||||
and installing fixtures.
|
||||
``birds``. See the :djadmin:`loaddata documentation<loaddata>` for more
|
||||
details on defining and installing fixtures.
|
||||
|
||||
This flush/load procedure is repeated for each test in the test case, so you
|
||||
can be certain that the outcome of a test will not be affected by
|
||||
another test, or by the order of test execution.
|
||||
can be certain that the outcome of a test will not be affected by another test,
|
||||
or by the order of test execution.
|
||||
|
||||
URLconf configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -824,18 +834,18 @@ URLconf configuration
|
|||
|
||||
.. attribute:: TestCase.urls
|
||||
|
||||
If your application provides views, you may want to include tests that
|
||||
use the test client to exercise those views. However, an end user is free
|
||||
to deploy the views in your application at any URL of their choosing.
|
||||
This means that your tests can't rely upon the fact that your views will
|
||||
be available at a particular URL.
|
||||
If your application provides views, you may want to include tests that use the
|
||||
test client to exercise those views. However, an end user is free to deploy the
|
||||
views in your application at any URL of their choosing. This means that your
|
||||
tests can't rely upon the fact that your views will be available at a
|
||||
particular URL.
|
||||
|
||||
In order to provide a reliable URL space for your test,
|
||||
``django.test.TestCase`` provides the ability to customize the URLconf
|
||||
configuration for the duration of the execution of a test suite.
|
||||
If your ``TestCase`` instance defines an ``urls`` attribute, the
|
||||
``TestCase`` will use the value of that attribute as the ``ROOT_URLCONF``
|
||||
for the duration of that test.
|
||||
configuration for the duration of the execution of a test suite. If your
|
||||
``TestCase`` instance defines an ``urls`` attribute, the ``TestCase`` will use
|
||||
the value of that attribute as the ``ROOT_URLCONF`` for the duration of that
|
||||
test.
|
||||
|
||||
For example::
|
||||
|
||||
|
@ -867,10 +877,10 @@ Assertions
|
|||
|
||||
**New in Django development version**
|
||||
|
||||
As Python's normal ``unittest.TestCase`` class implements assertion
|
||||
methods such as ``assertTrue`` and ``assertEquals``, Django's custom
|
||||
``TestCase`` class provides a number of custom assertion methods that are
|
||||
useful for testing Web applications:
|
||||
As Python's normal ``unittest.TestCase`` class implements assertion methods
|
||||
such as ``assertTrue`` and ``assertEquals``, Django's custom ``TestCase`` class
|
||||
provides a number of custom assertion methods that are useful for testing Web
|
||||
applications:
|
||||
|
||||
.. method:: TestCase.assertContains(response, text, count=None, status_code=200)
|
||||
|
||||
|
@ -913,8 +923,8 @@ useful for testing Web applications:
|
|||
|
||||
.. method:: assertRedirects(response, expected_url, status_code=302, target_status_code=200)
|
||||
|
||||
Asserts that the response return a ``status_code`` redirect status,
|
||||
it redirected to ``expected_url`` (including any GET data), and the subsequent
|
||||
Asserts that the response return a ``status_code`` redirect status, it
|
||||
redirected to ``expected_url`` (including any GET data), and the subsequent
|
||||
page was received with ``target_status_code``.
|
||||
|
||||
E-mail services
|
||||
|
@ -930,21 +940,22 @@ test every aspect of sending e-mail -- from the number of messages sent to the
|
|||
contents of each message -- without actually sending the messages.
|
||||
|
||||
The test runner accomplishes this by transparently replacing the normal
|
||||
:class:`~django.core.mail.SMTPConnection` class with a different version. (Don't
|
||||
worry -- this has no effect on any other e-mail senders outside of Django, such
|
||||
as your machine's mail server, if you're running one.)
|
||||
:class:`~django.core.mail.SMTPConnection` class with a different version.
|
||||
(Don't worry -- this has no effect on any other e-mail senders outside of
|
||||
Django, such as your machine's mail server, if you're running one.)
|
||||
|
||||
.. currentmodule:: django.core.mail
|
||||
|
||||
.. data:: django.core.mail.output
|
||||
|
||||
During test running, each outgoing e-mail is saved in
|
||||
``django.core.mail.outbox``. This is a simple list of all :class:`<~django.core.mail.EmailMessage>`
|
||||
instances that have been sent. It does not exist under normal execution
|
||||
conditions, i.e., when you're not running unit tests. The outbox is created
|
||||
during test setup, along with the dummy :class:`<~django.core.mail.SMTPConnection>`. When the test
|
||||
framework is torn down, the standard :class:`<~django.core.mail.SMTPConnection>` class is restored, and
|
||||
the test outbox is destroyed.
|
||||
``django.core.mail.outbox``. This is a simple list of all
|
||||
:class:`<~django.core.mail.EmailMessage>` instances that have been sent.
|
||||
It does not exist under normal execution conditions, i.e., when you're not
|
||||
running unit tests. The outbox is created during test setup, along with the
|
||||
dummy :class:`<~django.core.mail.SMTPConnection>`. When the test framework is
|
||||
torn down, the standard :class:`<~django.core.mail.SMTPConnection>` class is
|
||||
restored, and the test outbox is destroyed.
|
||||
|
||||
Here's an example test that examines ``django.core.mail.outbox`` for length
|
||||
and contents::
|
||||
|
@ -965,9 +976,9 @@ and contents::
|
|||
# Verify that the subject of the first message is correct.
|
||||
self.assertEqual(mail.outbox[0].subject, 'Subject here')
|
||||
|
||||
As noted :ref:`previously <emptying-test-outbox>`, the test outbox is emptied at the start of every
|
||||
test in a Django ``TestCase``. To empty the outbox manually, assign the
|
||||
empty list to ``mail.outbox``::
|
||||
As noted :ref:`previously <emptying-test-outbox>`, the test outbox is emptied
|
||||
at the start of every test in a Django ``TestCase``. To empty the outbox
|
||||
manually, assign the empty list to ``mail.outbox``::
|
||||
|
||||
from django.core import mail
|
||||
|
||||
|
@ -1004,9 +1015,9 @@ testing behavior. This behavior involves:
|
|||
#. Performing global post-test teardown.
|
||||
|
||||
If you define your own test runner method and point :setting:`TEST_RUNNER` at
|
||||
that method, Django will execute your test runner whenever you run ``./manage.py
|
||||
test``. In this way, it is possible to use any test framework that can be
|
||||
executed from Python code.
|
||||
that method, Django will execute your test runner whenever you run
|
||||
``./manage.py test``. In this way, it is possible to use any test framework
|
||||
that can be executed from Python code.
|
||||
|
||||
Defining a test runner
|
||||
----------------------
|
||||
|
@ -1053,20 +1064,19 @@ Testing utilities
|
|||
.. module:: django.test.utils
|
||||
:synopsis: Helpers to write custom test runners.
|
||||
|
||||
To assist in the creation of your own test runner, Django provides
|
||||
a number of utility methods in the ``django.test.utils`` module.
|
||||
To assist in the creation of your own test runner, Django provides a number of
|
||||
utility methods in the ``django.test.utils`` module.
|
||||
|
||||
.. function:: setup_test_environment()
|
||||
|
||||
Performs any global pre-test setup, such as the installing the
|
||||
instrumentation of the template rendering system and setting up
|
||||
the dummy ``SMTPConnection``.
|
||||
instrumentation of the template rendering system and setting up the dummy
|
||||
``SMTPConnection``.
|
||||
|
||||
.. function:: teardown_test_environment()
|
||||
|
||||
Performs any global post-test teardown, such as removing the
|
||||
black magic hooks into the template system and restoring normal e-mail
|
||||
services.
|
||||
Performs any global post-test teardown, such as removing the black magic
|
||||
hooks into the template system and restoring normal e-mail services.
|
||||
|
||||
The creation module of the database backend (``connection.creation``) also
|
||||
provides some utilities that can be useful during testing.
|
||||
|
|
Loading…
Reference in New Issue