Added a rough cut of a document on using the new testing framework.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3678 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2006-08-29 18:04:09 +00:00
parent f89b9c8654
commit ff4f24958d
2 changed files with 199 additions and 0 deletions

View File

@ -292,6 +292,13 @@ this command to install the default apps.
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
give you the option of creating a superuser immediately. give you the option of creating a superuser immediately.
test
----
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
.. _testing django applications: ../testing/
validate validate
-------- --------

192
docs/testing.txt Normal file
View File

@ -0,0 +1,192 @@
===========================
Testing Django applications
===========================
**New in Django development version**.
.. XXX insert quick introduction to testing (and why you'd want to do it)
.. note::
This testing framework is currently under development, and may change
slightly before the next official Django release.
(That's *no* excuse not to write tests, though!)
Writing tests
=============
Tests in Django come in two forms: doctests and unit tests.
Writing doctests
----------------
Doctests use Python's standard doctest_ module, which searches for tests in
your docstrings. Django's test runner looks for doctests in your ``models.py``
file, and executes any that it finds.
.. admonition:: What's a **docstring**?
A good explanation of docstrings (and some guidlines for using them
effectively) can be found in :PEP:`257`:
A docstring is a string literal that occurs as the first statement in
a module, function, class, or method definition. Such a docstring
becomes the ``__doc__`` special attribute of that object.
Since tests often make great documentation, doctest lets you put your
tests directly in your docstrings.
You can put doctest strings on any object in your ``models.py``, but it's
common practice to put application-level doctests in the module docstring, and
model-level doctests in the docstring for each model.
For example::
from django.db import model
class Animal(models.Model):
"""
An animal that knows how to make noise
# Create some animals
>>> lion = Animal.objects.create(name="lion", sound="roar")
>>> cat = Animal.objects.create(name="cat", sound="meow")
# Make 'em speak
>>> lion.speak()
'The lion says "roar"'
>>> cat.speak()
'The cat says "meow"'
"""
name = models.CharField(maxlength=20)
sound = models.CharField(maxlength=20)
def speak(self):
return 'The %s says "%s"' % (self.name, self.sound)
When you `run your tests`_, the test utility 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.
For more details about how doctest works, see the `standard library
documentation for doctest`_
.. _doctest: http://docs.python.org/lib/module-doctest.html
.. _standard library documentation for doctest: doctest_
Writing unittests
-----------------
Like doctests, Django's unit tests use a standard library module: unittest_.
Django's test runner looks for unit test cases in a ``tests.py`` file in your
app (i.e. in the same directory as your ``models.py`` file).
An equivalent unittest test case for the above example would look like::
import unittest
from myapp.models import Animal
class AnimalTestCase(unittest.TestCase):
def setUp(self):
self.lion = Animal.objects.create(name="lion", sound="roar")
self.cat = Animal.objects.create(name="cat", sound="meow")
def testSpeaking(self):
self.assertEquals(self.lion.speak(), 'The lion says "roar"')
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
When you `run your tests`_, the test utility will find all the test cases
(that is, subclasses of ``unittest.TestCase``) in ``tests.py``, automatically
build a test suite out of those test cases, and run that suite.
For more details about ``unittest``, see the `standard library unittest
documentation`_.
.. _unittest: http://docs.python.org/lib/module-unittest.html
.. _standard library unittest documentation: unittest_
.. _run your tests: `Running tests`_
Which should I use?
-------------------
Choosing a test framework is often contentious, so Django simply supports
both of the standard Python test frameworks. Choosing one is up to each
developer's personal tastes; each is supported equally. Since each test
system has different benefits, the best approach is probably to use both
together, picking the test system to match the type of tests you need to
write.
For developers new to testing, however, this choice can seem
confusing, so here are a few key differences to help you decide weather
doctests or unit tests are right for you.
If you've been using Python for a while, ``doctest`` will probably feel more
"pythonic". It's designed to make writing tests as easy as possible, so
there's no overhead of writing classes or methods; you simply put tests in
docstrings. This gives the added advantage of given your modules automatic
documentation -- well-written doctests can kill both the documentation and the
testing bird with a single stone.
For developers just getting started with testing, using doctests will probably
get you started faster.
The ``unittest`` framework will probably feel very familiar to developers
coming from Java. Since ``unittest`` is inspired by Java's JUnit, if
you've used testing frameworks in other languages that similarly were
inspired by JUnit, ``unittest`` should also feel pretty familiar.
Since ``unittest`` is organized around classes and methods, if you need
to write a bunch of tests that all share similar code, you can easily use
subclass to abstract common tasks; this makes test code shorter and cleaner.
There's also support for explicit setup and/or cleanup routines, which give
you a high level of control over the environment your test cases run in.
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.
Running tests
=============
Run your tests using your project's ``manage.py`` utility::
$ ./manage.py test
You'll see a bunch of text flow by as the test database is created, models are
initialized, and your tests are run. If everything goes well, at the end
you'll see::
----------------------------------------------------------------------
Ran 22 tests in 0.221s
OK
If there are test failures, however, you'll see full details about what tests
failed::
======================================================================
FAIL: Doctest: ellington.core.throttle.models
----------------------------------------------------------------------
Traceback (most recent call last):
File "/dev/django/test/doctest.py", line 2153, in runTest
raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for myapp.models
File "/dev/myapp/models.py", line 0, in models
----------------------------------------------------------------------
File "/dev/myapp/models.py", line 14, in myapp.models
Failed example:
throttle.check("actor A", "action one", limit=2, hours=1)
Expected:
True
Got:
False
----------------------------------------------------------------------
Ran 2 tests in 0.048s
FAILED (failures=1)