Commits

Danilo Bellini committed b2108fd

zero to many doctests from module instead of one

Comments (0)

Files changed (2)

_pytest/doctest.py

         self.reprlocation.toterminal(tw)
 
 class DoctestItem(pytest.Item):
+    def __init__(self, name, parent, runner=None, dtest=None):
+        super(DoctestItem, self).__init__(name, parent)
+        self.runner = runner
+        self.dtest = dtest
+
+    def runtest(self):
+        self.runner.run(self.dtest)
+
     def repr_failure(self, excinfo):
         doctest = py.std.doctest
         if excinfo.errisinstance((doctest.DocTestFailure,
             return super(DoctestItem, self).repr_failure(excinfo)
 
     def reportinfo(self):
-        return self.fspath, None, "[doctest]"
+        return self.fspath, None, "[doctest] %s" % self.name
 
 class DoctestTextfile(DoctestItem, pytest.File):
     def runtest(self):
             extraglobs=dict(getfixture=fixture_request.getfuncargvalue),
             raise_on_error=True, verbose=0)
 
-class DoctestModule(DoctestItem, pytest.File):
-    def runtest(self):
+class DoctestModule(pytest.File):
+    def collect(self):
         doctest = py.std.doctest
         if self.fspath.basename == "conftest.py":
             module = self.config._conftest.importconftest(self.fspath)
         self.funcargs = {}
         self._fixtureinfo = FuncFixtureInfo((), [], {})
         fixture_request = FixtureRequest(self)
-        failed, tot = doctest.testmod(
-            module, raise_on_error=True, verbose=0,
-            extraglobs=dict(getfixture=fixture_request.getfuncargvalue),
-            optionflags=doctest.ELLIPSIS)
+        doctest_globals = dict(getfixture=fixture_request.getfuncargvalue)
+        # uses internal doctest module parsing mechanism
+        finder = doctest.DocTestFinder()
+        runner = doctest.DebugRunner(verbose=0, optionflags=doctest.ELLIPSIS)
+        for test in finder.find(module, module.__name__,
+                                extraglobs=doctest_globals):
+            if test.examples: # skip empty doctests
+                yield DoctestItem(test.name, self, runner, test)

testing/test_doctest.py

-from _pytest.doctest import DoctestModule, DoctestTextfile
+from _pytest.doctest import DoctestItem, DoctestModule, DoctestTextfile
 import py, pytest
 
 class TestDoctests:
         items, reprec = testdir.inline_genitems(w)
         assert len(items) == 1
 
-    def test_collect_module(self, testdir):
+    def test_collect_module_empty(self, testdir):
         path = testdir.makepyfile(whatever="#")
         for p in (path, testdir.tmpdir):
             items, reprec = testdir.inline_genitems(p,
                 '--doctest-modules')
+            assert len(items) == 0
+
+    def test_collect_module_single_modulelevel_doctest(self, testdir):
+        path = testdir.makepyfile(whatever='""">>> pass"""')
+        for p in (path, testdir.tmpdir):
+            items, reprec = testdir.inline_genitems(p,
+                '--doctest-modules')
             assert len(items) == 1
-            assert isinstance(items[0], DoctestModule)
+            assert isinstance(items[0], DoctestItem)
+            assert isinstance(items[0].parent, DoctestModule)
+
+    def test_collect_module_two_doctest_one_modulelevel(self, testdir):
+        path = testdir.makepyfile(whatever="""
+            '>>> x = None'
+            def my_func():
+                ">>> magic = 42 "
+        """)
+        for p in (path, testdir.tmpdir):
+            items, reprec = testdir.inline_genitems(p,
+                '--doctest-modules')
+            assert len(items) == 2
+            assert isinstance(items[0], DoctestItem)
+            assert isinstance(items[1], DoctestItem)
+            assert isinstance(items[0].parent, DoctestModule)
+            assert items[0].parent is items[1].parent
+
+    def test_collect_module_two_doctest_no_modulelevel(self, testdir):
+        path = testdir.makepyfile(whatever="""
+            '# Empty'
+            def my_func():
+                ">>> magic = 42 "
+            def unuseful():
+                '''
+                # This is a function
+                # >>> # it doesn't have any doctest
+                '''
+            def another():
+                '''
+                # This is another function
+                >>> import os # this one does have a doctest
+                '''
+        """)
+        for p in (path, testdir.tmpdir):
+            items, reprec = testdir.inline_genitems(p,
+                '--doctest-modules')
+            assert len(items) == 2
+            assert isinstance(items[0], DoctestItem)
+            assert isinstance(items[1], DoctestItem)
+            assert isinstance(items[0].parent, DoctestModule)
+            assert items[0].parent is items[1].parent
 
     def test_simple_doctestfile(self, testdir):
         p = testdir.maketxtfile(test_doc="""
         """)
         reprec = testdir.inline_run(p, "--doctest-modules")
         reprec.assertoutcome(passed=1)
+
+    def test_doctestmodule_three_tests(self, testdir):
+        p = testdir.makepyfile("""
+            '''
+            >>> dir = getfixture('tmpdir')
+            >>> type(dir).__name__
+            'LocalPath'
+            '''
+            def my_func():
+                '''
+                >>> magic = 42
+                >>> magic - 42
+                0
+                '''
+            def unuseful():
+                pass
+            def another():
+                '''
+                >>> import os
+                >>> os is os
+                True
+                '''
+        """)
+        reprec = testdir.inline_run(p, "--doctest-modules")
+        reprec.assertoutcome(passed=3)
+
+    def test_doctestmodule_two_tests_one_fail(self, testdir):
+        p = testdir.makepyfile("""
+            class MyClass:
+                def bad_meth(self):
+                    '''
+                    >>> magic = 42
+                    >>> magic
+                    0
+                    '''
+                def nice_meth(self):
+                    '''
+                    >>> magic = 42
+                    >>> magic - 42
+                    0
+                    '''
+        """)
+        reprec = testdir.inline_run(p, "--doctest-modules")
+        reprec.assertoutcome(failed=1, passed=1)