Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #13628 - Discourage the use of doctests; thanks d0ugal for the …

…suggestion.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15227 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5fd93e1c36081662c83cf817ac8370bf5f82b6fb 1 parent f89f1c8
Tim Graham authored January 16, 2011

Showing 1 changed file with 103 additions and 107 deletions. Show diff stats Hide diff stats

  1. 210  docs/topics/testing.txt
210  docs/topics/testing.txt
@@ -35,6 +35,17 @@ There are two primary ways to write tests with Django, corresponding to the
35 35
 two test frameworks that ship in the Python standard library. The two
36 36
 frameworks are:
37 37
 
  38
+    * **Unit tests** -- tests that are expressed as methods on a Python class
  39
+      that subclasses ``unittest.TestCase``. For example::
  40
+
  41
+          import unittest
  42
+
  43
+          class MyFuncTestCase(unittest.TestCase):
  44
+              def testBasic(self):
  45
+                  a = ['larry', 'curly', 'moe']
  46
+                  self.assertEqual(my_func(a, 0), 'larry')
  47
+                  self.assertEqual(my_func(a, 1), 'curly')
  48
+
38 49
     * **Doctests** -- tests that are embedded in your functions' docstrings and
39 50
       are written in a way that emulates a session of the Python interactive
40 51
       interpreter. For example::
