[py-dev] running doctest-based tests

David Stanek dstanek at dstanek.com
Thu Jun 9 11:33:14 CEST 2005


> After studying the code I found out that the way failures are reported is
> hardcoded in repr_failure method in TerminalSession. Even tkinter backend
> uses it.
>
> My situation requires a custom representation of a failure instead of
> plain
> traceback.
>
> A solution might be to abstract the way failures are reported by moving
> this
> responsibility from TerminalSession to the Failure class, for example.
> After
> all, this even seems logical - different kind of failures may require
> different representations and a Failure class is a natural place to hold
> this information.  OTOH, the session classes *are* responsible for an
> actual
> failure's representation: be it console output, graphical window or
> network
> socket.
>
> A method to the Failure class will be added that will return a suitable
> string representation of a failure. Failure class itself will provide
> default implementation that will yield formatted traceback.  This way I
> could subclass Failure that will yield doctest output instead of
> traceback.
>
> What would you say?

I made a couple of changes to your conftest.py. The original one did not
run under my version of Python. The classes being used were added in 2.4.
Please see if that works for you. Later today I'll investigate Holger's
suggestion.

David

::::::conftest.py::::::
import py
import doctest


class Directory(py.test.collect.Directory):

    def buildname2items(self):
        # just let our base class do its building
        d = super(Directory, self).buildname2items()

        # let's look for doctests ...
        for fn in self.fspath.listdir('*.py'):
            if fn.basename in d or fn.basename == 'conftest.py':
                continue
            # we have a candidate for doctests
            #if not isdoctestmodule(fn): # if possible to implement that
            #    continue
            module = DoctestModule(fn, parent=self)
            d[fn.basename] = module
        return d


class DoctestModule(py.test.collect.Module):

    def funcnamefilter(self, name):
        return True

    def classnamefilter(self, name):
        return True

    def buildname2items(self):
        d = {}
        doctests = doctest._find_tests(self.obj)
        tester = doctest.Tester(mod=self.obj, verbose=0)
        for (testname, docstring, filename, lineno) in doctests:
            d[testname] = DoctestItem(testname, docstring, tester, self)
        return d


class DoctestItem(py.test.Item):

    def __init__(self, name, test, tester, parent):
        py.test.Item.__init__(self, name, parent)
        self.test = test
        self.tester = tester

    def run(self):
        failed, tried = self.tester.runstring(self.test, self.name)
        if failed:
            raise self.Failed('ooops')




More information about the py-dev mailing list