python-2.5.2/win32/Lib/unittest.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 #!/usr/bin/env python
       
     2 '''
       
     3 Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
       
     4 Smalltalk testing framework.
       
     5 
       
     6 This module contains the core framework classes that form the basis of
       
     7 specific test cases and suites (TestCase, TestSuite etc.), and also a
       
     8 text-based utility class for running the tests and reporting the results
       
     9  (TextTestRunner).
       
    10 
       
    11 Simple usage:
       
    12 
       
    13     import unittest
       
    14 
       
    15     class IntegerArithmenticTestCase(unittest.TestCase):
       
    16         def testAdd(self):  ## test method names begin 'test*'
       
    17             self.assertEquals((1 + 2), 3)
       
    18             self.assertEquals(0 + 1, 1)
       
    19         def testMultiply(self):
       
    20             self.assertEquals((0 * 10), 0)
       
    21             self.assertEquals((5 * 8), 40)
       
    22 
       
    23     if __name__ == '__main__':
       
    24         unittest.main()
       
    25 
       
    26 Further information is available in the bundled documentation, and from
       
    27 
       
    28   http://pyunit.sourceforge.net/
       
    29 
       
    30 Copyright (c) 1999-2003 Steve Purcell
       
    31 This module is free software, and you may redistribute it and/or modify
       
    32 it under the same terms as Python itself, so long as this copyright message
       
    33 and disclaimer are retained in their original form.
       
    34 
       
    35 IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
       
    36 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
       
    37 THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
       
    38 DAMAGE.
       
    39 
       
    40 THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
       
    41 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
       
    42 PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
       
    43 AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
       
    44 SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
       
    45 '''
       
    46 
       
    47 __author__ = "Steve Purcell"
       
    48 __email__ = "stephen_purcell at yahoo dot com"
       
    49 __version__ = "#Revision: 1.63 $"[11:-2]
       
    50 
       
    51 import time
       
    52 import sys
       
    53 import traceback
       
    54 import os
       
    55 import types
       
    56 
       
    57 ##############################################################################
       
    58 # Exported classes and functions
       
    59 ##############################################################################
       
    60 __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
       
    61            'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
       
    62 
       
    63 # Expose obsolete functions for backwards compatibility
       
    64 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
       
    65 
       
    66 
       
    67 ##############################################################################
       
    68 # Backward compatibility
       
    69 ##############################################################################
       
    70 if sys.version_info[:2] < (2, 2):
       
    71     False, True = 0, 1
       
    72     def isinstance(obj, clsinfo):
       
    73         import __builtin__
       
    74         if type(clsinfo) in (tuple, list):
       
    75             for cls in clsinfo:
       
    76                 if cls is type: cls = types.ClassType
       
    77                 if __builtin__.isinstance(obj, cls):
       
    78                     return 1
       
    79             return 0
       
    80         else: return __builtin__.isinstance(obj, clsinfo)
       
    81 
       
    82 
       
    83 ##############################################################################
       
    84 # Test framework core
       
    85 ##############################################################################
       
    86 
       
    87 # All classes defined herein are 'new-style' classes, allowing use of 'super()'
       
    88 __metaclass__ = type
       
    89 
       
    90 def _strclass(cls):
       
    91     return "%s.%s" % (cls.__module__, cls.__name__)
       
    92 
       
    93 __unittest = 1
       
    94 
       
    95 class TestResult:
       
    96     """Holder for test result information.
       
    97 
       
    98     Test results are automatically managed by the TestCase and TestSuite
       
    99     classes, and do not need to be explicitly manipulated by writers of tests.
       
   100 
       
   101     Each instance holds the total number of tests run, and collections of
       
   102     failures and errors that occurred among those test runs. The collections
       
   103     contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
       
   104     formatted traceback of the error that occurred.
       
   105     """
       
   106     def __init__(self):
       
   107         self.failures = []
       
   108         self.errors = []
       
   109         self.testsRun = 0
       
   110         self.shouldStop = 0
       
   111 
       
   112     def startTest(self, test):
       
   113         "Called when the given test is about to be run"
       
   114         self.testsRun = self.testsRun + 1
       
   115 
       
   116     def stopTest(self, test):
       
   117         "Called when the given test has been run"
       
   118         pass
       
   119 
       
   120     def addError(self, test, err):
       
   121         """Called when an error has occurred. 'err' is a tuple of values as
       
   122         returned by sys.exc_info().
       
   123         """
       
   124         self.errors.append((test, self._exc_info_to_string(err, test)))
       
   125 
       
   126     def addFailure(self, test, err):
       
   127         """Called when an error has occurred. 'err' is a tuple of values as
       
   128         returned by sys.exc_info()."""
       
   129         self.failures.append((test, self._exc_info_to_string(err, test)))
       
   130 
       
   131     def addSuccess(self, test):
       
   132         "Called when a test has completed successfully"
       
   133         pass
       
   134 
       
   135     def wasSuccessful(self):
       
   136         "Tells whether or not this result was a success"
       
   137         return len(self.failures) == len(self.errors) == 0
       
   138 
       
   139     def stop(self):
       
   140         "Indicates that the tests should be aborted"
       
   141         self.shouldStop = True
       
   142 
       
   143     def _exc_info_to_string(self, err, test):
       
   144         """Converts a sys.exc_info()-style tuple of values into a string."""
       
   145         exctype, value, tb = err
       
   146         # Skip test runner traceback levels
       
   147         while tb and self._is_relevant_tb_level(tb):
       
   148             tb = tb.tb_next
       
   149         if exctype is test.failureException:
       
   150             # Skip assert*() traceback levels
       
   151             length = self._count_relevant_tb_levels(tb)
       
   152             return ''.join(traceback.format_exception(exctype, value, tb, length))
       
   153         return ''.join(traceback.format_exception(exctype, value, tb))
       
   154 
       
   155     def _is_relevant_tb_level(self, tb):
       
   156         return tb.tb_frame.f_globals.has_key('__unittest')
       
   157 
       
   158     def _count_relevant_tb_levels(self, tb):
       
   159         length = 0
       
   160         while tb and not self._is_relevant_tb_level(tb):
       
   161             length += 1
       
   162             tb = tb.tb_next
       
   163         return length
       
   164 
       
   165     def __repr__(self):
       
   166         return "<%s run=%i errors=%i failures=%i>" % \
       
   167                (_strclass(self.__class__), self.testsRun, len(self.errors),
       
   168                 len(self.failures))
       
   169 
       
   170 class TestCase:
       
   171     """A class whose instances are single test cases.
       
   172 
       
   173     By default, the test code itself should be placed in a method named
       
   174     'runTest'.
       
   175 
       
   176     If the fixture may be used for many test cases, create as
       
   177     many test methods as are needed. When instantiating such a TestCase
       
   178     subclass, specify in the constructor arguments the name of the test method
       
   179     that the instance is to execute.
       
   180 
       
   181     Test authors should subclass TestCase for their own tests. Construction
       
   182     and deconstruction of the test's environment ('fixture') can be
       
   183     implemented by overriding the 'setUp' and 'tearDown' methods respectively.
       
   184 
       
   185     If it is necessary to override the __init__ method, the base class
       
   186     __init__ method must always be called. It is important that subclasses
       
   187     should not change the signature of their __init__ method, since instances
       
   188     of the classes are instantiated automatically by parts of the framework
       
   189     in order to be run.
       
   190     """
       
   191 
       
   192     # This attribute determines which exception will be raised when
       
   193     # the instance's assertion methods fail; test methods raising this
       
   194     # exception will be deemed to have 'failed' rather than 'errored'
       
   195 
       
   196     failureException = AssertionError
       
   197 
       
   198     def __init__(self, methodName='runTest'):
       
   199         """Create an instance of the class that will use the named test
       
   200            method when executed. Raises a ValueError if the instance does
       
   201            not have a method with the specified name.
       
   202         """
       
   203         try:
       
   204             self._testMethodName = methodName
       
   205             testMethod = getattr(self, methodName)
       
   206             self._testMethodDoc = testMethod.__doc__
       
   207         except AttributeError:
       
   208             raise ValueError, "no such test method in %s: %s" % \
       
   209                   (self.__class__, methodName)
       
   210 
       
   211     def setUp(self):
       
   212         "Hook method for setting up the test fixture before exercising it."
       
   213         pass
       
   214 
       
   215     def tearDown(self):
       
   216         "Hook method for deconstructing the test fixture after testing it."
       
   217         pass
       
   218 
       
   219     def countTestCases(self):
       
   220         return 1
       
   221 
       
   222     def defaultTestResult(self):
       
   223         return TestResult()
       
   224 
       
   225     def shortDescription(self):
       
   226         """Returns a one-line description of the test, or None if no
       
   227         description has been provided.
       
   228 
       
   229         The default implementation of this method returns the first line of
       
   230         the specified test method's docstring.
       
   231         """
       
   232         doc = self._testMethodDoc
       
   233         return doc and doc.split("\n")[0].strip() or None
       
   234 
       
   235     def id(self):
       
   236         return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
       
   237 
       
   238     def __str__(self):
       
   239         return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
       
   240 
       
   241     def __repr__(self):
       
   242         return "<%s testMethod=%s>" % \
       
   243                (_strclass(self.__class__), self._testMethodName)
       
   244 
       
   245     def run(self, result=None):
       
   246         if result is None: result = self.defaultTestResult()
       
   247         result.startTest(self)
       
   248         testMethod = getattr(self, self._testMethodName)
       
   249         try:
       
   250             try:
       
   251                 self.setUp()
       
   252             except KeyboardInterrupt:
       
   253                 raise
       
   254             except:
       
   255                 result.addError(self, self._exc_info())
       
   256                 return
       
   257 
       
   258             ok = False
       
   259             try:
       
   260                 testMethod()
       
   261                 ok = True
       
   262             except self.failureException:
       
   263                 result.addFailure(self, self._exc_info())
       
   264             except KeyboardInterrupt:
       
   265                 raise
       
   266             except:
       
   267                 result.addError(self, self._exc_info())
       
   268 
       
   269             try:
       
   270                 self.tearDown()
       
   271             except KeyboardInterrupt:
       
   272                 raise
       
   273             except:
       
   274                 result.addError(self, self._exc_info())
       
   275                 ok = False
       
   276             if ok: result.addSuccess(self)
       
   277         finally:
       
   278             result.stopTest(self)
       
   279 
       
   280     def __call__(self, *args, **kwds):
       
   281         return self.run(*args, **kwds)
       
   282 
       
   283     def debug(self):
       
   284         """Run the test without collecting errors in a TestResult"""
       
   285         self.setUp()
       
   286         getattr(self, self._testMethodName)()
       
   287         self.tearDown()
       
   288 
       
   289     def _exc_info(self):
       
   290         """Return a version of sys.exc_info() with the traceback frame
       
   291            minimised; usually the top level of the traceback frame is not
       
   292            needed.
       
   293         """
       
   294         exctype, excvalue, tb = sys.exc_info()
       
   295         if sys.platform[:4] == 'java': ## tracebacks look different in Jython
       
   296             return (exctype, excvalue, tb)
       
   297         return (exctype, excvalue, tb)
       
   298 
       
   299     def fail(self, msg=None):
       
   300         """Fail immediately, with the given message."""
       
   301         raise self.failureException, msg
       
   302 
       
   303     def failIf(self, expr, msg=None):
       
   304         "Fail the test if the expression is true."
       
   305         if expr: raise self.failureException, msg
       
   306 
       
   307     def failUnless(self, expr, msg=None):
       
   308         """Fail the test unless the expression is true."""
       
   309         if not expr: raise self.failureException, msg
       
   310 
       
   311     def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
       
   312         """Fail unless an exception of class excClass is thrown
       
   313            by callableObj when invoked with arguments args and keyword
       
   314            arguments kwargs. If a different type of exception is
       
   315            thrown, it will not be caught, and the test case will be
       
   316            deemed to have suffered an error, exactly as for an
       
   317            unexpected exception.
       
   318         """
       
   319         try:
       
   320             callableObj(*args, **kwargs)
       
   321         except excClass:
       
   322             return
       
   323         else:
       
   324             if hasattr(excClass,'__name__'): excName = excClass.__name__
       
   325             else: excName = str(excClass)
       
   326             raise self.failureException, "%s not raised" % excName
       
   327 
       
   328     def failUnlessEqual(self, first, second, msg=None):
       
   329         """Fail if the two objects are unequal as determined by the '=='
       
   330            operator.
       
   331         """
       
   332         if not first == second:
       
   333             raise self.failureException, \
       
   334                   (msg or '%r != %r' % (first, second))
       
   335 
       
   336     def failIfEqual(self, first, second, msg=None):
       
   337         """Fail if the two objects are equal as determined by the '=='
       
   338            operator.
       
   339         """
       
   340         if first == second:
       
   341             raise self.failureException, \
       
   342                   (msg or '%r == %r' % (first, second))
       
   343 
       
   344     def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
       
   345         """Fail if the two objects are unequal as determined by their
       
   346            difference rounded to the given number of decimal places
       
   347            (default 7) and comparing to zero.
       
   348 
       
   349            Note that decimal places (from zero) are usually not the same
       
   350            as significant digits (measured from the most signficant digit).
       
   351         """
       
   352         if round(second-first, places) != 0:
       
   353             raise self.failureException, \
       
   354                   (msg or '%r != %r within %r places' % (first, second, places))
       
   355 
       
   356     def failIfAlmostEqual(self, first, second, places=7, msg=None):
       
   357         """Fail if the two objects are equal as determined by their
       
   358            difference rounded to the given number of decimal places
       
   359            (default 7) and comparing to zero.
       
   360 
       
   361            Note that decimal places (from zero) are usually not the same
       
   362            as significant digits (measured from the most signficant digit).
       
   363         """
       
   364         if round(second-first, places) == 0:
       
   365             raise self.failureException, \
       
   366                   (msg or '%r == %r within %r places' % (first, second, places))
       
   367 
       
   368     # Synonyms for assertion methods
       
   369 
       
   370     assertEqual = assertEquals = failUnlessEqual
       
   371 
       
   372     assertNotEqual = assertNotEquals = failIfEqual
       
   373 
       
   374     assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
       
   375 
       
   376     assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
       
   377 
       
   378     assertRaises = failUnlessRaises
       
   379 
       
   380     assert_ = assertTrue = failUnless
       
   381 
       
   382     assertFalse = failIf
       
   383 
       
   384 
       
   385 
       
   386 class TestSuite:
       
   387     """A test suite is a composite test consisting of a number of TestCases.
       
   388 
       
   389     For use, create an instance of TestSuite, then add test case instances.
       
   390     When all tests have been added, the suite can be passed to a test
       
   391     runner, such as TextTestRunner. It will run the individual test cases
       
   392     in the order in which they were added, aggregating the results. When
       
   393     subclassing, do not forget to call the base class constructor.
       
   394     """
       
   395     def __init__(self, tests=()):
       
   396         self._tests = []
       
   397         self.addTests(tests)
       
   398 
       
   399     def __repr__(self):
       
   400         return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
       
   401 
       
   402     __str__ = __repr__
       
   403 
       
   404     def __iter__(self):
       
   405         return iter(self._tests)
       
   406 
       
   407     def countTestCases(self):
       
   408         cases = 0
       
   409         for test in self._tests:
       
   410             cases += test.countTestCases()
       
   411         return cases
       
   412 
       
   413     def addTest(self, test):
       
   414         # sanity checks
       
   415         if not callable(test):
       
   416             raise TypeError("the test to add must be callable")
       
   417         if (isinstance(test, (type, types.ClassType)) and
       
   418             issubclass(test, (TestCase, TestSuite))):
       
   419             raise TypeError("TestCases and TestSuites must be instantiated "
       
   420                             "before passing them to addTest()")
       
   421         self._tests.append(test)
       
   422 
       
   423     def addTests(self, tests):
       
   424         if isinstance(tests, basestring):
       
   425             raise TypeError("tests must be an iterable of tests, not a string")
       
   426         for test in tests:
       
   427             self.addTest(test)
       
   428 
       
   429     def run(self, result):
       
   430         for test in self._tests:
       
   431             if result.shouldStop:
       
   432                 break
       
   433             test(result)
       
   434         return result
       
   435 
       
   436     def __call__(self, *args, **kwds):
       
   437         return self.run(*args, **kwds)
       
   438 
       
   439     def debug(self):
       
   440         """Run the tests without collecting errors in a TestResult"""
       
   441         for test in self._tests: test.debug()
       
   442 
       
   443 
       
   444 class FunctionTestCase(TestCase):
       
   445     """A test case that wraps a test function.
       
   446 
       
   447     This is useful for slipping pre-existing test functions into the
       
   448     PyUnit framework. Optionally, set-up and tidy-up functions can be
       
   449     supplied. As with TestCase, the tidy-up ('tearDown') function will
       
   450     always be called if the set-up ('setUp') function ran successfully.
       
   451     """
       
   452 
       
   453     def __init__(self, testFunc, setUp=None, tearDown=None,
       
   454                  description=None):
       
   455         TestCase.__init__(self)
       
   456         self.__setUpFunc = setUp
       
   457         self.__tearDownFunc = tearDown
       
   458         self.__testFunc = testFunc
       
   459         self.__description = description
       
   460 
       
   461     def setUp(self):
       
   462         if self.__setUpFunc is not None:
       
   463             self.__setUpFunc()
       
   464 
       
   465     def tearDown(self):
       
   466         if self.__tearDownFunc is not None:
       
   467             self.__tearDownFunc()
       
   468 
       
   469     def runTest(self):
       
   470         self.__testFunc()
       
   471 
       
   472     def id(self):
       
   473         return self.__testFunc.__name__
       
   474 
       
   475     def __str__(self):
       
   476         return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
       
   477 
       
   478     def __repr__(self):
       
   479         return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
       
   480 
       
   481     def shortDescription(self):
       
   482         if self.__description is not None: return self.__description
       
   483         doc = self.__testFunc.__doc__
       
   484         return doc and doc.split("\n")[0].strip() or None
       
   485 
       
   486 
       
   487 
       
   488 ##############################################################################
       
   489 # Locating and loading tests
       
   490 ##############################################################################
       
   491 
       
   492 class TestLoader:
       
   493     """This class is responsible for loading tests according to various
       
   494     criteria and returning them wrapped in a Test
       
   495     """
       
   496     testMethodPrefix = 'test'
       
   497     sortTestMethodsUsing = cmp
       
   498     suiteClass = TestSuite
       
   499 
       
   500     def loadTestsFromTestCase(self, testCaseClass):
       
   501         """Return a suite of all tests cases contained in testCaseClass"""
       
   502         if issubclass(testCaseClass, TestSuite):
       
   503             raise TypeError("Test cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?")
       
   504         testCaseNames = self.getTestCaseNames(testCaseClass)
       
   505         if not testCaseNames and hasattr(testCaseClass, 'runTest'):
       
   506             testCaseNames = ['runTest']
       
   507         return self.suiteClass(map(testCaseClass, testCaseNames))
       
   508 
       
   509     def loadTestsFromModule(self, module):
       
   510         """Return a suite of all tests cases contained in the given module"""
       
   511         tests = []
       
   512         for name in dir(module):
       
   513             obj = getattr(module, name)
       
   514             if (isinstance(obj, (type, types.ClassType)) and
       
   515                 issubclass(obj, TestCase)):
       
   516                 tests.append(self.loadTestsFromTestCase(obj))
       
   517         return self.suiteClass(tests)
       
   518 
       
   519     def loadTestsFromName(self, name, module=None):
       
   520         """Return a suite of all tests cases given a string specifier.
       
   521 
       
   522         The name may resolve either to a module, a test case class, a
       
   523         test method within a test case class, or a callable object which
       
   524         returns a TestCase or TestSuite instance.
       
   525 
       
   526         The method optionally resolves the names relative to a given module.
       
   527         """
       
   528         parts = name.split('.')
       
   529         if module is None:
       
   530             parts_copy = parts[:]
       
   531             while parts_copy:
       
   532                 try:
       
   533                     module = __import__('.'.join(parts_copy))
       
   534                     break
       
   535                 except ImportError:
       
   536                     del parts_copy[-1]
       
   537                     if not parts_copy: raise
       
   538             parts = parts[1:]
       
   539         obj = module
       
   540         for part in parts:
       
   541             parent, obj = obj, getattr(obj, part)
       
   542 
       
   543         if type(obj) == types.ModuleType:
       
   544             return self.loadTestsFromModule(obj)
       
   545         elif (isinstance(obj, (type, types.ClassType)) and
       
   546               issubclass(obj, TestCase)):
       
   547             return self.loadTestsFromTestCase(obj)
       
   548         elif type(obj) == types.UnboundMethodType:
       
   549             return parent(obj.__name__)
       
   550         elif isinstance(obj, TestSuite):
       
   551             return obj
       
   552         elif callable(obj):
       
   553             test = obj()
       
   554             if not isinstance(test, (TestCase, TestSuite)):
       
   555                 raise ValueError, \
       
   556                       "calling %s returned %s, not a test" % (obj,test)
       
   557             return test
       
   558         else:
       
   559             raise ValueError, "don't know how to make test from: %s" % obj
       
   560 
       
   561     def loadTestsFromNames(self, names, module=None):
       
   562         """Return a suite of all tests cases found using the given sequence
       
   563         of string specifiers. See 'loadTestsFromName()'.
       
   564         """
       
   565         suites = [self.loadTestsFromName(name, module) for name in names]
       
   566         return self.suiteClass(suites)
       
   567 
       
   568     def getTestCaseNames(self, testCaseClass):
       
   569         """Return a sorted sequence of method names found within testCaseClass
       
   570         """
       
   571         def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix):
       
   572             return attrname.startswith(prefix) and callable(getattr(testCaseClass, attrname))
       
   573         testFnNames = filter(isTestMethod, dir(testCaseClass))
       
   574         for baseclass in testCaseClass.__bases__:
       
   575             for testFnName in self.getTestCaseNames(baseclass):
       
   576                 if testFnName not in testFnNames:  # handle overridden methods
       
   577                     testFnNames.append(testFnName)
       
   578         if self.sortTestMethodsUsing:
       
   579             testFnNames.sort(self.sortTestMethodsUsing)
       
   580         return testFnNames
       
   581 
       
   582 
       
   583 
       
   584 defaultTestLoader = TestLoader()
       
   585 
       
   586 
       
   587 ##############################################################################
       
   588 # Patches for old functions: these functions should be considered obsolete
       
   589 ##############################################################################
       
   590 
       
   591 def _makeLoader(prefix, sortUsing, suiteClass=None):
       
   592     loader = TestLoader()
       
   593     loader.sortTestMethodsUsing = sortUsing
       
   594     loader.testMethodPrefix = prefix
       
   595     if suiteClass: loader.suiteClass = suiteClass
       
   596     return loader
       
   597 
       
   598 def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
       
   599     return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
       
   600 
       
   601 def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
       
   602     return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
       
   603 
       
   604 def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
       
   605     return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
       
   606 
       
   607 
       
   608 ##############################################################################
       
   609 # Text UI
       
   610 ##############################################################################
       
   611 
       
   612 class _WritelnDecorator:
       
   613     """Used to decorate file-like objects with a handy 'writeln' method"""
       
   614     def __init__(self,stream):
       
   615         self.stream = stream
       
   616 
       
   617     def __getattr__(self, attr):
       
   618         return getattr(self.stream,attr)
       
   619 
       
   620     def writeln(self, arg=None):
       
   621         if arg: self.write(arg)
       
   622         self.write('\n') # text-mode streams translate to \r\n if needed
       
   623 
       
   624 
       
   625 class _TextTestResult(TestResult):
       
   626     """A test result class that can print formatted text results to a stream.
       
   627 
       
   628     Used by TextTestRunner.
       
   629     """
       
   630     separator1 = '=' * 70
       
   631     separator2 = '-' * 70
       
   632 
       
   633     def __init__(self, stream, descriptions, verbosity):
       
   634         TestResult.__init__(self)
       
   635         self.stream = stream
       
   636         self.showAll = verbosity > 1
       
   637         self.dots = verbosity == 1
       
   638         self.descriptions = descriptions
       
   639 
       
   640     def getDescription(self, test):
       
   641         if self.descriptions:
       
   642             return test.shortDescription() or str(test)
       
   643         else:
       
   644             return str(test)
       
   645 
       
   646     def startTest(self, test):
       
   647         TestResult.startTest(self, test)
       
   648         if self.showAll:
       
   649             self.stream.write(self.getDescription(test))
       
   650             self.stream.write(" ... ")
       
   651 
       
   652     def addSuccess(self, test):
       
   653         TestResult.addSuccess(self, test)
       
   654         if self.showAll:
       
   655             self.stream.writeln("ok")
       
   656         elif self.dots:
       
   657             self.stream.write('.')
       
   658 
       
   659     def addError(self, test, err):
       
   660         TestResult.addError(self, test, err)
       
   661         if self.showAll:
       
   662             self.stream.writeln("ERROR")
       
   663         elif self.dots:
       
   664             self.stream.write('E')
       
   665 
       
   666     def addFailure(self, test, err):
       
   667         TestResult.addFailure(self, test, err)
       
   668         if self.showAll:
       
   669             self.stream.writeln("FAIL")
       
   670         elif self.dots:
       
   671             self.stream.write('F')
       
   672 
       
   673     def printErrors(self):
       
   674         if self.dots or self.showAll:
       
   675             self.stream.writeln()
       
   676         self.printErrorList('ERROR', self.errors)
       
   677         self.printErrorList('FAIL', self.failures)
       
   678 
       
   679     def printErrorList(self, flavour, errors):
       
   680         for test, err in errors:
       
   681             self.stream.writeln(self.separator1)
       
   682             self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
       
   683             self.stream.writeln(self.separator2)
       
   684             self.stream.writeln("%s" % err)
       
   685 
       
   686 
       
   687 class TextTestRunner:
       
   688     """A test runner class that displays results in textual form.
       
   689 
       
   690     It prints out the names of tests as they are run, errors as they
       
   691     occur, and a summary of the results at the end of the test run.
       
   692     """
       
   693     def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
       
   694         self.stream = _WritelnDecorator(stream)
       
   695         self.descriptions = descriptions
       
   696         self.verbosity = verbosity
       
   697 
       
   698     def _makeResult(self):
       
   699         return _TextTestResult(self.stream, self.descriptions, self.verbosity)
       
   700 
       
   701     def run(self, test):
       
   702         "Run the given test case or test suite."
       
   703         result = self._makeResult()
       
   704         startTime = time.time()
       
   705         test(result)
       
   706         stopTime = time.time()
       
   707         timeTaken = stopTime - startTime
       
   708         result.printErrors()
       
   709         self.stream.writeln(result.separator2)
       
   710         run = result.testsRun
       
   711         self.stream.writeln("Ran %d test%s in %.3fs" %
       
   712                             (run, run != 1 and "s" or "", timeTaken))
       
   713         self.stream.writeln()
       
   714         if not result.wasSuccessful():
       
   715             self.stream.write("FAILED (")
       
   716             failed, errored = map(len, (result.failures, result.errors))
       
   717             if failed:
       
   718                 self.stream.write("failures=%d" % failed)
       
   719             if errored:
       
   720                 if failed: self.stream.write(", ")
       
   721                 self.stream.write("errors=%d" % errored)
       
   722             self.stream.writeln(")")
       
   723         else:
       
   724             self.stream.writeln("OK")
       
   725         return result
       
   726 
       
   727 
       
   728 
       
   729 ##############################################################################
       
   730 # Facilities for running tests from the command line
       
   731 ##############################################################################
       
   732 
       
   733 class TestProgram:
       
   734     """A command-line program that runs a set of tests; this is primarily
       
   735        for making test modules conveniently executable.
       
   736     """
       
   737     USAGE = """\
       
   738 Usage: %(progName)s [options] [test] [...]
       
   739 
       
   740 Options:
       
   741   -h, --help       Show this message
       
   742   -v, --verbose    Verbose output
       
   743   -q, --quiet      Minimal output
       
   744 
       
   745 Examples:
       
   746   %(progName)s                               - run default set of tests
       
   747   %(progName)s MyTestSuite                   - run suite 'MyTestSuite'
       
   748   %(progName)s MyTestCase.testSomething      - run MyTestCase.testSomething
       
   749   %(progName)s MyTestCase                    - run all 'test*' test methods
       
   750                                                in MyTestCase
       
   751 """
       
   752     def __init__(self, module='__main__', defaultTest=None,
       
   753                  argv=None, testRunner=None, testLoader=defaultTestLoader):
       
   754         if type(module) == type(''):
       
   755             self.module = __import__(module)
       
   756             for part in module.split('.')[1:]:
       
   757                 self.module = getattr(self.module, part)
       
   758         else:
       
   759             self.module = module
       
   760         if argv is None:
       
   761             argv = sys.argv
       
   762         self.verbosity = 1
       
   763         self.defaultTest = defaultTest
       
   764         self.testRunner = testRunner
       
   765         self.testLoader = testLoader
       
   766         self.progName = os.path.basename(argv[0])
       
   767         self.parseArgs(argv)
       
   768         self.runTests()
       
   769 
       
   770     def usageExit(self, msg=None):
       
   771         if msg: print msg
       
   772         print self.USAGE % self.__dict__
       
   773         sys.exit(2)
       
   774 
       
   775     def parseArgs(self, argv):
       
   776         import getopt
       
   777         try:
       
   778             options, args = getopt.getopt(argv[1:], 'hHvq',
       
   779                                           ['help','verbose','quiet'])
       
   780             for opt, value in options:
       
   781                 if opt in ('-h','-H','--help'):
       
   782                     self.usageExit()
       
   783                 if opt in ('-q','--quiet'):
       
   784                     self.verbosity = 0
       
   785                 if opt in ('-v','--verbose'):
       
   786                     self.verbosity = 2
       
   787             if len(args) == 0 and self.defaultTest is None:
       
   788                 self.test = self.testLoader.loadTestsFromModule(self.module)
       
   789                 return
       
   790             if len(args) > 0:
       
   791                 self.testNames = args
       
   792             else:
       
   793                 self.testNames = (self.defaultTest,)
       
   794             self.createTests()
       
   795         except getopt.error, msg:
       
   796             self.usageExit(msg)
       
   797 
       
   798     def createTests(self):
       
   799         self.test = self.testLoader.loadTestsFromNames(self.testNames,
       
   800                                                        self.module)
       
   801 
       
   802     def runTests(self):
       
   803         if self.testRunner is None:
       
   804             self.testRunner = TextTestRunner(verbosity=self.verbosity)
       
   805         result = self.testRunner.run(self.test)
       
   806         sys.exit(not result.wasSuccessful())
       
   807 
       
   808 main = TestProgram
       
   809 
       
   810 
       
   811 ##############################################################################
       
   812 # Executing this module from the command line
       
   813 ##############################################################################
       
   814 
       
   815 if __name__ == "__main__":
       
   816     main(module=None)