TestUtil.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. # Copyright (c) 2004 Canonical Limited
  2. # Author: Robert Collins <robert.collins@canonical.com>
  3. #
  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.
  8. #
  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.
  13. #
  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
  17. #
  18. import sys
  19. import logging
  20. import unittest
  21. class LogCollector(logging.Handler):
  22. def __init__(self):
  23. logging.Handler.__init__(self)
  24. self.records=[]
  25. def emit(self, record):
  26. self.records.append(record.getMessage())
  27. def makeCollectingLogger():
  28. """I make a logger instance that collects its logs for programmatic analysis
  29. -> (logger, collector)"""
  30. logger=logging.Logger("collector")
  31. handler=LogCollector()
  32. handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
  33. logger.addHandler(handler)
  34. return logger, handler
  35. def visitTests(suite, visitor):
  36. """A foreign method for visiting the tests in a test suite."""
  37. if isinstance(suite, unittest.TestCase):
  38. visitor.visitCase(suite)
  39. return
  40. for test in suite._tests:
  41. #Abusing types to avoid monkey patching unittest.TestCase.
  42. # Maybe that would be better?
  43. try:
  44. test.visit(visitor)
  45. except AttributeError:
  46. if isinstance(test, unittest.TestCase):
  47. visitor.visitCase(test)
  48. elif isinstance(test, unittest.TestSuite):
  49. visitor.visitSuite(test)
  50. visitTests(test, visitor)
  51. else:
  52. print("unvisitable non-unittest.TestCase element %r (%r)" % (test, test.__class__))
  53. class TestSuite(unittest.TestSuite):
  54. """I am an extended TestSuite with a visitor interface.
  55. This is primarily to allow filtering of tests - and suites or
  56. more in the future. An iterator of just tests wouldn't scale..."""
  57. def visit(self, visitor):
  58. """visit the composite. Visiting is depth-first.
  59. current callbacks are visitSuite and visitCase."""
  60. visitor.visitSuite(self)
  61. visitTests(self, visitor)
  62. class TestLoader(unittest.TestLoader):
  63. """Custome TestLoader to set the right TestSuite class."""
  64. suiteClass = TestSuite
  65. class TestVisitor(object):
  66. """A visitor for Tests"""
  67. def visitSuite(self, aTestSuite):
  68. pass
  69. def visitCase(self, aTestCase):
  70. pass