[py-dev] more doctest...

Ian Bicking ianb at colorstudy.com
Sun Nov 28 09:25:39 CET 2004


Following up on my other doctest email, here's a slightly better 
technique I'm using:

from test_fixture import DoctestCollector
import some_module

collect_doctest = DoctestCollector(some_module)


Then I added something to py.test.collect.Module:

     def collect_collectors(self, extpy):
         if extpy.check(basestarts='collect_'):
             iter = extpy.resolve()(self.extpy)
             for item in iter:
                 yield item


And this is the new test_fixture.py, with just a small addition to 
DoctestCollector (__init__ and __call__), though extpy starts to feel 
pretty extraneous:

class DoctestCollector(PyCollector):

     def __init__(self, extpy_or_module):
         if isinstance(extpy_or_module, types.ModuleType):
             self.module = extpy_or_module
             self.extpy = None
         else:
             self.extpy = extpy_or_module
             self.module = self.extpy.getpymodule()

     def __call__(self, extpy):
         # we throw it away, because this has been set up to explicitly
         # check another module; maybe this isn't clean
         if self.extpy is None:
             self.extpy = extpy
         return self

     def __iter__(self):
         finder = doctest.DocTestFinder()
         tests = finder.find(self.module)
         for t in tests:
             yield DoctestItem(self.extpy, t)

class DoctestItem(DoctestCollector.Item):

     def __init__(self, extpy, doctestitem, *args):
         self.extpy = extpy
         self.doctestitem = doctestitem
         self.name = extpy.basename
         self.args = args

     def execute(self, driver):
         runner = doctest.DocTestRunner()
         driver.setup_path(self.extpy)
         target, teardown = driver.setup_method(self.extpy)
         try:
             (failed, tried), run_output = capture_stdout(runner.run, 
self.doctestitem)
             if failed:
                 raise self.Failed(msg=run_output, tbindex=-2)

         finally:
             if teardown:
                 teardown(target)

def capture_stdout(func, *args, **kw):
     newstdout = StringIO()
     oldstdout = sys.stdout
     sys.stdout = newstdout
     try:
         result = func(*args, **kw)
     finally:
         sys.stdout = oldstdout
     return result, newstdout.getvalue()


-- 
Ian Bicking  /  ianb at colorstudy.com  / http://blog.ianbicking.org



More information about the Pytest-dev mailing list