@@ -49,21 +60,87 @@ frameworks are:
49 60
               """
50 61
               return a_list[idx]
51 62
 
52  
-    * **Unit tests** -- tests that are expressed as methods on a Python class
53  
-      that subclasses ``unittest.TestCase``. For example::
  63
+We'll discuss choosing the appropriate test framework later, however, most
  64
+experienced developers prefer unit tests. You can also use any *other* Python
  65
+test framework, as we'll explain in a bit.
54 66
 
55  
-          import unittest
  67
+Writing unit tests
  68
+------------------
56 69
 
57  
-          class MyFuncTestCase(unittest.TestCase):
58  
-              def testBasic(self):
59  
-                  a = ['larry', 'curly', 'moe']
60  
-                  self.assertEqual(my_func(a, 0), 'larry')
61  
-                  self.assertEqual(my_func(a, 1), 'curly')
  70
+Django's unit tests use a Python standard library module: unittest_. This
  71
+module defines tests in class-based approach.
  72
+
  73
+.. admonition:: unittest2
  74
+
  75
+    .. versionchanged:: 1.3
  76
+
  77
+    Python 2.7 introduced some major changes to the unittest library,
  78
+    adding some extremely useful features. To ensure that every Django
  79
+    project can benefit from these new features, Django ships with a
  80
+    copy of unittest2_, a copy of the Python 2.7 unittest library,
  81
+    backported for Python 2.4 compatibility.
  82
+
  83
+    To access this library, Django provides the
  84
+    ``django.utils.unittest`` module alias. If you are using Python
  85
+    2.7, or you have installed unittest2 locally, Django will map the
  86
+    alias to the installed version of the unittest library. Otherwise,
  87
+    Django will use it's own bundled version of unittest2.
  88
+
  89
+    To use this alias, simply use::
  90
+
  91
+        from django.utils import unittest
  92
+
  93
+    wherever you would have historically used::
  94
+
  95
+        import unittest
  96
+
  97
+    If you want to continue to use the base unittest libary, you can --
  98
+    you just won't get any of the nice new unittest2 features.
  99
+
  100
+.. _unittest2: http://pypi.python.org/pypi/unittest2
  101
+
  102
+For a given Django application, the test runner looks for unit tests in two
  103
+places:
  104
+
  105
+    * The ``models.py`` file. The test runner looks for any subclass of
  106
+      ``unittest.TestCase`` in this module.
  107
+
  108
+    * A file called ``tests.py`` in the application directory -- i.e., the
  109
+      directory that holds ``models.py``. Again, the test runner looks for any
  110
+      subclass of ``unittest.TestCase`` in this module.
  111
+
  112
+Here is an example ``unittest.TestCase`` subclass::
  113
+
  114
+    from django.utils import unittest
  115
+    from myapp.models import Animal
  116
+
  117
+    class AnimalTestCase(unittest.TestCase):
  118
+        def setUp(self):
  119
+            self.lion = Animal.objects.create(name="lion", sound="roar")
  120
+            self.cat = Animal.objects.create(name="cat", sound="meow")
  121
+
  122
+        def testSpeaking(self):
  123
+            self.assertEqual(self.lion.speak(), 'The lion says "roar"')
  124
+            self.assertEqual(self.cat.speak(), 'The cat says "meow"')
  125
+
  126
+When you :ref:`run your tests <running-tests>`, the default behavior of the
  127
+test utility is to find all the test cases (that is, subclasses of
  128
+``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a
  129
+test suite out of those test cases, and run that suite.
  130
+
  131
+There is a second way to define the test suite for a module: if you define a
  132
+function called ``suite()`` in either ``models.py`` or ``tests.py``, the
  133
+Django test runner will use that function to construct the test suite for that
  134
+module. This follows the `suggested organization`_ for unit tests. See the
  135
+Python documentation for more details on how to construct a complex test
  136
+suite.
62 137
 
63  
-You can choose the test framework you like, depending on which syntax you
64  
-prefer, or you can mix and match, using one framework for some of your code and
65  
-the other framework for other code. You can also use any *other* Python test
66  
-frameworks, as we'll explain in a bit.
  138
+For more details about ``unittest``, see the `standard library unittest
  139
+documentation`_.
  140
+
  141
+.. _unittest: http://docs.python.org/library/unittest.html
  142
+.. _standard library unittest documentation: unittest_
  143
+.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
67 144
 
68 145
 Writing doctests
69 146
 ----------------
@@ -85,14 +162,14 @@ read Python's official documentation for the details.
85 162
     For example, this function has a docstring that describes what it does::
86 163
 
87 164
         def add_two(num):
88  
-          "Return the result of adding two to the provided number."
89  
-           return num + 2
  165
+            "Return the result of adding two to the provided number."
  166
+            return num + 2
90 167
 
91 168
     Because tests often make great documentation, putting tests directly in
92 169
     your docstrings is an effective way to document *and* test your code.
93 170
 
94  
-For a given Django application, the test runner looks for doctests in two
95  
-places:
  171
+As with unit tests, for a given Django application, the test runner looks for
  172
+doctests in two places:
96 173
 
97 174
     * The ``models.py`` file. You can define module-level doctests and/or a
98 175
       doctest for individual models. It's common practice to put
@@ -103,7 +180,8 @@ places:
103 180
       directory that holds ``models.py``. This file is a hook for any and all
104 181
       doctests you want to write that aren't necessarily related to models.
105 182
 
106  
-Here is an example model doctest::
  183
+This example doctest is equivalent to the example given in the unittest section
  184
+above::
107 185
 
108 186
     # models.py
109 187
 
@@ -148,86 +226,6 @@ documentation for doctest`_.
148 226
 .. _doctest: http://docs.python.org/library/doctest.html
149 227
 .. _standard library documentation for doctest: doctest_
150 228
 
151  
-Writing unit tests
152  
-------------------
153  
-
154  
-Like doctests, Django's unit tests use a Python standard library
155  
-module: unittest_. This module uses a different way of defining tests,
156  
-taking a class-based approach.
157  
-
158  
-.. admonition:: unittest2
159  
-
160  
-    .. versionchanged:: 1.3
161  
-
162  
-    Python 2.7 introduced some major changes to the unittest library,
163  
-    adding some extremely useful features. To ensure that every Django
164  
-    project can benefit from these new features, Django ships with a
165  
-    copy of unittest2_, a copy of the Python 2.7 unittest library,
166  
-    backported for Python 2.4 compatibility.
167  
-
168  
-    To access this library, Django provides the
169  
-    ``django.utils.unittest`` module alias. If you are using Python
170  
-    2.7, or you have installed unittest2 locally, Django will map the
171  
-    alias to the installed version of the unittest library. Otherwise,
172  
-    Django will use it's own bundled version of unittest2.
173  
-
174  
-    To use this alias, simply use::
175  
-
176  
-        from django.utils import unittest
177  
-
178  
-    wherever you would have historically used::
179  
-
180  
-        import unittest
181  
-
182  
-    If you want to continue to use the base unittest libary, you can --
183  
-    you just won't get any of the nice new unittest2 features.
184  
-
185  
-.. _unittest2: http://pypi.python.org/pypi/unittest2
186  
-
187  
-As with doctests, for a given Django application, the test runner looks for
188  
-unit tests in two places:
189  
-
190  
-    * The ``models.py`` file. The test runner looks for any subclass of
191  
-      ``unittest.TestCase`` in this module.
192  
-
193  
-    * A file called ``tests.py`` in the application directory -- i.e., the
194  
-      directory that holds ``models.py``. Again, the test runner looks for any
195  
-      subclass of ``unittest.TestCase`` in this module.
196  
-
197  
-This example ``unittest.TestCase`` subclass is equivalent to the example given
198  
-in the doctest section above::
199  
-
200  
-    from django.utils import unittest
201  
-    from myapp.models import Animal
202  
-
203  
-    class AnimalTestCase(unittest.TestCase):
204  
-        def setUp(self):
205  
-            self.lion = Animal.objects.create(name="lion", sound="roar")
206  
-            self.cat = Animal.objects.create(name="cat", sound="meow")
207  
-
208  
-        def testSpeaking(self):
209  
-            self.assertEqual(self.lion.speak(), 'The lion says "roar"')
210  
-            self.assertEqual(self.cat.speak(), 'The cat says "meow"')
211  
-
212  
-When you :ref:`run your tests <running-tests>`, the default behavior of the
213  
-test utility is to find all the test cases (that is, subclasses of
214  
-``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a
215  
-test suite out of those test cases, and run that suite.
216  
-
217  
-There is a second way to define the test suite for a module: if you define a
218  
-function called ``suite()`` in either ``models.py`` or ``tests.py``, the
219  
-Django test runner will use that function to construct the test suite for that
220  
-module. This follows the `suggested organization`_ for unit tests. See the
221  
-Python documentation for more details on how to construct a complex test
222  
-suite.
223  
-
224  
-For more details about ``unittest``, see the `standard library unittest
225  
-documentation`_.
226  
-
227  
-.. _unittest: http://docs.python.org/library/unittest.html
228  
-.. _standard library unittest documentation: unittest_
229  
-.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
230  
-
231 229
 
232 230
 Which should I use?
233 231
 -------------------
@@ -244,10 +242,12 @@ you:
244 242
       more "pythonic". It's designed to make writing tests as easy as possible,
245 243
       so it requires no overhead of writing classes or methods. You simply put
246 244
       tests in docstrings. This has the added advantage of serving as
247  
-      documentation (and correct documentation, at that!).
248  
-
249  
-      If you're just getting started with testing, using doctests will probably
250  
-      get you started faster.
  245
+      documentation (and correct documentation, at that!). However, while
  246
+      doctests are good for some simple example code, they are not very good if
  247
+      you want to produce either high quality, comprehensive tests or high
  248
+      quality documentation. Test failures are often difficult to debug
  249
+      as it can be unclear exactly why the test failed. Thus, doctests should
  250
+      generally be avoided and used primarily for documentation examples only.
251 251
 
252 252
     * The ``unittest`` framework will probably feel very familiar to developers
253 253
       coming from Java. ``unittest`` is inspired by Java's JUnit, so you'll
@@ -263,10 +263,6 @@ you:
263 263
 
264 264
     * If you're writing tests for Django itself, you should use ``unittest``.
265 265
 
266  
-Again, remember that you can use both systems side-by-side (even in the same
267  
-app). In the end, most projects will eventually end up using both. Each shines
268  
-in different circumstances.
269  
-
270 266
 .. _running-tests:
271 267
 
272 268
 Running tests
@@ -710,7 +706,7 @@ arguments at time of construction:
710 706
             ...       HTTP_X_REQUESTED_WITH='XMLHttpRequest')
711 707
 
712 708
         ...will send the HTTP header ``HTTP_X_REQUESTED_WITH`` to the
713  
-        details	view, which is a good way to test code paths that use the
  709
+        details view, which is a good way to test code paths that use the
714 710
         :meth:`django.http.HttpRequest.is_ajax()` method.
715 711
 
716 712
         If you already have the GET arguments in URL-encoded form, you can
@@ -1715,7 +1711,7 @@ set up, execute and tear down the test suite.
1715 1711
 .. method:: DjangoTestSuiteRunner.suite_result(suite, result, **kwargs)
1716 1712
 
1717 1713
     Computes and returns a return code based on a test suite, and the result
1718  
-	from that test suite.
  1714
+    from that test suite.
1719 1715
 
1720 1716
 
1721 1717
 Testing utilities

0 notes on commit 5fd93e1

Please sign in to comment.
Something went wrong with that request. Please try again.