This commit was manufactured by cvs2svn to create tag 'r234c1'.
[python/dscho.git] / Lib / unittest.py
blob043b9a848a4f824e02504b66f0157c57571552dd
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://pyunit.sourceforge.net/
30 Copyright (c) 1999, 2000, 2001 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.46 $"[11:-2]
51 import time
52 import sys
53 import traceback
54 import string
55 import os
56 import types
58 ##############################################################################
59 # Exported classes and functions
60 ##############################################################################
61 __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
62 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
64 # Expose obsolete functions for backwards compatability
65 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
68 ##############################################################################
69 # Test framework core
70 ##############################################################################
72 # All classes defined herein are 'new-style' classes, allowing use of 'super()'
73 __metaclass__ = type
75 def _strclass(cls):
76 return "%s.%s" % (cls.__module__, cls.__name__)
78 class TestResult:
79 """Holder for test result information.
81 Test results are automatically managed by the TestCase and TestSuite
82 classes, and do not need to be explicitly manipulated by writers of tests.
84 Each instance holds the total number of tests run, and collections of
85 failures and errors that occurred among those test runs. The collections
86 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
87 formatted traceback of the error that occurred.
88 """
89 def __init__(self):
90 self.failures = []
91 self.errors = []
92 self.testsRun = 0
93 self.shouldStop = 0
95 def startTest(self, test):
96 "Called when the given test is about to be run"
97 self.testsRun = self.testsRun + 1
99 def stopTest(self, test):
100 "Called when the given test has been run"
101 pass
103 def addError(self, test, err):
104 """Called when an error has occurred. 'err' is a tuple of values as
105 returned by sys.exc_info().
107 self.errors.append((test, self._exc_info_to_string(err)))
109 def addFailure(self, test, err):
110 """Called when an error has occurred. 'err' is a tuple of values as
111 returned by sys.exc_info()."""
112 self.failures.append((test, self._exc_info_to_string(err)))
114 def addSuccess(self, test):
115 "Called when a test has completed successfully"
116 pass
118 def wasSuccessful(self):
119 "Tells whether or not this result was a success"
120 return len(self.failures) == len(self.errors) == 0
122 def stop(self):
123 "Indicates that the tests should be aborted"
124 self.shouldStop = 1
126 def _exc_info_to_string(self, err):
127 """Converts a sys.exc_info()-style tuple of values into a string."""
128 return string.join(traceback.format_exception(*err), '')
130 def __repr__(self):
131 return "<%s run=%i errors=%i failures=%i>" % \
132 (_strclass(self.__class__), self.testsRun, len(self.errors),
133 len(self.failures))
136 class TestCase:
137 """A class whose instances are single test cases.
139 By default, the test code itself should be placed in a method named
140 'runTest'.
142 If the fixture may be used for many test cases, create as
143 many test methods as are needed. When instantiating such a TestCase
144 subclass, specify in the constructor arguments the name of the test method
145 that the instance is to execute.
147 Test authors should subclass TestCase for their own tests. Construction
148 and deconstruction of the test's environment ('fixture') can be
149 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
151 If it is necessary to override the __init__ method, the base class
152 __init__ method must always be called. It is important that subclasses
153 should not change the signature of their __init__ method, since instances
154 of the classes are instantiated automatically by parts of the framework
155 in order to be run.
158 # This attribute determines which exception will be raised when
159 # the instance's assertion methods fail; test methods raising this
160 # exception will be deemed to have 'failed' rather than 'errored'
162 failureException = AssertionError
164 def __init__(self, methodName='runTest'):
165 """Create an instance of the class that will use the named test
166 method when executed. Raises a ValueError if the instance does
167 not have a method with the specified name.
169 try:
170 self.__testMethodName = methodName
171 testMethod = getattr(self, methodName)
172 self.__testMethodDoc = testMethod.__doc__
173 except AttributeError:
174 raise ValueError, "no such test method in %s: %s" % \
175 (self.__class__, methodName)
177 def setUp(self):
178 "Hook method for setting up the test fixture before exercising it."
179 pass
181 def tearDown(self):
182 "Hook method for deconstructing the test fixture after testing it."
183 pass
185 def countTestCases(self):
186 return 1
188 def defaultTestResult(self):
189 return TestResult()
191 def shortDescription(self):
192 """Returns a one-line description of the test, or None if no
193 description has been provided.
195 The default implementation of this method returns the first line of
196 the specified test method's docstring.
198 doc = self.__testMethodDoc
199 return doc and string.strip(string.split(doc, "\n")[0]) or None
201 def id(self):
202 return "%s.%s" % (_strclass(self.__class__), self.__testMethodName)
204 def __str__(self):
205 return "%s (%s)" % (self.__testMethodName, _strclass(self.__class__))
207 def __repr__(self):
208 return "<%s testMethod=%s>" % \
209 (_strclass(self.__class__), self.__testMethodName)
211 def run(self, result=None):
212 return self(result)
214 def __call__(self, result=None):
215 if result is None: result = self.defaultTestResult()
216 result.startTest(self)
217 testMethod = getattr(self, self.__testMethodName)
218 try:
219 try:
220 self.setUp()
221 except KeyboardInterrupt:
222 raise
223 except:
224 result.addError(self, self.__exc_info())
225 return
227 ok = 0
228 try:
229 testMethod()
230 ok = 1
231 except self.failureException:
232 result.addFailure(self, self.__exc_info())
233 except KeyboardInterrupt:
234 raise
235 except:
236 result.addError(self, self.__exc_info())
238 try:
239 self.tearDown()
240 except KeyboardInterrupt:
241 raise
242 except:
243 result.addError(self, self.__exc_info())
244 ok = 0
245 if ok: result.addSuccess(self)
246 finally:
247 result.stopTest(self)
249 def debug(self):
250 """Run the test without collecting errors in a TestResult"""
251 self.setUp()
252 getattr(self, self.__testMethodName)()
253 self.tearDown()
255 def __exc_info(self):
256 """Return a version of sys.exc_info() with the traceback frame
257 minimised; usually the top level of the traceback frame is not
258 needed.
260 exctype, excvalue, tb = sys.exc_info()
261 if sys.platform[:4] == 'java': ## tracebacks look different in Jython
262 return (exctype, excvalue, tb)
263 newtb = tb.tb_next
264 if newtb is None:
265 return (exctype, excvalue, tb)
266 return (exctype, excvalue, newtb)
268 def fail(self, msg=None):
269 """Fail immediately, with the given message."""
270 raise self.failureException, msg
272 def failIf(self, expr, msg=None):
273 "Fail the test if the expression is true."
274 if expr: raise self.failureException, msg
276 def failUnless(self, expr, msg=None):
277 """Fail the test unless the expression is true."""
278 if not expr: raise self.failureException, msg
280 def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
281 """Fail unless an exception of class excClass is thrown
282 by callableObj when invoked with arguments args and keyword
283 arguments kwargs. If a different type of exception is
284 thrown, it will not be caught, and the test case will be
285 deemed to have suffered an error, exactly as for an
286 unexpected exception.
288 try:
289 callableObj(*args, **kwargs)
290 except excClass:
291 return
292 else:
293 if hasattr(excClass,'__name__'): excName = excClass.__name__
294 else: excName = str(excClass)
295 raise self.failureException, excName
297 def failUnlessEqual(self, first, second, msg=None):
298 """Fail if the two objects are unequal as determined by the '=='
299 operator.
301 if not first == second:
302 raise self.failureException, \
303 (msg or '%s != %s' % (`first`, `second`))
305 def failIfEqual(self, first, second, msg=None):
306 """Fail if the two objects are equal as determined by the '=='
307 operator.
309 if first == second:
310 raise self.failureException, \
311 (msg or '%s == %s' % (`first`, `second`))
313 def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
314 """Fail if the two objects are unequal as determined by their
315 difference rounded to the given number of decimal places
316 (default 7) and comparing to zero.
318 Note that decimal places (from zero) is usually not the same
319 as significant digits (measured from the most signficant digit).
321 if round(second-first, places) != 0:
322 raise self.failureException, \
323 (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
325 def failIfAlmostEqual(self, first, second, places=7, msg=None):
326 """Fail if the two objects are equal as determined by their
327 difference rounded to the given number of decimal places
328 (default 7) and comparing to zero.
330 Note that decimal places (from zero) is usually not the same
331 as significant digits (measured from the most signficant digit).
333 if round(second-first, places) == 0:
334 raise self.failureException, \
335 (msg or '%s == %s within %s places' % (`first`, `second`, `places`))
337 assertEqual = assertEquals = failUnlessEqual
339 assertNotEqual = assertNotEquals = failIfEqual
341 assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
343 assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
345 assertRaises = failUnlessRaises
347 assert_ = failUnless
351 class TestSuite:
352 """A test suite is a composite test consisting of a number of TestCases.
354 For use, create an instance of TestSuite, then add test case instances.
355 When all tests have been added, the suite can be passed to a test
356 runner, such as TextTestRunner. It will run the individual test cases
357 in the order in which they were added, aggregating the results. When
358 subclassing, do not forget to call the base class constructor.
360 def __init__(self, tests=()):
361 self._tests = []
362 self.addTests(tests)
364 def __repr__(self):
365 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
367 __str__ = __repr__
369 def countTestCases(self):
370 cases = 0
371 for test in self._tests:
372 cases = cases + test.countTestCases()
373 return cases
375 def addTest(self, test):
376 self._tests.append(test)
378 def addTests(self, tests):
379 for test in tests:
380 self.addTest(test)
382 def run(self, result):
383 return self(result)
385 def __call__(self, result):
386 for test in self._tests:
387 if result.shouldStop:
388 break
389 test(result)
390 return result
392 def debug(self):
393 """Run the tests without collecting errors in a TestResult"""
394 for test in self._tests: test.debug()
397 class FunctionTestCase(TestCase):
398 """A test case that wraps a test function.
400 This is useful for slipping pre-existing test functions into the
401 PyUnit framework. Optionally, set-up and tidy-up functions can be
402 supplied. As with TestCase, the tidy-up ('tearDown') function will
403 always be called if the set-up ('setUp') function ran successfully.
406 def __init__(self, testFunc, setUp=None, tearDown=None,
407 description=None):
408 TestCase.__init__(self)
409 self.__setUpFunc = setUp
410 self.__tearDownFunc = tearDown
411 self.__testFunc = testFunc
412 self.__description = description
414 def setUp(self):
415 if self.__setUpFunc is not None:
416 self.__setUpFunc()
418 def tearDown(self):
419 if self.__tearDownFunc is not None:
420 self.__tearDownFunc()
422 def runTest(self):
423 self.__testFunc()
425 def id(self):
426 return self.__testFunc.__name__
428 def __str__(self):
429 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
431 def __repr__(self):
432 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
434 def shortDescription(self):
435 if self.__description is not None: return self.__description
436 doc = self.__testFunc.__doc__
437 return doc and string.strip(string.split(doc, "\n")[0]) or None
441 ##############################################################################
442 # Locating and loading tests
443 ##############################################################################
445 class TestLoader:
446 """This class is responsible for loading tests according to various
447 criteria and returning them wrapped in a Test
449 testMethodPrefix = 'test'
450 sortTestMethodsUsing = cmp
451 suiteClass = TestSuite
453 def loadTestsFromTestCase(self, testCaseClass):
454 """Return a suite of all tests cases contained in testCaseClass"""
455 return self.suiteClass(map(testCaseClass,
456 self.getTestCaseNames(testCaseClass)))
458 def loadTestsFromModule(self, module):
459 """Return a suite of all tests cases contained in the given module"""
460 tests = []
461 for name in dir(module):
462 obj = getattr(module, name)
463 if (isinstance(obj, (type, types.ClassType)) and
464 issubclass(obj, TestCase)):
465 tests.append(self.loadTestsFromTestCase(obj))
466 return self.suiteClass(tests)
468 def loadTestsFromName(self, name, module=None):
469 """Return a suite of all tests cases given a string specifier.
471 The name may resolve either to a module, a test case class, a
472 test method within a test case class, or a callable object which
473 returns a TestCase or TestSuite instance.
475 The method optionally resolves the names relative to a given module.
477 parts = string.split(name, '.')
478 if module is None:
479 if not parts:
480 raise ValueError, "incomplete test name: %s" % name
481 else:
482 parts_copy = parts[:]
483 while parts_copy:
484 try:
485 module = __import__(string.join(parts_copy,'.'))
486 break
487 except ImportError:
488 del parts_copy[-1]
489 if not parts_copy: raise
490 parts = parts[1:]
491 obj = module
492 for part in parts:
493 obj = getattr(obj, part)
495 import unittest
496 if type(obj) == types.ModuleType:
497 return self.loadTestsFromModule(obj)
498 elif (isinstance(obj, (type, types.ClassType)) and
499 issubclass(obj, unittest.TestCase)):
500 return self.loadTestsFromTestCase(obj)
501 elif type(obj) == types.UnboundMethodType:
502 return obj.im_class(obj.__name__)
503 elif callable(obj):
504 test = obj()
505 if not isinstance(test, unittest.TestCase) and \
506 not isinstance(test, unittest.TestSuite):
507 raise ValueError, \
508 "calling %s returned %s, not a test" % (obj,test)
509 return test
510 else:
511 raise ValueError, "don't know how to make test from: %s" % obj
513 def loadTestsFromNames(self, names, module=None):
514 """Return a suite of all tests cases found using the given sequence
515 of string specifiers. See 'loadTestsFromName()'.
517 suites = []
518 for name in names:
519 suites.append(self.loadTestsFromName(name, module))
520 return self.suiteClass(suites)
522 def getTestCaseNames(self, testCaseClass):
523 """Return a sorted sequence of method names found within testCaseClass
525 testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
526 dir(testCaseClass))
527 for baseclass in testCaseClass.__bases__:
528 for testFnName in self.getTestCaseNames(baseclass):
529 if testFnName not in testFnNames: # handle overridden methods
530 testFnNames.append(testFnName)
531 if self.sortTestMethodsUsing:
532 testFnNames.sort(self.sortTestMethodsUsing)
533 return testFnNames
537 defaultTestLoader = TestLoader()
540 ##############################################################################
541 # Patches for old functions: these functions should be considered obsolete
542 ##############################################################################
544 def _makeLoader(prefix, sortUsing, suiteClass=None):
545 loader = TestLoader()
546 loader.sortTestMethodsUsing = sortUsing
547 loader.testMethodPrefix = prefix
548 if suiteClass: loader.suiteClass = suiteClass
549 return loader
551 def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
552 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
554 def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
555 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
557 def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
558 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
561 ##############################################################################
562 # Text UI
563 ##############################################################################
565 class _WritelnDecorator:
566 """Used to decorate file-like objects with a handy 'writeln' method"""
567 def __init__(self,stream):
568 self.stream = stream
570 def __getattr__(self, attr):
571 return getattr(self.stream,attr)
573 def writeln(self, arg=None):
574 if arg: self.write(arg)
575 self.write('\n') # text-mode streams translate to \r\n if needed
578 class _TextTestResult(TestResult):
579 """A test result class that can print formatted text results to a stream.
581 Used by TextTestRunner.
583 separator1 = '=' * 70
584 separator2 = '-' * 70
586 def __init__(self, stream, descriptions, verbosity):
587 TestResult.__init__(self)
588 self.stream = stream
589 self.showAll = verbosity > 1
590 self.dots = verbosity == 1
591 self.descriptions = descriptions
593 def getDescription(self, test):
594 if self.descriptions:
595 return test.shortDescription() or str(test)
596 else:
597 return str(test)
599 def startTest(self, test):
600 TestResult.startTest(self, test)
601 if self.showAll:
602 self.stream.write(self.getDescription(test))
603 self.stream.write(" ... ")
605 def addSuccess(self, test):
606 TestResult.addSuccess(self, test)
607 if self.showAll:
608 self.stream.writeln("ok")
609 elif self.dots:
610 self.stream.write('.')
612 def addError(self, test, err):
613 TestResult.addError(self, test, err)
614 if self.showAll:
615 self.stream.writeln("ERROR")
616 elif self.dots:
617 self.stream.write('E')
619 def addFailure(self, test, err):
620 TestResult.addFailure(self, test, err)
621 if self.showAll:
622 self.stream.writeln("FAIL")
623 elif self.dots:
624 self.stream.write('F')
626 def printErrors(self):
627 if self.dots or self.showAll:
628 self.stream.writeln()
629 self.printErrorList('ERROR', self.errors)
630 self.printErrorList('FAIL', self.failures)
632 def printErrorList(self, flavour, errors):
633 for test, err in errors:
634 self.stream.writeln(self.separator1)
635 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
636 self.stream.writeln(self.separator2)
637 self.stream.writeln("%s" % err)
640 class TextTestRunner:
641 """A test runner class that displays results in textual form.
643 It prints out the names of tests as they are run, errors as they
644 occur, and a summary of the results at the end of the test run.
646 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
647 self.stream = _WritelnDecorator(stream)
648 self.descriptions = descriptions
649 self.verbosity = verbosity
651 def _makeResult(self):
652 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
654 def run(self, test):
655 "Run the given test case or test suite."
656 result = self._makeResult()
657 startTime = time.time()
658 test(result)
659 stopTime = time.time()
660 timeTaken = float(stopTime - startTime)
661 result.printErrors()
662 self.stream.writeln(result.separator2)
663 run = result.testsRun
664 self.stream.writeln("Ran %d test%s in %.3fs" %
665 (run, run != 1 and "s" or "", timeTaken))
666 self.stream.writeln()
667 if not result.wasSuccessful():
668 self.stream.write("FAILED (")
669 failed, errored = map(len, (result.failures, result.errors))
670 if failed:
671 self.stream.write("failures=%d" % failed)
672 if errored:
673 if failed: self.stream.write(", ")
674 self.stream.write("errors=%d" % errored)
675 self.stream.writeln(")")
676 else:
677 self.stream.writeln("OK")
678 return result
682 ##############################################################################
683 # Facilities for running tests from the command line
684 ##############################################################################
686 class TestProgram:
687 """A command-line program that runs a set of tests; this is primarily
688 for making test modules conveniently executable.
690 USAGE = """\
691 Usage: %(progName)s [options] [test] [...]
693 Options:
694 -h, --help Show this message
695 -v, --verbose Verbose output
696 -q, --quiet Minimal output
698 Examples:
699 %(progName)s - run default set of tests
700 %(progName)s MyTestSuite - run suite 'MyTestSuite'
701 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
702 %(progName)s MyTestCase - run all 'test*' test methods
703 in MyTestCase
705 def __init__(self, module='__main__', defaultTest=None,
706 argv=None, testRunner=None, testLoader=defaultTestLoader):
707 if type(module) == type(''):
708 self.module = __import__(module)
709 for part in string.split(module,'.')[1:]:
710 self.module = getattr(self.module, part)
711 else:
712 self.module = module
713 if argv is None:
714 argv = sys.argv
715 self.verbosity = 1
716 self.defaultTest = defaultTest
717 self.testRunner = testRunner
718 self.testLoader = testLoader
719 self.progName = os.path.basename(argv[0])
720 self.parseArgs(argv)
721 self.runTests()
723 def usageExit(self, msg=None):
724 if msg: print msg
725 print self.USAGE % self.__dict__
726 sys.exit(2)
728 def parseArgs(self, argv):
729 import getopt
730 try:
731 options, args = getopt.getopt(argv[1:], 'hHvq',
732 ['help','verbose','quiet'])
733 for opt, value in options:
734 if opt in ('-h','-H','--help'):
735 self.usageExit()
736 if opt in ('-q','--quiet'):
737 self.verbosity = 0
738 if opt in ('-v','--verbose'):
739 self.verbosity = 2
740 if len(args) == 0 and self.defaultTest is None:
741 self.test = self.testLoader.loadTestsFromModule(self.module)
742 return
743 if len(args) > 0:
744 self.testNames = args
745 else:
746 self.testNames = (self.defaultTest,)
747 self.createTests()
748 except getopt.error, msg:
749 self.usageExit(msg)
751 def createTests(self):
752 self.test = self.testLoader.loadTestsFromNames(self.testNames,
753 self.module)
755 def runTests(self):
756 if self.testRunner is None:
757 self.testRunner = TextTestRunner(verbosity=self.verbosity)
758 result = self.testRunner.run(self.test)
759 sys.exit(not result.wasSuccessful())
761 main = TestProgram
764 ##############################################################################
765 # Executing this module from the command line
766 ##############################################################################
768 if __name__ == "__main__":
769 main(module=None)