1 # Copyright (c) 2004 Canonical Limited
2 # Author: Robert Collins <robert.collins@canonical.com>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 class LogCollector(logging.Handler):
26 logging.Handler.__init__(self)
28 def emit(self, record):
29 self.records.append(record.getMessage())
32 def makeCollectingLogger():
33 """I make a logger instance that collects its logs for programmatic analysis
34 -> (logger, collector)"""
35 logger=logging.Logger("collector")
36 handler=LogCollector()
37 handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
38 logger.addHandler(handler)
39 return logger, handler
42 def visitTests(suite, visitor):
43 """A foreign method for visiting the tests in a test suite."""
44 for test in suite._tests:
45 #Abusing types to avoid monkey patching unittest.TestCase.
46 # Maybe that would be better?
49 except AttributeError:
50 if isinstance(test, unittest.TestCase):
51 visitor.visitCase(test)
52 elif isinstance(test, unittest.TestSuite):
53 visitor.visitSuite(test)
54 visitTests(test, visitor)
56 print "unvisitable non-unittest.TestCase element %r (%r)" % (test, test.__class__)
59 class TestSuite(unittest.TestSuite):
60 """I am an extended TestSuite with a visitor interface.
61 This is primarily to allow filtering of tests - and suites or
62 more in the future. An iterator of just tests wouldn't scale..."""
64 def visit(self, visitor):
65 """visit the composite. Visiting is depth-first.
66 current callbacks are visitSuite and visitCase."""
67 visitor.visitSuite(self)
68 visitTests(self, visitor)
71 class TestLoader(unittest.TestLoader):
72 """Custome TestLoader to set the right TestSuite class."""
73 suiteClass = TestSuite
75 class TestVisitor(object):
76 """A visitor for Tests"""
77 def visitSuite(self, aTestSuite):
79 def visitCase(self, aTestCase):