Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #6364 -- Added the ability to run individual doctests.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12364 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 84599495a0332925ceae8e7902eb4cc8bfb3e635 1 parent e0dd8a9
Russell Keith-Magee authored February 01, 2010
52  django/test/simple.py
@@ -133,24 +133,58 @@ def build_test(label):
133 133
     if len(parts) < 2 or len(parts) > 3:
134 134
         raise ValueError("Test label '%s' should be of the form app.TestCase or app.TestCase.test_method" % label)
135 135
 
  136
+    #
  137
+    # First, look for TestCase instances with a name that matches
  138
+    #
136 139
     app_module = get_app(parts[0])
  140
+    test_module = get_tests(app_module)
137 141
     TestClass = getattr(app_module, parts[1], None)
138 142
 
139 143
     # Couldn't find the test class in models.py; look in tests.py
140 144
     if TestClass is None:
141  
-        test_module = get_tests(app_module)
142 145
         if test_module:
143 146
             TestClass = getattr(test_module, parts[1], None)
144 147
 
145  
-    if len(parts) == 2: # label is app.TestClass
  148
+    try:
  149
+        if issubclass(TestClass, unittest.TestCase):
  150
+            print 'is a test case'
  151
+            if len(parts) == 2: # label is app.TestClass
  152
+                try:
  153
+                    return unittest.TestLoader().loadTestsFromTestCase(TestClass)
  154
+                except TypeError:
  155
+                    raise ValueError("Test label '%s' does not refer to a test class" % label)
  156
+            else: # label is app.TestClass.test_method
  157
+                return TestClass(parts[2])
  158
+    except TypeError:
  159
+        # TestClass isn't a TestClass - it must be a method or normal class
  160
+        pass
  161
+
  162
+    #
  163
+    # If there isn't a TestCase, look for a doctest that matches
  164
+    #
  165
+    tests = []
  166
+    for module in app_module, test_module:
146 167
         try:
147  
-            return unittest.TestLoader().loadTestsFromTestCase(TestClass)
148  
-        except TypeError:
149  
-            raise ValueError("Test label '%s' does not refer to a test class" % label)
150  
-    else: # label is app.TestClass.test_method
151  
-        if not TestClass:
152  
-            raise ValueError("Test label '%s' does not refer to a test class" % label)
153  
-        return TestClass(parts[2])
  168
+            doctests = doctest.DocTestSuite(module,
  169
+                                            checker=doctestOutputChecker,
  170
+                                            runner=DocTestRunner)
  171
+            # Now iterate over the suite, looking for doctests whose name
  172
+            # matches the pattern that was given
  173
+            for test in doctests:
  174
+                if test._dt_test.name in (
  175
+                        '%s.%s' % (module.__name__, '.'.join(parts[1:])),
  176
+                        '%s.__test__.%s' % (module.__name__, '.'.join(parts[1:]))):
  177
+                    tests.append(test)
  178
+        except ValueError:
  179
+            # No doctests found.
  180
+            pass
  181
+
  182
+    # If no tests were found, then we were given a bad test label.
  183
+    if not tests:
  184
+        raise ValueError("Test label '%s' does not refer to a test" % label)
  185
+
  186
+    # Construct a suite out of the tests that matched.
  187
+    return unittest.TestSuite(tests)
154 188
 
155 189
 # Python 2.3 compatibility: TestSuites were made iterable in 2.4.
156 190
 # We need to iterate over them, so we add the missing method when
34  docs/topics/testing.txt
@@ -261,20 +261,40 @@ Note that we used ``animals``, not ``myproject.animals``.
261 261
 .. versionadded:: 1.0
262 262
    You can now choose which test to run.
263 263
 
264  
-If you use unit tests, as opposed to
265  
-doctests, you can be even *more* specific in choosing which tests to execute.
266  
-To run a single test case in an application (for example, the
267  
-``AnimalTestCase`` described in the "Writing unit tests" section), add the
268  
-name of the test case to the label on the command line::
  264
+You can be even *more* specific by naming an individual test case. To
  265
+run a single test case in an application (for example, the
  266
+``AnimalTestCase`` described in the "Writing unit tests" section), add
  267
+the name of the test case to the label on the command line::
269 268
 
270 269
     $ ./manage.py test animals.AnimalTestCase
271 270
 
272  
-And it gets even more granular than that! To run a *single* test method inside
273  
-a test case, add the name of the test method to the label::
  271
+And it gets even more granular than that! To run a *single* test
  272
+method inside a test case, add the name of the test method to the
  273
+label::
274 274
 
275 275
     $ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
276 276
 
277 277
 .. versionadded:: 1.2
  278
+   The ability to select individual doctests was added.
  279
+
  280
+You can use the same rules if you're using doctests. Django will use the
  281
+test label as a path to the test method or class that you want to run.
  282
+If your ``models.py`` or ``tests.py`` has a function with a doctest, or
  283
+class with a class-level doctest, you can invoke that test by appending the
  284
+name of the test method or class to the label::
  285
+
  286
+    $ ./manage.py test animals.classify
  287
+
  288
+If you want to run the doctest for a specific method in a class, add the
  289
+name of the method to the label::
  290
+
  291
+    $ ./manage.py test animals.Classifier.run
  292
+
  293
+If you're using a ``__test__`` dictionary to specify doctests for a
  294
+module, Django will use the label as a key in the ``__test__`` dictionary
  295
+for defined in ``models.py`` and ``tests.py``.
  296
+
  297
+.. versionadded:: 1.2
278 298
    You can now trigger a graceful exit from a test run by pressing ``Ctrl-C``.
279 299
 
280 300
 If you press ``Ctrl-C`` while the tests are running, the test runner will

0 notes on commit 8459949

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