Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Fixed #13628 - Discourage the use of doctests; thanks d0ugal …

…for the suggestion.

Backport of r15227 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15228 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 0866dc171582125bb9d81a640a70d907553e9d54 1 parent be12f9e
Tim Graham authored January 16, 2011

Showing 1 changed file with 75 additions and 77 deletions. Show diff stats Hide diff stats

  1. 152  docs/topics/testing.txt
152  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,58 @@ 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.assertEquals(my_func(a, 0), 'larry')
61  
-                  self.assertEquals(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
+For a given Django application, the test runner looks for unit tests in two
  74
+places:
  75
+
  76
+    * The ``models.py`` file. The test runner looks for any subclass of
  77
+      ``unittest.TestCase`` in this module.
  78
+
  79
+    * A file called ``tests.py`` in the application directory -- i.e., the
  80
+      directory that holds ``models.py``. Again, the test runner looks for any
  81
+      subclass of ``unittest.TestCase`` in this module.
  82
+
  83
+Here is an example ``unittest.TestCase`` subclass::
  84
+
  85
+    from django.utils import unittest
  86
+    from myapp.models import Animal
  87
+
  88
+    class AnimalTestCase(unittest.TestCase):
  89
+        def setUp(self):
  90
+            self.lion = Animal.objects.create(name="lion", sound="roar")
  91
+            self.cat = Animal.objects.create(name="cat", sound="meow")
  92
+
  93
+        def testSpeaking(self):
  94
+            self.assertEqual(self.lion.speak(), 'The lion says "roar"')
  95
+            self.assertEqual(self.cat.speak(), 'The cat says "meow"')
  96
+
  97
+When you :ref:`run your tests <running-tests>`, the default behavior of the
  98
+test utility is to find all the test cases (that is, subclasses of
  99
+``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a
  100
+test suite out of those test cases, and run that suite.
  101
+
  102
+There is a second way to define the test suite for a module: if you define a
  103
+function called ``suite()`` in either ``models.py`` or ``tests.py``, the
  104
+Django test runner will use that function to construct the test suite for that
  105
+module. This follows the `suggested organization`_ for unit tests. See the
  106
+Python documentation for more details on how to construct a complex test
  107
+suite.
  108
+
  109
+For more details about ``unittest``, see the `standard library unittest
  110
+documentation`_.
62 111
 
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.
  112
+.. _unittest: http://docs.python.org/library/unittest.html
  113
+.. _standard library unittest documentation: unittest_
  114
+.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
67 115
 
68 116
 Writing doctests
69 117
 ----------------
@@ -85,14 +133,14 @@ read Python's official documentation for the details.
85 133
     For example, this function has a docstring that describes what it does::
86 134
 
87 135
         def add_two(num):
88  
-          "Return the result of adding two to the provided number."
89  
-           return num + 2
  136
+            "Return the result of adding two to the provided number."
  137
+            return num + 2
90 138
 
91 139
     Because tests often make great documentation, putting tests directly in
92 140
     your docstrings is an effective way to document *and* test your code.
93 141
 
94  
-For a given Django application, the test runner looks for doctests in two
95  
-places:
  142
+As with unit tests, for a given Django application, the test runner looks for
  143
+doctests in two places:
96 144
 
97 145
     * The ``models.py`` file. You can define module-level doctests and/or a
98 146
       doctest for individual models. It's common practice to put
@@ -103,7 +151,8 @@ places:
103 151
       directory that holds ``models.py``. This file is a hook for any and all
104 152
       doctests you want to write that aren't necessarily related to models.
105 153
 
106  
-Here is an example model doctest::
  154
+This example doctest is equivalent to the example given in the unittest section
  155
+above::
107 156
 
108 157
     # models.py
109 158
 
@@ -148,57 +197,6 @@ documentation for doctest`_.
148 197
 .. _doctest: http://docs.python.org/library/doctest.html
149 198
 .. _standard library documentation for doctest: doctest_
150 199
 
151  
-Writing unit tests
152  
-------------------
153  
-
154  
-Like doctests, Django's unit tests use a standard library module: unittest_.
155  
-This module uses a different way of defining tests, taking a class-based
156  
-approach.
157  
-
158  
-As with doctests, for a given Django application, the test runner looks for
159  
-unit tests in two places:
160  
-
161  
-    * The ``models.py`` file. The test runner looks for any subclass of
162  
-      ``unittest.TestCase`` in this module.
163  
-
164  
-    * A file called ``tests.py`` in the application directory -- i.e., the
165  
-      directory that holds ``models.py``. Again, the test runner looks for any
166  
-      subclass of ``unittest.TestCase`` in this module.
167  
-
168  
-This example ``unittest.TestCase`` subclass is equivalent to the example given
169  
-in the doctest section above::
170  
-
171  
-    import unittest
172  
-    from myapp.models import Animal
173  
-
174  
-    class AnimalTestCase(unittest.TestCase):
175  
-        def setUp(self):
176  
-            self.lion = Animal.objects.create(name="lion", sound="roar")
177  
-            self.cat = Animal.objects.create(name="cat", sound="meow")
178  
-
179  
-        def testSpeaking(self):
180  
-            self.assertEquals(self.lion.speak(), 'The lion says "roar"')
181  
-            self.assertEquals(self.cat.speak(), 'The cat says "meow"')
182  
-
183  
-When you :ref:`run your tests <running-tests>`, the default behavior of the
184  
-test utility is to find all the test cases (that is, subclasses of
185  
-``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a
186  
-test suite out of those test cases, and run that suite.
187  
-
188  
-There is a second way to define the test suite for a module: if you define a
189  
-function called ``suite()`` in either ``models.py`` or ``tests.py``, the
190  
-Django test runner will use that function to construct the test suite for that
191  
-module. This follows the `suggested organization`_ for unit tests. See the
192  
-Python documentation for more details on how to construct a complex test
193  
-suite.
194  
-
195  
-For more details about ``unittest``, see the `standard library unittest
196  
-documentation`_.
197  
-
198  
-.. _unittest: http://docs.python.org/library/unittest.html
199  
-.. _standard library unittest documentation: unittest_
200  
-.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
201  
-
202 200
 Which should I use?
203 201
 -------------------
204 202
 
@@ -214,10 +212,12 @@ you:
214 212
       more "pythonic". It's designed to make writing tests as easy as possible,
215 213
       so it requires no overhead of writing classes or methods. You simply put
216 214
       tests in docstrings. This has the added advantage of serving as
217  
-      documentation (and correct documentation, at that!).
218  
-
219  
-      If you're just getting started with testing, using doctests will probably
220  
-      get you started faster.
  215
+      documentation (and correct documentation, at that!). However, while
  216
+      doctests are good for some simple example code, they are not very good if
  217
+      you want to produce either high quality, comprehensive tests or high
  218
+      quality documentation. Test failures are often difficult to debug
  219
+      as it can be unclear exactly why the test failed. Thus, doctests should
  220
+      generally be avoided and used primarily for documentation examples only.
221 221
 
222 222
     * The ``unittest`` framework will probably feel very familiar to developers
223 223
       coming from Java. ``unittest`` is inspired by Java's JUnit, so you'll
@@ -231,9 +231,7 @@ you:
231 231
       routines, which give you a high level of control over the environment
232 232
       in which your test cases are run.
233 233
 
234  
-Again, remember that you can use both systems side-by-side (even in the same
235  
-app). In the end, most projects will eventually end up using both. Each shines
236  
-in different circumstances.
  234
+    * If you're writing tests for Django itself, you should use ``unittest``.
237 235
 
238 236
 .. _running-tests:
239 237
 
@@ -676,7 +674,7 @@ arguments at time of construction:
676 674
             ...       HTTP_X_REQUESTED_WITH='XMLHttpRequest')
677 675
 
678 676
         ...will send the HTTP header ``HTTP_X_REQUESTED_WITH`` to the
679  
-        details	view, which is a good way to test code paths that use the
  677
+        details view, which is a good way to test code paths that use the
680 678
         :meth:`django.http.HttpRequest.is_ajax()` method.
681 679
 
682 680
         .. versionadded:: 1.1
@@ -1533,7 +1531,7 @@ set up, execute and tear down the test suite.
1533 1531
 .. method:: DjangoTestSuiteRunner.suite_result(suite, result, **kwargs)
1534 1532
 
1535 1533
     Computes and returns a return code based on a test suite, and the result
1536  
-	from that test suite.
  1534
+    from that test suite.
1537 1535
 
1538 1536
 
1539 1537
 Testing utilities

0 notes on commit 0866dc1

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