Fix the tag.
[python/dscho.git] / Lib / unittest.py
blob742871bd2337e30885f6a3ec6de73fbc48c76ee4
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.
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).
11 Simple usage:
13 import unittest
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)
23 if __name__ == '__main__':
24 unittest.main()
26 Further information is available in the bundled documentation, and from
28 http://docs.python.org/lib/module-unittest.html
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.
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.
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 '''
47 __author__ = "Steve Purcell"
48 __email__ = "stephen_purcell at yahoo dot com"
49 __version__ = "#Revision: 1.63 $"[11:-2]
51 import time
52 import sys
53 import traceback
54 import os
55 import types
57 ##############################################################################
58 # Exported classes and functions
59 ##############################################################################
60 __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
61 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
63 # Expose obsolete functions for backwards compatibility
64 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
67 ##############################################################################
68 # Test framework core
69 ##############################################################################
71 def _strclass(cls):
72 return "%s.%s" % (cls.__module__, cls.__name__)
74 __unittest = 1
76 class TestResult:
77 """Holder for test result information.
79 Test results are automatically managed by the TestCase and TestSuite
80 classes, and do not need to be explicitly manipulated by writers of tests.
82 Each instance holds the total number of tests run, and collections of
83 failures and errors that occurred among those test runs. The collections
84 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
85 formatted traceback of the error that occurred.
86 """
87 def __init__(self):
88 self.failures = []
89 self.errors = []
90 self.testsRun = 0
91 self.shouldStop = False
93 def startTest(self, test):
94 "Called when the given test is about to be run"
95 self.testsRun = self.testsRun + 1
97 def stopTest(self, test):
98 "Called when the given test has been run"
99 pass
101 def addError(self, test, err):
102 """Called when an error has occurred. 'err' is a tuple of values as
103 returned by sys.exc_info().
105 self.errors.append((test, self._exc_info_to_string(err, test)))
107 def addFailure(self, test, err):
108 """Called when an error has occurred. 'err' is a tuple of values as
109 returned by sys.exc_info()."""
110 self.failures.append((test, self._exc_info_to_string(err, test)))
112 def addSuccess(self, test):
113 "Called when a test has completed successfully"
114 pass
116 def wasSuccessful(self):
117 "Tells whether or not this result was a success"
118 return len(self.failures) == len(self.errors) == 0
120 def stop(self):
121 "Indicates that the tests should be aborted"
122 self.shouldStop = True
124 def _exc_info_to_string(self, err, test):
125 """Converts a sys.exc_info()-style tuple of values into a string."""
126 exctype, value, tb = err
127 # Skip test runner traceback levels
128 while tb and self._is_relevant_tb_level(tb):
129 tb = tb.tb_next
130 if exctype is test.failureException:
131 # Skip assert*() traceback levels
132 length = self._count_relevant_tb_levels(tb)
133 return ''.join(traceback.format_exception(exctype, value,
134 tb, length))
135 return ''.join(traceback.format_exception(exctype, value, tb))
137 def _is_relevant_tb_level(self, tb):
138 return '__unittest' in tb.tb_frame.f_globals
140 def _count_relevant_tb_levels(self, tb):
141 length = 0
142 while tb and not self._is_relevant_tb_level(tb):
143 length += 1
144 tb = tb.tb_next
145 return length
147 def __repr__(self):
148 return "<%s run=%i errors=%i failures=%i>" % \
149 (_strclass(self.__class__), self.testsRun, len(self.errors),
150 len(self.failures))
152 class TestCase:
153 """A class whose instances are single test cases.
155 By default, the test code itself should be placed in a method named
156 'runTest'.
158 If the fixture may be used for many test cases, create as
159 many test methods as are needed. When instantiating such a TestCase
160 subclass, specify in the constructor arguments the name of the test method
161 that the instance is to execute.
163 Test authors should subclass TestCase for their own tests. Construction
164 and deconstruction of the test's environment ('fixture') can be
165 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
167 If it is necessary to override the __init__ method, the base class
168 __init__ method must always be called. It is important that subclasses
169 should not change the signature of their __init__ method, since instances
170 of the classes are instantiated automatically by parts of the framework
171 in order to be run.
174 # This attribute determines which exception will be raised when
175 # the instance's assertion methods fail; test methods raising this
176 # exception will be deemed to have 'failed' rather than 'errored'
178 failureException = AssertionError
180 def __init__(self, methodName='runTest'):
181 """Create an instance of the class that will use the named test
182 method when executed. Raises a ValueError if the instance does
183 not have a method with the specified name.
185 try:
186 self._testMethodName = methodName
187 testMethod = getattr(self, methodName)
188 self._testMethodDoc = testMethod.__doc__
189 except AttributeError:
190 raise ValueError("no such test method in %s: %s"
191 % (self.__class__, methodName))
193 def setUp(self):
194 "Hook method for setting up the test fixture before exercising it."
195 pass
197 def tearDown(self):
198 "Hook method for deconstructing the test fixture after testing it."
199 pass
201 def countTestCases(self):
202 return 1
204 def defaultTestResult(self):
205 return TestResult()
207 def shortDescription(self):
208 """Returns a one-line description of the test, or None if no
209 description has been provided.
211 The default implementation of this method returns the first line of
212 the specified test method's docstring.
214 doc = self._testMethodDoc
215 return doc and doc.split("\n")[0].strip() or None
217 def id(self):
218 return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
220 def __eq__(self, other):
221 if type(self) is not type(other):
222 return False
224 return self._testMethodName == other._testMethodName
226 def __ne__(self, other):
227 return not self == other
229 def __hash__(self):
230 return hash((type(self), self._testMethodName))
232 def __str__(self):
233 return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
235 def __repr__(self):
236 return "<%s testMethod=%s>" % \
237 (_strclass(self.__class__), self._testMethodName)
239 def run(self, result=None):
240 if result is None: result = self.defaultTestResult()
241 result.startTest(self)
242 testMethod = getattr(self, self._testMethodName)
243 try:
244 try:
245 self.setUp()
246 except KeyboardInterrupt:
247 raise
248 except:
249 result.addError(self, self._exc_info())
250 return
252 ok = False
253 try:
254 testMethod()
255 ok = True
256 except self.failureException:
257 result.addFailure(self, self._exc_info())
258 except KeyboardInterrupt:
259 raise
260 except:
261 result.addError(self, self._exc_info())
263 try:
264 self.tearDown()
265 except KeyboardInterrupt:
266 raise
267 except:
268 result.addError(self, self._exc_info())
269 ok = False
270 if ok: result.addSuccess(self)
271 finally:
272 result.stopTest(self)
274 def __call__(self, *args, **kwds):
275 return self.run(*args, **kwds)
277 def debug(self):
278 """Run the test without collecting errors in a TestResult"""
279 self.setUp()
280 getattr(self, self._testMethodName)()
281 self.tearDown()
283 def _exc_info(self):
284 """Return a version of sys.exc_info() with the traceback frame
285 minimised; usually the top level of the traceback frame is not
286 needed.
288 return sys.exc_info()
290 def fail(self, msg=None):
291 """Fail immediately, with the given message."""
292 raise self.failureException(msg)
294 def failIf(self, expr, msg=None):
295 "Fail the test if the expression is true."
296 if expr: raise self.failureException(msg)
298 def failUnless(self, expr, msg=None):
299 """Fail the test unless the expression is true."""
300 if not expr: raise self.failureException(msg)
302 def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
303 """Fail unless an exception of class excClass is thrown
304 by callableObj when invoked with arguments args and keyword
305 arguments kwargs. If a different type of exception is
306 thrown, it will not be caught, and the test case will be
307 deemed to have suffered an error, exactly as for an
308 unexpected exception.
310 try:
311 callableObj(*args, **kwargs)
312 except excClass:
313 return
314 else:
315 excName = str(getattr(excClass, '__name__', excClass))
316 objName = str(getattr(callableObj, '__name__', callableObj))
317 raise self.failureException("%s not raised by %s" % (excName,
318 objName))
320 def failUnlessEqual(self, first, second, msg=None):
321 """Fail if the two objects are unequal as determined by the '=='
322 operator.
324 if not first == second:
325 raise self.failureException(msg or '%r != %r' % (first, second))
327 def failIfEqual(self, first, second, msg=None):
328 """Fail if the two objects are equal as determined by the '=='
329 operator.
331 if first == second:
332 raise self.failureException(msg or '%r == %r' % (first, second))
334 def failUnlessAlmostEqual(self, first, second, *, places=7, msg=None):
335 """Fail if the two objects are unequal as determined by their
336 difference rounded to the given number of decimal places
337 (default 7) and comparing to zero.
339 Note that decimal places (from zero) are usually not the same
340 as significant digits (measured from the most signficant digit).
342 if round(abs(second-first), places) != 0:
343 raise self.failureException(msg or '%r != %r within %r places'
344 % (first, second, places))
346 def failIfAlmostEqual(self, first, second, *, places=7, msg=None):
347 """Fail if the two objects are equal as determined by their
348 difference rounded to the given number of decimal places
349 (default 7) and comparing to zero.
351 Note that decimal places (from zero) are usually not the same
352 as significant digits (measured from the most signficant digit).
354 if round(abs(second-first), places) == 0:
355 raise self.failureException(msg or '%r == %r within %r places'
356 % (first, second, places))
358 # Synonyms for assertion methods
360 assertEqual = assertEquals = failUnlessEqual
362 assertNotEqual = assertNotEquals = failIfEqual
364 assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
366 assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
368 assertRaises = failUnlessRaises
370 assert_ = assertTrue = failUnless
372 assertFalse = failIf
376 class TestSuite:
377 """A test suite is a composite test consisting of a number of TestCases.
379 For use, create an instance of TestSuite, then add test case instances.
380 When all tests have been added, the suite can be passed to a test
381 runner, such as TextTestRunner. It will run the individual test cases
382 in the order in which they were added, aggregating the results. When
383 subclassing, do not forget to call the base class constructor.
385 def __init__(self, tests=()):
386 self._tests = []
387 self.addTests(tests)
389 def __repr__(self):
390 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
392 __str__ = __repr__
394 def __eq__(self, other):
395 if type(self) is not type(other):
396 return False
397 return self._tests == other._tests
399 def __ne__(self, other):
400 return not self == other
402 def __iter__(self):
403 return iter(self._tests)
405 def countTestCases(self):
406 cases = 0
407 for test in self._tests:
408 cases += test.countTestCases()
409 return cases
411 def addTest(self, test):
412 # sanity checks
413 if not hasattr(test, '__call__'):
414 raise TypeError("the test to add must be callable")
415 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
416 raise TypeError("TestCases and TestSuites must be instantiated "
417 "before passing them to addTest()")
418 self._tests.append(test)
420 def addTests(self, tests):
421 if isinstance(tests, str):
422 raise TypeError("tests must be an iterable of tests, not a string")
423 for test in tests:
424 self.addTest(test)
426 def run(self, result):
427 for test in self._tests:
428 if result.shouldStop:
429 break
430 test(result)
431 return result
433 def __call__(self, *args, **kwds):
434 return self.run(*args, **kwds)
436 def debug(self):
437 """Run the tests without collecting errors in a TestResult"""
438 for test in self._tests: test.debug()
441 class FunctionTestCase(TestCase):
442 """A test case that wraps a test function.
444 This is useful for slipping pre-existing test functions into the
445 unittest framework. Optionally, set-up and tidy-up functions can be
446 supplied. As with TestCase, the tidy-up ('tearDown') function will
447 always be called if the set-up ('setUp') function ran successfully.
450 def __init__(self, testFunc, setUp=None, tearDown=None,
451 description=None):
452 TestCase.__init__(self)
453 self.__setUpFunc = setUp
454 self.__tearDownFunc = tearDown
455 self.__testFunc = testFunc
456 self.__description = description
458 def setUp(self):
459 if self.__setUpFunc is not None:
460 self.__setUpFunc()
462 def tearDown(self):
463 if self.__tearDownFunc is not None:
464 self.__tearDownFunc()
466 def runTest(self):
467 self.__testFunc()
469 def id(self):
470 return self.__testFunc.__name__
472 def __eq__(self, other):
473 if type(self) is not type(other):
474 return False
476 return self.__setUpFunc == other.__setUpFunc and \
477 self.__tearDownFunc == other.__tearDownFunc and \
478 self.__testFunc == other.__testFunc and \
479 self.__description == other.__description
481 def __ne__(self, other):
482 return not self == other
484 def __hash__(self):
485 return hash((type(self), self.__setUpFunc, self.__tearDownFunc,
486 self.__testFunc, self.__description))
488 def __str__(self):
489 return "%s (%s)" % (_strclass(self.__class__),
490 self.__testFunc.__name__)
492 def __repr__(self):
493 return "<%s testFunc=%s>" % (_strclass(self.__class__),
494 self.__testFunc)
496 def shortDescription(self):
497 if self.__description is not None: return self.__description
498 doc = self.__testFunc.__doc__
499 return doc and doc.split("\n")[0].strip() or None
503 ##############################################################################
504 # Locating and loading tests
505 ##############################################################################
507 def CmpToKey(mycmp):
508 'Convert a cmp= function into a key= function'
509 class K(object):
510 def __init__(self, obj, *args):
511 self.obj = obj
512 def __lt__(self, other):
513 return mycmp(self.obj, other.obj) == -1
514 return K
516 class TestLoader:
517 """This class is responsible for loading tests according to various
518 criteria and returning them wrapped in a TestSuite
520 testMethodPrefix = 'test'
521 sortTestMethodsUsing = cmp
522 suiteClass = TestSuite
524 def loadTestsFromTestCase(self, testCaseClass):
525 """Return a suite of all tests cases contained in testCaseClass"""
526 if issubclass(testCaseClass, TestSuite):
527 raise TypeError("Test cases should not be derived from TestSuite."
528 "Maybe you meant to derive from TestCase?")
529 testCaseNames = self.getTestCaseNames(testCaseClass)
530 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
531 testCaseNames = ['runTest']
532 return self.suiteClass(map(testCaseClass, testCaseNames))
534 def loadTestsFromModule(self, module):
535 """Return a suite of all tests cases contained in the given module"""
536 tests = []
537 for name in dir(module):
538 obj = getattr(module, name)
539 if isinstance(obj, type) and issubclass(obj, TestCase):
540 tests.append(self.loadTestsFromTestCase(obj))
541 return self.suiteClass(tests)
543 def loadTestsFromName(self, name, module=None):
544 """Return a suite of all tests cases given a string specifier.
546 The name may resolve either to a module, a test case class, a
547 test method within a test case class, or a callable object which
548 returns a TestCase or TestSuite instance.
550 The method optionally resolves the names relative to a given module.
552 parts = name.split('.')
553 if module is None:
554 parts_copy = parts[:]
555 while parts_copy:
556 try:
557 module = __import__('.'.join(parts_copy))
558 break
559 except ImportError:
560 del parts_copy[-1]
561 if not parts_copy: raise
562 parts = parts[1:]
563 obj = module
564 for part in parts:
565 parent, obj = obj, getattr(obj, part)
567 if type(obj) == types.ModuleType:
568 return self.loadTestsFromModule(obj)
569 elif isinstance(obj, type) and issubclass(obj, TestCase):
570 return self.loadTestsFromTestCase(obj)
571 elif (isinstance(obj, types.FunctionType) and
572 isinstance(parent, type) and
573 issubclass(parent, TestCase)):
574 name = obj.__name__
575 inst = parent(name)
576 # static methods follow a different path
577 if not isinstance(getattr(inst, name), types.FunctionType):
578 return TestSuite([inst])
579 elif isinstance(obj, TestSuite):
580 return obj
582 if hasattr(obj, '__call__'):
583 test = obj()
584 if isinstance(test, TestSuite):
585 return test
586 elif isinstance(test, TestCase):
587 return TestSuite([test])
588 else:
589 raise TypeError("calling %s returned %s, not a test" %
590 (obj, test))
591 else:
592 raise TypeError("don't know how to make test from: %s" % obj)
594 def loadTestsFromNames(self, names, module=None):
595 """Return a suite of all tests cases found using the given sequence
596 of string specifiers. See 'loadTestsFromName()'.
598 suites = [self.loadTestsFromName(name, module) for name in names]
599 return self.suiteClass(suites)
601 def getTestCaseNames(self, testCaseClass):
602 """Return a sorted sequence of method names found within testCaseClass
604 def isTestMethod(attrname, testCaseClass=testCaseClass,
605 prefix=self.testMethodPrefix):
606 return attrname.startswith(prefix) \
607 and hasattr(getattr(testCaseClass, attrname), '__call__')
608 testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
609 if self.sortTestMethodsUsing:
610 testFnNames.sort(key=CmpToKey(self.sortTestMethodsUsing))
611 return testFnNames
615 defaultTestLoader = TestLoader()
618 ##############################################################################
619 # Patches for old functions: these functions should be considered obsolete
620 ##############################################################################
622 def _makeLoader(prefix, sortUsing, suiteClass=None):
623 loader = TestLoader()
624 loader.sortTestMethodsUsing = sortUsing
625 loader.testMethodPrefix = prefix
626 if suiteClass: loader.suiteClass = suiteClass
627 return loader
629 def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
630 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
632 def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
633 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
635 def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
636 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
639 ##############################################################################
640 # Text UI
641 ##############################################################################
643 class _WritelnDecorator:
644 """Used to decorate file-like objects with a handy 'writeln' method"""
645 def __init__(self,stream):
646 self.stream = stream
648 def __getattr__(self, attr):
649 return getattr(self.stream,attr)
651 def writeln(self, arg=None):
652 if arg: self.write(arg)
653 self.write('\n') # text-mode streams translate to \r\n if needed
656 class _TextTestResult(TestResult):
657 """A test result class that can print formatted text results to a stream.
659 Used by TextTestRunner.
661 separator1 = '=' * 70
662 separator2 = '-' * 70
664 def __init__(self, stream, descriptions, verbosity):
665 TestResult.__init__(self)
666 self.stream = stream
667 self.showAll = verbosity > 1
668 self.dots = verbosity == 1
669 self.descriptions = descriptions
671 def getDescription(self, test):
672 if self.descriptions:
673 return test.shortDescription() or str(test)
674 else:
675 return str(test)
677 def startTest(self, test):
678 TestResult.startTest(self, test)
679 if self.showAll:
680 self.stream.write(self.getDescription(test))
681 self.stream.write(" ... ")
683 def addSuccess(self, test):
684 TestResult.addSuccess(self, test)
685 if self.showAll:
686 self.stream.writeln("ok")
687 elif self.dots:
688 self.stream.write('.')
690 def addError(self, test, err):
691 TestResult.addError(self, test, err)
692 if self.showAll:
693 self.stream.writeln("ERROR")
694 elif self.dots:
695 self.stream.write('E')
697 def addFailure(self, test, err):
698 TestResult.addFailure(self, test, err)
699 if self.showAll:
700 self.stream.writeln("FAIL")
701 elif self.dots:
702 self.stream.write('F')
704 def printErrors(self):
705 if self.dots or self.showAll:
706 self.stream.writeln()
707 self.printErrorList('ERROR', self.errors)
708 self.printErrorList('FAIL', self.failures)
710 def printErrorList(self, flavour, errors):
711 for test, err in errors:
712 self.stream.writeln(self.separator1)
713 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
714 self.stream.writeln(self.separator2)
715 self.stream.writeln("%s" % err)
718 class TextTestRunner:
719 """A test runner class that displays results in textual form.
721 It prints out the names of tests as they are run, errors as they
722 occur, and a summary of the results at the end of the test run.
724 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
725 self.stream = _WritelnDecorator(stream)
726 self.descriptions = descriptions
727 self.verbosity = verbosity
729 def _makeResult(self):
730 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
732 def run(self, test):
733 "Run the given test case or test suite."
734 result = self._makeResult()
735 startTime = time.time()
736 test(result)
737 stopTime = time.time()
738 timeTaken = stopTime - startTime
739 result.printErrors()
740 self.stream.writeln(result.separator2)
741 run = result.testsRun
742 self.stream.writeln("Ran %d test%s in %.3fs" %
743 (run, run != 1 and "s" or "", timeTaken))
744 self.stream.writeln()
745 if not result.wasSuccessful():
746 self.stream.write("FAILED (")
747 failed, errored = len(result.failures), len(result.errors)
748 if failed:
749 self.stream.write("failures=%d" % failed)
750 if errored:
751 if failed: self.stream.write(", ")
752 self.stream.write("errors=%d" % errored)
753 self.stream.writeln(")")
754 else:
755 self.stream.writeln("OK")
756 return result
760 ##############################################################################
761 # Facilities for running tests from the command line
762 ##############################################################################
764 class TestProgram:
765 """A command-line program that runs a set of tests; this is primarily
766 for making test modules conveniently executable.
768 USAGE = """\
769 Usage: %(progName)s [options] [test] [...]
771 Options:
772 -h, --help Show this message
773 -v, --verbose Verbose output
774 -q, --quiet Minimal output
776 Examples:
777 %(progName)s - run default set of tests
778 %(progName)s MyTestSuite - run suite 'MyTestSuite'
779 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
780 %(progName)s MyTestCase - run all 'test*' test methods
781 in MyTestCase
783 def __init__(self, module='__main__', defaultTest=None,
784 argv=None, testRunner=TextTestRunner,
785 testLoader=defaultTestLoader):
786 if type(module) == type(''):
787 self.module = __import__(module)
788 for part in module.split('.')[1:]:
789 self.module = getattr(self.module, part)
790 else:
791 self.module = module
792 if argv is None:
793 argv = sys.argv
794 self.verbosity = 1
795 self.defaultTest = defaultTest
796 self.testRunner = testRunner
797 self.testLoader = testLoader
798 self.progName = os.path.basename(argv[0])
799 self.parseArgs(argv)
800 self.runTests()
802 def usageExit(self, msg=None):
803 if msg: print(msg)
804 print(self.USAGE % self.__dict__)
805 sys.exit(2)
807 def parseArgs(self, argv):
808 import getopt
809 try:
810 options, args = getopt.getopt(argv[1:], 'hHvq',
811 ['help','verbose','quiet'])
812 for opt, value in options:
813 if opt in ('-h','-H','--help'):
814 self.usageExit()
815 if opt in ('-q','--quiet'):
816 self.verbosity = 0
817 if opt in ('-v','--verbose'):
818 self.verbosity = 2
819 if len(args) == 0 and self.defaultTest is None:
820 self.test = self.testLoader.loadTestsFromModule(self.module)
821 return
822 if len(args) > 0:
823 self.testNames = args
824 else:
825 self.testNames = (self.defaultTest,)
826 self.createTests()
827 except getopt.error as msg:
828 self.usageExit(msg)
830 def createTests(self):
831 self.test = self.testLoader.loadTestsFromNames(self.testNames,
832 self.module)
834 def runTests(self):
835 if isinstance(self.testRunner, type):
836 try:
837 testRunner = self.testRunner(verbosity=self.verbosity)
838 except TypeError:
839 # didn't accept the verbosity argument
840 testRunner = self.testRunner()
841 else:
842 # it is assumed to be a TestRunner instance
843 testRunner = self.testRunner
844 result = testRunner.run(self.test)
845 sys.exit(not result.wasSuccessful())
847 main = TestProgram
850 ##############################################################################
851 # Executing this module from the command line
852 ##############################################################################
854 if __name__ == "__main__":
855 main(module=None)