PageRenderTime 65ms CodeModel.GetById 11ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/unittest.py

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