mirror of https://github.com/django/django.git
Finally began proofreading docs/testing.txt. Did the intro for now; more to come
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5153 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
36b164d838
commit
3d52993b46
118
docs/testing.txt
118
docs/testing.txt
|
@ -2,19 +2,29 @@
|
|||
Testing Django applications
|
||||
===========================
|
||||
|
||||
Automated testing is an extremely useful weapon in the bug-killing arsenal
|
||||
of the modern developer. When initially writing code, a test suite can be
|
||||
used to validate that code behaves as expected. When refactoring or
|
||||
modifying code, tests serve as a guide to ensure that behavior hasn't
|
||||
changed unexpectedly as a result of the refactor.
|
||||
Automated testing is an extremely useful bug-killing tool for the modern
|
||||
Web developer. You can use a collection of tests -- a **test suite** -- to
|
||||
to solve, or avoid, a number of problems:
|
||||
|
||||
Testing a web application is a complex task, as there are many
|
||||
components of a web application that must be validated and tested. To
|
||||
help you test your application, Django provides a test execution
|
||||
framework, and range of utilities that can be used to simulate and
|
||||
inspect various facets of a web application.
|
||||
* When you're writing new code, you can use tests to validate your code
|
||||
works as expected.
|
||||
|
||||
This testing framework is currently under development, and may change
|
||||
* When you're refactoring or modifying old code, you can use tests to
|
||||
ensure your changes haven't affected your application's behavior
|
||||
unexpectedly.
|
||||
|
||||
Testing a Web application is a complex task, because a Web application is made
|
||||
of several layers of logic -- from HTTP-level request handling, to form
|
||||
validation and processing, to template rendering. With Django's test-execution
|
||||
framework and assorted utilities, you can simulate requests, insert test data,
|
||||
inspect your application's output and generally verify your code is doing what
|
||||
it should be doing.
|
||||
|
||||
The best part is, it's really easy.
|
||||
|
||||
.. admonition:: Note
|
||||
|
||||
This testing framework is currently under development. It may change
|
||||
slightly before the next official Django release.
|
||||
|
||||
(That's *no* excuse not to write tests, though!)
|
||||
|
@ -216,21 +226,21 @@ can be invoked on the ``Client`` instance.
|
|||
|
||||
``post(path, data={}, content_type=MULTIPART_CONTENT)``
|
||||
Make a POST request on the provided ``path``. If you provide a content type
|
||||
(e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be
|
||||
sent as-is in the POST request, using the content type in the HTTP
|
||||
(e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be
|
||||
sent as-is in the POST request, using the content type in the HTTP
|
||||
``Content-Type`` header.
|
||||
|
||||
If you do not provide a value for ``content_type``, the values in
|
||||
|
||||
If you do not provide a value for ``content_type``, the values in
|
||||
``data`` will be transmitted with a content type of ``multipart/form-data``.
|
||||
The key-value pairs in the data dictionary 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 multiple selection list), provide the values as a
|
||||
|
||||
To submit multiple values for a given key (for example, to specify
|
||||
the selections for a multiple selection list), provide the values as a
|
||||
list or tuple for the required key. For example, a data dictionary of
|
||||
``{'choices': ('a','b','d')}`` would submit three selected rows for the
|
||||
field named ``choices``.
|
||||
|
||||
|
||||
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.,
|
||||
|
@ -248,31 +258,31 @@ can be invoked on the ``Client`` instance.
|
|||
|
||||
``login(**credentials)``
|
||||
** New in Django development version **
|
||||
|
||||
|
||||
On a production site, it is likely that some views will be protected from
|
||||
anonymous access through the use of the @login_required decorator, or some
|
||||
other login checking mechanism. The ``login()`` method can be used to
|
||||
simulate the effect of a user logging into the site. As a result of calling
|
||||
this method, the Client will have all the cookies and session data required
|
||||
to pass any login-based tests that may form part of a view.
|
||||
|
||||
In most cases, the ``credentials`` required by this method are the username
|
||||
and password of the user that wants to log in, provided as keyword
|
||||
|
||||
In most cases, the ``credentials`` required by this method are the username
|
||||
and password of the user that wants to log in, provided as keyword
|
||||
arguments::
|
||||
|
||||
|
||||
c = Client()
|
||||
c.login(username='fred', password='secret')
|
||||
# Now you can access a login protected view
|
||||
|
||||
If you are using a different authentication backend, this method may
|
||||
require different credentials.
|
||||
|
||||
``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.
|
||||
|
||||
Note that since the test suite will be executed using the test database,
|
||||
which contains no users by default. As a result, logins that are valid
|
||||
on your production site will not work under test conditions. You will
|
||||
on your production site will not work under test conditions. You will
|
||||
need to create users as part of the test suite (either manually, or
|
||||
using a test fixture).
|
||||
|
||||
|
@ -373,13 +383,13 @@ The following is a simple unit test using the Test Client::
|
|||
TestCase
|
||||
--------
|
||||
|
||||
Normal python unit tests extend a base class of ``unittest.testCase``.
|
||||
Django provides an extension of this base class - ``django.test.TestCase``
|
||||
- that provides some additional capabilities that can be useful for
|
||||
testing web sites.
|
||||
Normal python unit tests extend a base class of ``unittest.testCase``.
|
||||
Django provides an extension of this base class - ``django.test.TestCase``
|
||||
- that provides some additional capabilities that can be useful for
|
||||
testing web sites.
|
||||
|
||||
Moving from a normal unittest TestCase to a Django TestCase is easy - just
|
||||
change the base class of your test from ``unittest.TestCase`` to
|
||||
change the base class of your test from ``unittest.TestCase`` to
|
||||
``django.test.TestCase``. All of the standard Python unit test facilities
|
||||
will continue to be available, but they will be augmented with some useful
|
||||
extra facilities.
|
||||
|
@ -389,7 +399,7 @@ Default Test Client
|
|||
** New in Django development version **
|
||||
|
||||
Every test case in a ``django.test.TestCase`` instance has access to an
|
||||
instance of a Django `Test Client`_. This Client can be accessed as
|
||||
instance of a Django `Test Client`_. This Client can be accessed as
|
||||
``self.client``. This client is recreated for each test.
|
||||
|
||||
Fixture loading
|
||||
|
@ -405,20 +415,20 @@ comprise the fixture can be distributed over multiple directories, in
|
|||
multiple applications.
|
||||
|
||||
.. note::
|
||||
If you have synchronized a Django project, you have already experienced
|
||||
If you have synchronized a Django project, you have already experienced
|
||||
the use of one fixture -- the ``initial_data`` fixture. Every time you
|
||||
synchronize the database, Django installs the ``initial_data`` fixture.
|
||||
This provides a mechanism to populate a new database with any initial
|
||||
data (such as a default set of categories). Fixtures with other names
|
||||
can be installed manually using ``django-admin.py loaddata``.
|
||||
can be installed manually using ``django-admin.py loaddata``.
|
||||
|
||||
However, for the purposes of unit testing, each test must be able to
|
||||
However, for the purposes of unit testing, each test must be able to
|
||||
guarantee the contents of the database at the start of each and every
|
||||
test.
|
||||
test.
|
||||
|
||||
To define a fixture for a test, all you need to do is add a class
|
||||
attribute to your test describing the fixtures you want the test to use.
|
||||
For example, the test case from `Writing unittests`_ would
|
||||
For example, the test case from `Writing unittests`_ would
|
||||
look like::
|
||||
|
||||
from django.test import TestCase
|
||||
|
@ -426,29 +436,29 @@ look like::
|
|||
|
||||
class AnimalTestCase(TestCase):
|
||||
fixtures = ['mammals.json', 'birds']
|
||||
|
||||
|
||||
def setUp(self):
|
||||
# test definitions as before
|
||||
|
||||
At the start of each test case, before ``setUp()`` is run, Django will
|
||||
flush the database, returning the database the state it was in directly
|
||||
after ``syncdb`` was called. Then, all the named fixtures are installed.
|
||||
flush the database, returning the database the state it was in directly
|
||||
after ``syncdb`` was called. Then, all the named fixtures are installed.
|
||||
In this example, any JSON fixture called ``mammals``, and any fixture
|
||||
named ``birds`` will be installed. See the documentation on
|
||||
named ``birds`` will be installed. See the documentation on
|
||||
`loading fixtures`_ for more details on defining and installing fixtures.
|
||||
|
||||
.. _`loading fixtures`: ../django-admin/#loaddata-fixture-fixture
|
||||
|
||||
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
|
||||
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 the order of test execution.
|
||||
|
||||
Assertions
|
||||
~~~~~~~~~~
|
||||
** New in Django development version **
|
||||
|
||||
Normal Python unit tests have a wide range of assertions, such as
|
||||
``assertTrue`` and ``assertEquals`` that can be used to validate behavior.
|
||||
Normal Python unit tests have a wide range of assertions, such as
|
||||
``assertTrue`` and ``assertEquals`` that can be used to validate behavior.
|
||||
``django.TestCase`` adds to these, providing some assertions
|
||||
that can be useful in testing the behavior of web sites.
|
||||
|
||||
|
@ -458,9 +468,9 @@ that can be useful in testing the behavior of web sites.
|
|||
|
||||
``assertContains(response, text, count=1)``
|
||||
Assert that a response indicates that a page was retreived successfully,
|
||||
(i.e., the HTTP status code was 200), and that ``text`` occurs ``count``
|
||||
(i.e., the HTTP status code was 200), and that ``text`` occurs ``count``
|
||||
times in the content of the response.
|
||||
|
||||
|
||||
Running tests
|
||||
=============
|
||||
|
||||
|
@ -519,11 +529,11 @@ failed::
|
|||
|
||||
FAILED (failures=1)
|
||||
|
||||
The return code for the script is the total number of failed and erroneous
|
||||
The return code for the script is the total number of failed and erroneous
|
||||
tests. If all the tests pass, the return code is 0.
|
||||
|
||||
Regardless of whether the tests pass or fail, the test database is destroyed when
|
||||
all the tests have been executed.
|
||||
all the tests have been executed.
|
||||
|
||||
Using a different testing framework
|
||||
===================================
|
||||
|
@ -534,7 +544,7 @@ it does provide a mechanism to allow you to invoke tests constructed for
|
|||
an alternative framework as if they were normal Django tests.
|
||||
|
||||
When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
|
||||
setting to determine what to do. By default, ``TEST_RUNNER`` points to
|
||||
setting to determine what to do. By default, ``TEST_RUNNER`` points to
|
||||
``django.test.simple.run_tests``. This method defines the default Django
|
||||
testing behavior. This behavior involves:
|
||||
|
||||
|
@ -564,7 +574,7 @@ arguments:
|
|||
Verbosity determines the amount of notification and debug information that
|
||||
will be printed to the console; `0` is no output, `1` is normal output,
|
||||
and `2` is verbose output.
|
||||
|
||||
|
||||
This method should return the number of tests that failed.
|
||||
|
||||
Testing utilities
|
||||
|
|
Loading…
Reference in New Issue