Skip to content

Commit ff4f249

Browse files
committed
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
1 parent f89b9c8 commit ff4f249

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

docs/django-admin.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,13 @@ this command to install the default apps.
292292
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
293293
give you the option of creating a superuser immediately.
294294

295+
test
296+
----
297+
298+
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
299+
300+
.. _testing django applications: ../testing/
301+
295302
validate
296303
--------
297304

docs/testing.txt

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
===========================
2+
Testing Django applications
3+
===========================
4+
5+
**New in Django development version**.
6+
7+
.. XXX insert quick introduction to testing (and why you'd want to do it)
8+
9+
.. note::
10+
11+
This testing framework is currently under development, and may change
12+
slightly before the next official Django release.
13+
14+
(That's *no* excuse not to write tests, though!)
15+
16+
Writing tests
17+
=============
18+
19+
Tests in Django come in two forms: doctests and unit tests.
20+
21+
Writing doctests
22+
----------------
23+
24+
Doctests use Python's standard doctest_ module, which searches for tests in
25+
your docstrings. Django's test runner looks for doctests in your ``models.py``
26+
file, and executes any that it finds.
27+
28+
.. admonition:: What's a **docstring**?
29+
30+
A good explanation of docstrings (and some guidlines for using them
31+
effectively) can be found in :PEP:`257`:
32+
33+
A docstring is a string literal that occurs as the first statement in
34+
a module, function, class, or method definition. Such a docstring
35+
becomes the ``__doc__`` special attribute of that object.
36+
37+
Since tests often make great documentation, doctest lets you put your
38+
tests directly in your docstrings.
39+
40+
You can put doctest strings on any object in your ``models.py``, but it's
41+
common practice to put application-level doctests in the module docstring, and
42+
model-level doctests in the docstring for each model.
43+
44+
For example::
45+
46+
from django.db import model
47+
48+
class Animal(models.Model):
49+
"""
50+
An animal that knows how to make noise
51+
52+
# Create some animals
53+
>>> lion = Animal.objects.create(name="lion", sound="roar")
54+
>>> cat = Animal.objects.create(name="cat", sound="meow")
55+
56+
# Make 'em speak
57+
>>> lion.speak()
58+
'The lion says "roar"'
59+
>>> cat.speak()
60+
'The cat says "meow"'
61+
"""
62+
63+
name = models.CharField(maxlength=20)
64+
sound = models.CharField(maxlength=20)
65+
66+
def speak(self):
67+
return 'The %s says "%s"' % (self.name, self.sound)
68+
69+
When you `run your tests`_, the test utility will find this docstring, notice
70+
that portions of it look like an interactive Python session, and execute those
71+
lines while checking that the results match.
72+
73+
For more details about how doctest works, see the `standard library
74+
documentation for doctest`_
75+
76+
.. _doctest: http://docs.python.org/lib/module-doctest.html
77+
.. _standard library documentation for doctest: doctest_
78+
79+
Writing unittests
80+
-----------------
81+
82+
Like doctests, Django's unit tests use a standard library module: unittest_.
83+
Django's test runner looks for unit test cases in a ``tests.py`` file in your
84+
app (i.e. in the same directory as your ``models.py`` file).
85+
86+
An equivalent unittest test case for the above example would look like::
87+
88+
import unittest
89+
from myapp.models import Animal
90+
91+
class AnimalTestCase(unittest.TestCase):
92+
93+
def setUp(self):
94+
self.lion = Animal.objects.create(name="lion", sound="roar")
95+
self.cat = Animal.objects.create(name="cat", sound="meow")
96+
97+
def testSpeaking(self):
98+
self.assertEquals(self.lion.speak(), 'The lion says "roar"')
99+
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
100+
101+
When you `run your tests`_, the test utility will find all the test cases
102+
(that is, subclasses of ``unittest.TestCase``) in ``tests.py``, automatically
103+
build a test suite out of those test cases, and run that suite.
104+
105+
For more details about ``unittest``, see the `standard library unittest
106+
documentation`_.
107+
108+
.. _unittest: http://docs.python.org/lib/module-unittest.html
109+
.. _standard library unittest documentation: unittest_
110+
.. _run your tests: `Running tests`_
111+
112+
Which should I use?
113+
-------------------
114+
115+
Choosing a test framework is often contentious, so Django simply supports
116+
both of the standard Python test frameworks. Choosing one is up to each
117+
developer's personal tastes; each is supported equally. Since each test
118+
system has different benefits, the best approach is probably to use both
119+
together, picking the test system to match the type of tests you need to
120+
write.
121+
122+
For developers new to testing, however, this choice can seem
123+
confusing, so here are a few key differences to help you decide weather
124+
doctests or unit tests are right for you.
125+
126+
If you've been using Python for a while, ``doctest`` will probably feel more
127+
"pythonic". It's designed to make writing tests as easy as possible, so
128+
there's no overhead of writing classes or methods; you simply put tests in
129+
docstrings. This gives the added advantage of given your modules automatic
130+
documentation -- well-written doctests can kill both the documentation and the
131+
testing bird with a single stone.
132+
133+
For developers just getting started with testing, using doctests will probably
134+
get you started faster.
135+
136+
The ``unittest`` framework will probably feel very familiar to developers
137+
coming from Java. Since ``unittest`` is inspired by Java's JUnit, if
138+
you've used testing frameworks in other languages that similarly were
139+
inspired by JUnit, ``unittest`` should also feel pretty familiar.
140+
141+
Since ``unittest`` is organized around classes and methods, if you need
142+
to write a bunch of tests that all share similar code, you can easily use
143+
subclass to abstract common tasks; this makes test code shorter and cleaner.
144+
There's also support for explicit setup and/or cleanup routines, which give
145+
you a high level of control over the environment your test cases run in.
146+
147+
Again, remember that you can use both systems side-by-side (even in the same
148+
app). In the end, most projects will eventually end up using both; each shines
149+
in different circumstances.
150+
151+
Running tests
152+
=============
153+
154+
Run your tests using your project's ``manage.py`` utility::
155+
156+
$ ./manage.py test
157+
158+
You'll see a bunch of text flow by as the test database is created, models are
159+
initialized, and your tests are run. If everything goes well, at the end
160+
you'll see::
161+
162+
----------------------------------------------------------------------
163+
Ran 22 tests in 0.221s
164+
165+
OK
166+
167+
If there are test failures, however, you'll see full details about what tests
168+
failed::
169+
170+
======================================================================
171+
FAIL: Doctest: ellington.core.throttle.models
172+
----------------------------------------------------------------------
173+
Traceback (most recent call last):
174+
File "/dev/django/test/doctest.py", line 2153, in runTest
175+
raise self.failureException(self.format_failure(new.getvalue()))
176+
AssertionError: Failed doctest test for myapp.models
177+
File "/dev/myapp/models.py", line 0, in models
178+
179+
----------------------------------------------------------------------
180+
File "/dev/myapp/models.py", line 14, in myapp.models
181+
Failed example:
182+
throttle.check("actor A", "action one", limit=2, hours=1)
183+
Expected:
184+
True
185+
Got:
186+
False
187+
188+
----------------------------------------------------------------------
189+
Ran 2 tests in 0.048s
190+
191+
FAILED (failures=1)
192+

0 commit comments

Comments
 (0)