Merged revisions 81181 via svnmerge from
[python/dscho.git] / Lib / unittest.py
blobc27fac1cbf9881efe3ea5d54b81f3ca44b70f6f3
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.assertEqual((1 + 2), 3)
18 self.assertEqual(0 + 1, 1)
19 def testMultiply(self):
20 self.assertEqual((0 * 10), 0)
21 self.assertEqual((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/library/unittest.html
30 Copyright (c) 1999-2003 Steve Purcell
31 Copyright (c) 2003-2009 Python Software Foundation
32 This module is free software, and you may redistribute it and/or modify
33 it under the same terms as Python itself, so long as this copyright message
34 and disclaimer are retained in their original form.
36 IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
37 SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
38 THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
39 DAMAGE.
41 THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
42 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43 PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
44 AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
45 SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
46 '''
48 import difflib
49 import functools
50 import os
51 import pprint
52 import re
53 import sys
54 import time
55 import traceback
56 import types
57 import warnings
59 ##############################################################################
60 # Exported classes and functions
61 ##############################################################################
62 __all__ = ['TestResult', 'TestCase', 'TestSuite',
63 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
64 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
65 'expectedFailure']
67 # Expose obsolete functions for backwards compatibility
68 __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
71 ##############################################################################
72 # Test framework core
73 ##############################################################################
75 def _strclass(cls):
76 return "%s.%s" % (cls.__module__, cls.__name__)
79 class SkipTest(Exception):
80 """
81 Raise this exception in a test to skip it.
83 Usually you can use TestResult.skip() or one of the skipping decorators
84 instead of raising this directly.
85 """
86 pass
88 class _ExpectedFailure(Exception):
89 """
90 Raise this when a test is expected to fail.
92 This is an implementation detail.
93 """
95 def __init__(self, exc_info):
96 super(_ExpectedFailure, self).__init__()
97 self.exc_info = exc_info
99 class _UnexpectedSuccess(Exception):
101 The test was supposed to fail, but it didn't!
103 pass
105 def _id(obj):
106 return obj
108 def skip(reason):
110 Unconditionally skip a test.
112 def decorator(test_item):
113 if isinstance(test_item, type) and issubclass(test_item, TestCase):
114 test_item.__unittest_skip__ = True
115 test_item.__unittest_skip_why__ = reason
116 return test_item
117 @functools.wraps(test_item)
118 def skip_wrapper(*args, **kwargs):
119 raise SkipTest(reason)
120 return skip_wrapper
121 return decorator
123 def skipIf(condition, reason):
125 Skip a test if the condition is true.
127 if condition:
128 return skip(reason)
129 return _id
131 def skipUnless(condition, reason):
133 Skip a test unless the condition is true.
135 if not condition:
136 return skip(reason)
137 return _id
140 def expectedFailure(func):
141 @functools.wraps(func)
142 def wrapper(*args, **kwargs):
143 try:
144 func(*args, **kwargs)
145 except Exception:
146 raise _ExpectedFailure(sys.exc_info())
147 raise _UnexpectedSuccess
148 return wrapper
150 __unittest = 1
152 class TestResult(object):
153 """Holder for test result information.
155 Test results are automatically managed by the TestCase and TestSuite
156 classes, and do not need to be explicitly manipulated by writers of tests.
158 Each instance holds the total number of tests run, and collections of
159 failures and errors that occurred among those test runs. The collections
160 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
161 formatted traceback of the error that occurred.
163 def __init__(self):
164 self.failures = []
165 self.errors = []
166 self.testsRun = 0
167 self.skipped = []
168 self.expectedFailures = []
169 self.unexpectedSuccesses = []
170 self.shouldStop = False
172 def startTest(self, test):
173 "Called when the given test is about to be run"
174 self.testsRun = self.testsRun + 1
176 def startTestRun(self):
177 """Called once before any tests are executed.
179 See startTest for a method called before each test.
182 def stopTest(self, test):
183 "Called when the given test has been run"
184 pass
186 def stopTestRun(self):
187 """Called once after all tests are executed.
189 See stopTest for a method called after each test.
192 def addError(self, test, err):
193 """Called when an error has occurred. 'err' is a tuple of values as
194 returned by sys.exc_info().
196 self.errors.append((test, self._exc_info_to_string(err, test)))
198 def addFailure(self, test, err):
199 """Called when an error has occurred. 'err' is a tuple of values as
200 returned by sys.exc_info()."""
201 self.failures.append((test, self._exc_info_to_string(err, test)))
203 def addSuccess(self, test):
204 "Called when a test has completed successfully"
205 pass
207 def addSkip(self, test, reason):
208 """Called when a test is skipped."""
209 self.skipped.append((test, reason))
211 def addExpectedFailure(self, test, err):
212 """Called when an expected failure/error occured."""
213 self.expectedFailures.append(
214 (test, self._exc_info_to_string(err, test)))
216 def addUnexpectedSuccess(self, test):
217 """Called when a test was expected to fail, but succeed."""
218 self.unexpectedSuccesses.append(test)
220 def wasSuccessful(self):
221 "Tells whether or not this result was a success"
222 return len(self.failures) == len(self.errors) == 0
224 def stop(self):
225 "Indicates that the tests should be aborted"
226 self.shouldStop = True
228 def _exc_info_to_string(self, err, test):
229 """Converts a sys.exc_info()-style tuple of values into a string."""
230 exctype, value, tb = err
231 # Skip test runner traceback levels
232 while tb and self._is_relevant_tb_level(tb):
233 tb = tb.tb_next
234 if exctype is test.failureException:
235 # Skip assert*() traceback levels
236 length = self._count_relevant_tb_levels(tb)
237 return ''.join(traceback.format_exception(exctype, value,
238 tb, length))
239 return ''.join(traceback.format_exception(exctype, value, tb))
241 def _is_relevant_tb_level(self, tb):
242 return '__unittest' in tb.tb_frame.f_globals
244 def _count_relevant_tb_levels(self, tb):
245 length = 0
246 while tb and not self._is_relevant_tb_level(tb):
247 length += 1
248 tb = tb.tb_next
249 return length
251 def __repr__(self):
252 return "<%s run=%i errors=%i failures=%i>" % \
253 (_strclass(self.__class__), self.testsRun, len(self.errors),
254 len(self.failures))
257 class _AssertRaisesContext(object):
258 """A context manager used to implement TestCase.assertRaises* methods."""
261 def __init__(self, expected, test_case, callable_obj=None,
262 expected_regexp=None):
263 self.expected = expected
264 self.failureException = test_case.failureException
265 if callable_obj is not None:
266 try:
267 self.obj_name = callable_obj.__name__
268 except AttributeError:
269 self.obj_name = str(callable_obj)
270 else:
271 self.obj_name = None
272 self.expected_regex = expected_regexp
274 def __enter__(self):
275 pass
277 def __exit__(self, exc_type, exc_value, tb):
278 if exc_type is None:
279 try:
280 exc_name = self.expected.__name__
281 except AttributeError:
282 exc_name = str(self.expected)
283 if self.obj_name:
284 raise self.failureException("{0} not raised by {1}"
285 .format(exc_name, self.obj_name))
286 else:
287 raise self.failureException("{0} not raised"
288 .format(exc_name))
289 if not issubclass(exc_type, self.expected):
290 # let unexpected exceptions pass through
291 return False
292 if self.expected_regex is None:
293 return True
295 expected_regexp = self.expected_regex
296 if isinstance(expected_regexp, (bytes, str)):
297 expected_regexp = re.compile(expected_regexp)
298 if not expected_regexp.search(str(exc_value)):
299 raise self.failureException('"%s" does not match "%s"' %
300 (expected_regexp.pattern, str(exc_value)))
301 return True
304 class _AssertWrapper(object):
305 """Wrap entries in the _type_equality_funcs registry to make them deep
306 copyable."""
308 def __init__(self, function):
309 self.function = function
311 def __deepcopy__(self, memo):
312 memo[id(self)] = self
315 class TestCase(object):
316 """A class whose instances are single test cases.
318 By default, the test code itself should be placed in a method named
319 'runTest'.
321 If the fixture may be used for many test cases, create as
322 many test methods as are needed. When instantiating such a TestCase
323 subclass, specify in the constructor arguments the name of the test method
324 that the instance is to execute.
326 Test authors should subclass TestCase for their own tests. Construction
327 and deconstruction of the test's environment ('fixture') can be
328 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
330 If it is necessary to override the __init__ method, the base class
331 __init__ method must always be called. It is important that subclasses
332 should not change the signature of their __init__ method, since instances
333 of the classes are instantiated automatically by parts of the framework
334 in order to be run.
337 # This attribute determines which exception will be raised when
338 # the instance's assertion methods fail; test methods raising this
339 # exception will be deemed to have 'failed' rather than 'errored'
341 failureException = AssertionError
343 # This attribute determines whether long messages (including repr of
344 # objects used in assert methods) will be printed on failure in *addition*
345 # to any explicit message passed.
347 longMessage = False
350 def __init__(self, methodName='runTest'):
351 """Create an instance of the class that will use the named test
352 method when executed. Raises a ValueError if the instance does
353 not have a method with the specified name.
355 self._testMethodName = methodName
356 self._resultForDoCleanups = None
357 try:
358 testMethod = getattr(self, methodName)
359 except AttributeError:
360 raise ValueError("no such test method in %s: %s" % \
361 (self.__class__, methodName))
362 self._testMethodDoc = testMethod.__doc__
363 self._cleanups = []
365 # Map types to custom assertEqual functions that will compare
366 # instances of said type in more detail to generate a more useful
367 # error message.
368 self._type_equality_funcs = {}
369 self.addTypeEqualityFunc(dict, self.assertDictEqual)
370 self.addTypeEqualityFunc(list, self.assertListEqual)
371 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
372 self.addTypeEqualityFunc(set, self.assertSetEqual)
373 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
375 def addTypeEqualityFunc(self, typeobj, function):
376 """Add a type specific assertEqual style function to compare a type.
378 This method is for use by TestCase subclasses that need to register
379 their own type equality functions to provide nicer error messages.
381 Args:
382 typeobj: The data type to call this function on when both values
383 are of the same type in assertEqual().
384 function: The callable taking two arguments and an optional
385 msg= argument that raises self.failureException with a
386 useful error message when the two arguments are not equal.
388 self._type_equality_funcs[typeobj] = _AssertWrapper(function)
390 def addCleanup(self, function, *args, **kwargs):
391 """Add a function, with arguments, to be called when the test is
392 completed. Functions added are called on a LIFO basis and are
393 called after tearDown on test failure or success.
395 Cleanup items are called even if setUp fails (unlike tearDown)."""
396 self._cleanups.append((function, args, kwargs))
398 def setUp(self):
399 "Hook method for setting up the test fixture before exercising it."
400 pass
402 def tearDown(self):
403 "Hook method for deconstructing the test fixture after testing it."
404 pass
406 def countTestCases(self):
407 return 1
409 def defaultTestResult(self):
410 return TestResult()
412 def shortDescription(self):
413 """Returns both the test method name and first line of its docstring.
415 If no docstring is given, only returns the method name.
417 This method overrides unittest.TestCase.shortDescription(), which
418 only returns the first line of the docstring, obscuring the name
419 of the test upon failure.
421 desc = str(self)
422 doc_first_line = None
424 if self._testMethodDoc:
425 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
426 if doc_first_line:
427 desc = '\n'.join((desc, doc_first_line))
428 return desc
430 def id(self):
431 return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
433 def __eq__(self, other):
434 if type(self) is not type(other):
435 return NotImplemented
437 return self._testMethodName == other._testMethodName
439 def __ne__(self, other):
440 return not self == other
442 def __hash__(self):
443 return hash((type(self), self._testMethodName))
445 def __str__(self):
446 return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
448 def __repr__(self):
449 return "<%s testMethod=%s>" % \
450 (_strclass(self.__class__), self._testMethodName)
452 def run(self, result=None):
453 orig_result = result
454 if result is None:
455 result = self.defaultTestResult()
456 startTestRun = getattr(result, 'startTestRun', None)
457 if startTestRun is not None:
458 startTestRun()
460 self._resultForDoCleanups = result
461 result.startTest(self)
462 if getattr(self.__class__, "__unittest_skip__", False):
463 # If the whole class was skipped.
464 try:
465 result.addSkip(self, self.__class__.__unittest_skip_why__)
466 finally:
467 result.stopTest(self)
468 return
469 testMethod = getattr(self, self._testMethodName)
470 try:
471 success = False
472 try:
473 self.setUp()
474 except SkipTest as e:
475 result.addSkip(self, str(e))
476 except Exception:
477 result.addError(self, sys.exc_info())
478 else:
479 try:
480 testMethod()
481 except self.failureException:
482 result.addFailure(self, sys.exc_info())
483 except _ExpectedFailure as e:
484 result.addExpectedFailure(self, e.exc_info)
485 except _UnexpectedSuccess:
486 result.addUnexpectedSuccess(self)
487 except SkipTest as e:
488 result.addSkip(self, str(e))
489 except Exception:
490 result.addError(self, sys.exc_info())
491 else:
492 success = True
494 try:
495 self.tearDown()
496 except Exception:
497 result.addError(self, sys.exc_info())
498 success = False
500 cleanUpSuccess = self.doCleanups()
501 success = success and cleanUpSuccess
502 if success:
503 result.addSuccess(self)
504 finally:
505 result.stopTest(self)
506 if orig_result is None:
507 stopTestRun = getattr(result, 'stopTestRun', None)
508 if stopTestRun is not None:
509 stopTestRun()
511 def doCleanups(self):
512 """Execute all cleanup functions. Normally called for you after
513 tearDown."""
514 result = self._resultForDoCleanups
515 ok = True
516 while self._cleanups:
517 function, args, kwargs = self._cleanups.pop(-1)
518 try:
519 function(*args, **kwargs)
520 except Exception:
521 ok = False
522 result.addError(self, sys.exc_info())
523 return ok
525 def __call__(self, *args, **kwds):
526 return self.run(*args, **kwds)
528 def debug(self):
529 """Run the test without collecting errors in a TestResult"""
530 self.setUp()
531 getattr(self, self._testMethodName)()
532 self.tearDown()
534 def skipTest(self, reason):
535 """Skip this test."""
536 raise SkipTest(reason)
538 def fail(self, msg=None):
539 """Fail immediately, with the given message."""
540 raise self.failureException(msg)
542 def assertFalse(self, expr, msg=None):
543 "Fail the test if the expression is true."
544 if expr:
545 msg = self._formatMessage(msg, "%r is not False" % expr)
546 raise self.failureException(msg)
548 def assertTrue(self, expr, msg=None):
549 """Fail the test unless the expression is true."""
550 if not expr:
551 msg = self._formatMessage(msg, "%r is not True" % expr)
552 raise self.failureException(msg)
554 def _formatMessage(self, msg, standardMsg):
555 """Honour the longMessage attribute when generating failure messages.
556 If longMessage is False this means:
557 * Use only an explicit message if it is provided
558 * Otherwise use the standard message for the assert
560 If longMessage is True:
561 * Use the standard message
562 * If an explicit message is provided, plus ' : ' and the explicit message
564 if not self.longMessage:
565 return msg or standardMsg
566 if msg is None:
567 return standardMsg
568 return standardMsg + ' : ' + msg
571 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
572 """Fail unless an exception of class excClass is thrown
573 by callableObj when invoked with arguments args and keyword
574 arguments kwargs. If a different type of exception is
575 thrown, it will not be caught, and the test case will be
576 deemed to have suffered an error, exactly as for an
577 unexpected exception.
579 If called with callableObj omitted or None, will return a
580 context object used like this::
582 with self.assertRaises(some_error_class):
583 do_something()
585 context = _AssertRaisesContext(excClass, self, callableObj)
586 if callableObj is None:
587 return context
588 with context:
589 callableObj(*args, **kwargs)
591 def _getAssertEqualityFunc(self, first, second):
592 """Get a detailed comparison function for the types of the two args.
594 Returns: A callable accepting (first, second, msg=None) that will
595 raise a failure exception if first != second with a useful human
596 readable error message for those types.
599 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
600 # and vice versa. I opted for the conservative approach in case
601 # subclasses are not intended to be compared in detail to their super
602 # class instances using a type equality func. This means testing
603 # subtypes won't automagically use the detailed comparison. Callers
604 # should use their type specific assertSpamEqual method to compare
605 # subclasses if the detailed comparison is desired and appropriate.
606 # See the discussion in http://bugs.python.org/issue2578.
608 if type(first) is type(second):
609 asserter = self._type_equality_funcs.get(type(first))
610 if asserter is not None:
611 return asserter.function
613 return self._baseAssertEqual
615 def _baseAssertEqual(self, first, second, msg=None):
616 """The default assertEqual implementation, not type specific."""
617 if not first == second:
618 standardMsg = '%r != %r' % (first, second)
619 msg = self._formatMessage(msg, standardMsg)
620 raise self.failureException(msg)
622 def assertEqual(self, first, second, msg=None):
623 """Fail if the two objects are unequal as determined by the '=='
624 operator.
626 assertion_func = self._getAssertEqualityFunc(first, second)
627 assertion_func(first, second, msg=msg)
629 def assertNotEqual(self, first, second, msg=None):
630 """Fail if the two objects are equal as determined by the '=='
631 operator.
633 if not first != second:
634 msg = self._formatMessage(msg, '%r == %r' % (first, second))
635 raise self.failureException(msg)
637 def assertAlmostEqual(self, first, second, *, places=7, msg=None):
638 """Fail if the two objects are unequal as determined by their
639 difference rounded to the given number of decimal places
640 (default 7) and comparing to zero.
642 Note that decimal places (from zero) are usually not the same
643 as significant digits (measured from the most signficant digit).
645 if round(abs(second-first), places) != 0:
646 standardMsg = '%r != %r within %r places' % (first, second, places)
647 msg = self._formatMessage(msg, standardMsg)
648 raise self.failureException(msg)
650 def assertNotAlmostEqual(self, first, second, *, places=7, msg=None):
651 """Fail if the two objects are equal as determined by their
652 difference rounded to the given number of decimal places
653 (default 7) and comparing to zero.
655 Note that decimal places (from zero) are usually not the same
656 as significant digits (measured from the most signficant digit).
658 if round(abs(second-first), places) == 0:
659 standardMsg = '%r == %r within %r places' % (first, second, places)
660 msg = self._formatMessage(msg, standardMsg)
661 raise self.failureException(msg)
663 # Synonyms for assertion methods
665 # The plurals are undocumented. Keep them that way to discourage use.
666 # Do not add more. Do not remove.
667 # Going through a deprecation cycle on these would annoy many people.
668 assertEquals = assertEqual
669 assertNotEquals = assertNotEqual
670 assertAlmostEquals = assertAlmostEqual
671 assertNotAlmostEquals = assertNotAlmostEqual
672 assert_ = assertTrue
674 # These fail* assertion method names are pending deprecation and will
675 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
676 def _deprecate(original_func):
677 def deprecated_func(*args, **kwargs):
678 warnings.warn(
679 'Please use {0} instead.'.format(original_func.__name__),
680 PendingDeprecationWarning, 2)
681 return original_func(*args, **kwargs)
682 return deprecated_func
684 failUnlessEqual = _deprecate(assertEqual)
685 failIfEqual = _deprecate(assertNotEqual)
686 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
687 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
688 failUnless = _deprecate(assertTrue)
689 failUnlessRaises = _deprecate(assertRaises)
690 failIf = _deprecate(assertFalse)
692 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
693 """An equality assertion for ordered sequences (like lists and tuples).
695 For the purposes of this function, a valid ordered sequence type is one
696 which can be indexed, has a length, and has an equality operator.
698 Args:
699 seq1: The first sequence to compare.
700 seq2: The second sequence to compare.
701 seq_type: The expected datatype of the sequences, or None if no
702 datatype should be enforced.
703 msg: Optional message to use on failure instead of a list of
704 differences.
706 if seq_type != None:
707 seq_type_name = seq_type.__name__
708 if not isinstance(seq1, seq_type):
709 raise self.failureException('First sequence is not a %s: %r'
710 % (seq_type_name, seq1))
711 if not isinstance(seq2, seq_type):
712 raise self.failureException('Second sequence is not a %s: %r'
713 % (seq_type_name, seq2))
714 else:
715 seq_type_name = "sequence"
717 differing = None
718 try:
719 len1 = len(seq1)
720 except (TypeError, NotImplementedError):
721 differing = 'First %s has no length. Non-sequence?' % (
722 seq_type_name)
724 if differing is None:
725 try:
726 len2 = len(seq2)
727 except (TypeError, NotImplementedError):
728 differing = 'Second %s has no length. Non-sequence?' % (
729 seq_type_name)
731 if differing is None:
732 if seq1 == seq2:
733 return
735 seq1_repr = repr(seq1)
736 seq2_repr = repr(seq2)
737 if len(seq1_repr) > 30:
738 seq1_repr = seq1_repr[:30] + '...'
739 if len(seq2_repr) > 30:
740 seq2_repr = seq2_repr[:30] + '...'
741 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
742 differing = '%ss differ: %s != %s\n' % elements
744 for i in range(min(len1, len2)):
745 try:
746 item1 = seq1[i]
747 except (TypeError, IndexError, NotImplementedError):
748 differing += ('\nUnable to index element %d of first %s\n' %
749 (i, seq_type_name))
750 break
752 try:
753 item2 = seq2[i]
754 except (TypeError, IndexError, NotImplementedError):
755 differing += ('\nUnable to index element %d of second %s\n' %
756 (i, seq_type_name))
757 break
759 if item1 != item2:
760 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
761 (i, item1, item2))
762 break
763 else:
764 if (len1 == len2 and seq_type is None and
765 type(seq1) != type(seq2)):
766 # The sequences are the same, but have differing types.
767 return
769 if len1 > len2:
770 differing += ('\nFirst %s contains %d additional '
771 'elements.\n' % (seq_type_name, len1 - len2))
772 try:
773 differing += ('First extra element %d:\n%s\n' %
774 (len2, seq1[len2]))
775 except (TypeError, IndexError, NotImplementedError):
776 differing += ('Unable to index element %d '
777 'of first %s\n' % (len2, seq_type_name))
778 elif len1 < len2:
779 differing += ('\nSecond %s contains %d additional '
780 'elements.\n' % (seq_type_name, len2 - len1))
781 try:
782 differing += ('First extra element %d:\n%s\n' %
783 (len1, seq2[len1]))
784 except (TypeError, IndexError, NotImplementedError):
785 differing += ('Unable to index element %d '
786 'of second %s\n' % (len1, seq_type_name))
787 standardMsg = differing + '\n' + '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(),
788 pprint.pformat(seq2).splitlines()))
789 msg = self._formatMessage(msg, standardMsg)
790 self.fail(msg)
792 def assertListEqual(self, list1, list2, msg=None):
793 """A list-specific equality assertion.
795 Args:
796 list1: The first list to compare.
797 list2: The second list to compare.
798 msg: Optional message to use on failure instead of a list of
799 differences.
802 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
804 def assertTupleEqual(self, tuple1, tuple2, msg=None):
805 """A tuple-specific equality assertion.
807 Args:
808 tuple1: The first tuple to compare.
809 tuple2: The second tuple to compare.
810 msg: Optional message to use on failure instead of a list of
811 differences.
813 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
815 def assertSetEqual(self, set1, set2, msg=None):
816 """A set-specific equality assertion.
818 Args:
819 set1: The first set to compare.
820 set2: The second set to compare.
821 msg: Optional message to use on failure instead of a list of
822 differences.
824 For more general containership equality, assertSameElements will work
825 with things other than sets. This uses ducktyping to support
826 different types of sets, and is optimized for sets specifically
827 (parameters must support a difference method).
829 try:
830 difference1 = set1.difference(set2)
831 except TypeError as e:
832 self.fail('invalid type when attempting set difference: %s' % e)
833 except AttributeError as e:
834 self.fail('first argument does not support set difference: %s' % e)
836 try:
837 difference2 = set2.difference(set1)
838 except TypeError as e:
839 self.fail('invalid type when attempting set difference: %s' % e)
840 except AttributeError as e:
841 self.fail('second argument does not support set difference: %s' % e)
843 if not (difference1 or difference2):
844 return
846 lines = []
847 if difference1:
848 lines.append('Items in the first set but not the second:')
849 for item in difference1:
850 lines.append(repr(item))
851 if difference2:
852 lines.append('Items in the second set but not the first:')
853 for item in difference2:
854 lines.append(repr(item))
856 standardMsg = '\n'.join(lines)
857 self.fail(self._formatMessage(msg, standardMsg))
859 def assertIn(self, member, container, msg=None):
860 """Just like self.assertTrue(a in b), but with a nicer default message."""
861 if member not in container:
862 standardMsg = '%r not found in %r' % (member, container)
863 self.fail(self._formatMessage(msg, standardMsg))
865 def assertNotIn(self, member, container, msg=None):
866 """Just like self.assertTrue(a not in b), but with a nicer default message."""
867 if member in container:
868 standardMsg = '%r unexpectedly found in %r' % (member, container)
869 self.fail(self._formatMessage(msg, standardMsg))
871 def assertIs(self, expr1, expr2, msg=None):
872 """Just like self.assertTrue(a is b), but with a nicer default message."""
873 if expr1 is not expr2:
874 standardMsg = '%r is not %r' % (expr1, expr2)
875 self.fail(self._formatMessage(msg, standardMsg))
877 def assertIsNot(self, expr1, expr2, msg=None):
878 """Just like self.assertTrue(a is not b), but with a nicer default message."""
879 if expr1 is expr2:
880 standardMsg = 'unexpectedly identical: %r' % (expr1,)
881 self.fail(self._formatMessage(msg, standardMsg))
883 def assertDictEqual(self, d1, d2, msg=None):
884 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
885 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
887 if d1 != d2:
888 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
889 pprint.pformat(d1).splitlines(),
890 pprint.pformat(d2).splitlines())))
891 self.fail(self._formatMessage(msg, standardMsg))
893 def assertDictContainsSubset(self, expected, actual, msg=None):
894 """Checks whether actual is a superset of expected."""
895 missing = []
896 mismatched = []
897 for key, value in expected.items():
898 if key not in actual:
899 missing.append(key)
900 elif value != actual[key]:
901 mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key]))
903 if not (missing or mismatched):
904 return
906 standardMsg = ''
907 if missing:
908 standardMsg = 'Missing: %r' % ','.join(missing)
909 if mismatched:
910 if standardMsg:
911 standardMsg += '; '
912 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
914 self.fail(self._formatMessage(msg, standardMsg))
916 def assertSameElements(self, expected_seq, actual_seq, msg=None):
917 """An unordered sequence specific comparison.
919 Raises with an error message listing which elements of expected_seq
920 are missing from actual_seq and vice versa if any.
922 try:
923 expected = set(expected_seq)
924 actual = set(actual_seq)
925 missing = list(expected.difference(actual))
926 unexpected = list(actual.difference(expected))
927 missing.sort()
928 unexpected.sort()
929 except TypeError:
930 # Fall back to slower list-compare if any of the objects are
931 # not hashable.
932 expected = list(expected_seq)
933 actual = list(actual_seq)
934 try:
935 expected.sort()
936 actual.sort()
937 except TypeError:
938 missing, unexpected = _UnorderableListDifference(expected, actual)
939 else:
940 missing, unexpected = _SortedListDifference(expected, actual)
941 errors = []
942 if missing:
943 errors.append('Expected, but missing:\n %r' % missing)
944 if unexpected:
945 errors.append('Unexpected, but present:\n %r' % unexpected)
946 if errors:
947 standardMsg = '\n'.join(errors)
948 self.fail(self._formatMessage(msg, standardMsg))
950 def assertMultiLineEqual(self, first, second, msg=None):
951 """Assert that two multi-line strings are equal."""
952 self.assert_(isinstance(first, str), (
953 'First argument is not a string'))
954 self.assert_(isinstance(second, str), (
955 'Second argument is not a string'))
957 if first != second:
958 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True)))
959 self.fail(self._formatMessage(msg, standardMsg))
961 def assertLess(self, a, b, msg=None):
962 """Just like self.assertTrue(a < b), but with a nicer default message."""
963 if not a < b:
964 standardMsg = '%r not less than %r' % (a, b)
965 self.fail(self._formatMessage(msg, standardMsg))
967 def assertLessEqual(self, a, b, msg=None):
968 """Just like self.assertTrue(a <= b), but with a nicer default message."""
969 if not a <= b:
970 standardMsg = '%r not less than or equal to %r' % (a, b)
971 self.fail(self._formatMessage(msg, standardMsg))
973 def assertGreater(self, a, b, msg=None):
974 """Just like self.assertTrue(a > b), but with a nicer default message."""
975 if not a > b:
976 standardMsg = '%r not greater than %r' % (a, b)
977 self.fail(self._formatMessage(msg, standardMsg))
979 def assertGreaterEqual(self, a, b, msg=None):
980 """Just like self.assertTrue(a >= b), but with a nicer default message."""
981 if not a >= b:
982 standardMsg = '%r not greater than or equal to %r' % (a, b)
983 self.fail(self._formatMessage(msg, standardMsg))
985 def assertIsNone(self, obj, msg=None):
986 """Same as self.assertTrue(obj is None), with a nicer default message."""
987 if obj is not None:
988 standardMsg = '%r is not None' % obj
989 self.fail(self._formatMessage(msg, standardMsg))
991 def assertIsNotNone(self, obj, msg=None):
992 """Included for symmetry with assertIsNone."""
993 if obj is None:
994 standardMsg = 'unexpectedly None'
995 self.fail(self._formatMessage(msg, standardMsg))
997 def assertRaisesRegexp(self, expected_exception, expected_regexp,
998 callable_obj=None, *args, **kwargs):
999 """Asserts that the message in a raised exception matches a regexp.
1001 Args:
1002 expected_exception: Exception class expected to be raised.
1003 expected_regexp: Regexp (re pattern object or string) expected
1004 to be found in error message.
1005 callable_obj: Function to be called.
1006 args: Extra args.
1007 kwargs: Extra kwargs.
1009 context = _AssertRaisesContext(expected_exception, self, callable_obj,
1010 expected_regexp)
1011 if callable_obj is None:
1012 return context
1013 with context:
1014 callable_obj(*args, **kwargs)
1016 def assertRegexpMatches(self, text, expected_regex, msg=None):
1017 if isinstance(expected_regex, (str, bytes)):
1018 expected_regex = re.compile(expected_regex)
1019 if not expected_regex.search(text):
1020 msg = msg or "Regexp didn't match"
1021 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
1022 raise self.failureException(msg)
1025 def _SortedListDifference(expected, actual):
1026 """Finds elements in only one or the other of two, sorted input lists.
1028 Returns a two-element tuple of lists. The first list contains those
1029 elements in the "expected" list but not in the "actual" list, and the
1030 second contains those elements in the "actual" list but not in the
1031 "expected" list. Duplicate elements in either input list are ignored.
1033 i = j = 0
1034 missing = []
1035 unexpected = []
1036 while True:
1037 try:
1038 e = expected[i]
1039 a = actual[j]
1040 if e < a:
1041 missing.append(e)
1042 i += 1
1043 while expected[i] == e:
1044 i += 1
1045 elif e > a:
1046 unexpected.append(a)
1047 j += 1
1048 while actual[j] == a:
1049 j += 1
1050 else:
1051 i += 1
1052 try:
1053 while expected[i] == e:
1054 i += 1
1055 finally:
1056 j += 1
1057 while actual[j] == a:
1058 j += 1
1059 except IndexError:
1060 missing.extend(expected[i:])
1061 unexpected.extend(actual[j:])
1062 break
1063 return missing, unexpected
1065 def _UnorderableListDifference(expected, actual):
1066 """Same behavior as _SortedListDifference but
1067 for lists of unorderable items (like dicts).
1069 As it does a linear search per item (remove) it
1070 has O(n*n) performance."""
1071 missing = []
1072 while expected:
1073 item = expected.pop()
1074 try:
1075 actual.remove(item)
1076 except ValueError:
1077 missing.append(item)
1079 # anything left in actual is unexpected
1080 return missing, actual
1082 class TestSuite(object):
1083 """A test suite is a composite test consisting of a number of TestCases.
1085 For use, create an instance of TestSuite, then add test case instances.
1086 When all tests have been added, the suite can be passed to a test
1087 runner, such as TextTestRunner. It will run the individual test cases
1088 in the order in which they were added, aggregating the results. When
1089 subclassing, do not forget to call the base class constructor.
1091 def __init__(self, tests=()):
1092 self._tests = []
1093 self.addTests(tests)
1095 def __repr__(self):
1096 return "<%s tests=%s>" % (_strclass(self.__class__), list(self))
1098 def __eq__(self, other):
1099 if not isinstance(other, self.__class__):
1100 return NotImplemented
1101 return list(self) == list(other)
1103 def __ne__(self, other):
1104 return not self == other
1106 def __iter__(self):
1107 return iter(self._tests)
1109 def countTestCases(self):
1110 cases = 0
1111 for test in self:
1112 cases += test.countTestCases()
1113 return cases
1115 def addTest(self, test):
1116 # sanity checks
1117 if not hasattr(test, '__call__'):
1118 raise TypeError("the test to add must be callable")
1119 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
1120 raise TypeError("TestCases and TestSuites must be instantiated "
1121 "before passing them to addTest()")
1122 self._tests.append(test)
1124 def addTests(self, tests):
1125 if isinstance(tests, str):
1126 raise TypeError("tests must be an iterable of tests, not a string")
1127 for test in tests:
1128 self.addTest(test)
1130 def run(self, result):
1131 for test in self:
1132 if result.shouldStop:
1133 break
1134 test(result)
1135 return result
1137 def __call__(self, *args, **kwds):
1138 return self.run(*args, **kwds)
1140 def debug(self):
1141 """Run the tests without collecting errors in a TestResult"""
1142 for test in self:
1143 test.debug()
1146 class FunctionTestCase(TestCase):
1147 """A test case that wraps a test function.
1149 This is useful for slipping pre-existing test functions into the
1150 unittest framework. Optionally, set-up and tidy-up functions can be
1151 supplied. As with TestCase, the tidy-up ('tearDown') function will
1152 always be called if the set-up ('setUp') function ran successfully.
1155 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1156 super(FunctionTestCase, self).__init__()
1157 self._setUpFunc = setUp
1158 self._tearDownFunc = tearDown
1159 self._testFunc = testFunc
1160 self._description = description
1162 def setUp(self):
1163 if self._setUpFunc is not None:
1164 self._setUpFunc()
1166 def tearDown(self):
1167 if self._tearDownFunc is not None:
1168 self._tearDownFunc()
1170 def runTest(self):
1171 self._testFunc()
1173 def id(self):
1174 return self._testFunc.__name__
1176 def __eq__(self, other):
1177 if not isinstance(other, self.__class__):
1178 return NotImplemented
1180 return self._setUpFunc == other._setUpFunc and \
1181 self._tearDownFunc == other._tearDownFunc and \
1182 self._testFunc == other._testFunc and \
1183 self._description == other._description
1185 def __ne__(self, other):
1186 return not self == other
1188 def __hash__(self):
1189 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1190 self._testFunc, self._description))
1192 def __str__(self):
1193 return "%s (%s)" % (_strclass(self.__class__), self._testFunc.__name__)
1195 def __repr__(self):
1196 return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc)
1198 def shortDescription(self):
1199 if self._description is not None:
1200 return self._description
1201 doc = self._testFunc.__doc__
1202 return doc and doc.split("\n")[0].strip() or None
1206 ##############################################################################
1207 # Locating and loading tests
1208 ##############################################################################
1210 def CmpToKey(mycmp):
1211 'Convert a cmp= function into a key= function'
1212 class K(object):
1213 def __init__(self, obj, *args):
1214 self.obj = obj
1215 def __lt__(self, other):
1216 return mycmp(self.obj, other.obj) == -1
1217 return K
1219 def three_way_cmp(x, y):
1220 """Return -1 if x < y, 0 if x == y and 1 if x > y"""
1221 return (x > y) - (x < y)
1223 class TestLoader(object):
1225 This class is responsible for loading tests according to various criteria
1226 and returning them wrapped in a TestSuite
1228 testMethodPrefix = 'test'
1229 sortTestMethodsUsing = staticmethod(three_way_cmp)
1230 suiteClass = TestSuite
1232 def loadTestsFromTestCase(self, testCaseClass):
1233 """Return a suite of all tests cases contained in testCaseClass"""
1234 if issubclass(testCaseClass, TestSuite):
1235 raise TypeError("Test cases should not be derived from TestSuite." \
1236 " Maybe you meant to derive from TestCase?")
1237 testCaseNames = self.getTestCaseNames(testCaseClass)
1238 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1239 testCaseNames = ['runTest']
1240 suite = self.suiteClass(map(testCaseClass, testCaseNames))
1241 return suite
1243 def loadTestsFromModule(self, module):
1244 """Return a suite of all tests cases contained in the given module"""
1245 tests = []
1246 for name in dir(module):
1247 obj = getattr(module, name)
1248 if isinstance(obj, type) and issubclass(obj, TestCase):
1249 tests.append(self.loadTestsFromTestCase(obj))
1250 return self.suiteClass(tests)
1252 def loadTestsFromName(self, name, module=None):
1253 """Return a suite of all tests cases given a string specifier.
1255 The name may resolve either to a module, a test case class, a
1256 test method within a test case class, or a callable object which
1257 returns a TestCase or TestSuite instance.
1259 The method optionally resolves the names relative to a given module.
1261 parts = name.split('.')
1262 if module is None:
1263 parts_copy = parts[:]
1264 while parts_copy:
1265 try:
1266 module = __import__('.'.join(parts_copy))
1267 break
1268 except ImportError:
1269 del parts_copy[-1]
1270 if not parts_copy:
1271 raise
1272 parts = parts[1:]
1273 obj = module
1274 for part in parts:
1275 parent, obj = obj, getattr(obj, part)
1277 if isinstance(obj, types.ModuleType):
1278 return self.loadTestsFromModule(obj)
1279 elif isinstance(obj, type) and issubclass(obj, TestCase):
1280 return self.loadTestsFromTestCase(obj)
1281 elif (isinstance(obj, types.FunctionType) and
1282 isinstance(parent, type) and
1283 issubclass(parent, TestCase)):
1284 name = obj.__name__
1285 inst = parent(name)
1286 # static methods follow a different path
1287 if not isinstance(getattr(inst, name), types.FunctionType):
1288 return TestSuite([inst])
1289 elif isinstance(obj, TestSuite):
1290 return obj
1292 if hasattr(obj, '__call__'):
1293 test = obj()
1294 if isinstance(test, TestSuite):
1295 return test
1296 elif isinstance(test, TestCase):
1297 return TestSuite([test])
1298 else:
1299 raise TypeError("calling %s returned %s, not a test" %
1300 (obj, test))
1301 else:
1302 raise TypeError("don't know how to make test from: %s" % obj)
1304 def loadTestsFromNames(self, names, module=None):
1305 """Return a suite of all tests cases found using the given sequence
1306 of string specifiers. See 'loadTestsFromName()'.
1308 suites = [self.loadTestsFromName(name, module) for name in names]
1309 return self.suiteClass(suites)
1311 def getTestCaseNames(self, testCaseClass):
1312 """Return a sorted sequence of method names found within testCaseClass
1314 def isTestMethod(attrname, testCaseClass=testCaseClass,
1315 prefix=self.testMethodPrefix):
1316 return attrname.startswith(prefix) and \
1317 hasattr(getattr(testCaseClass, attrname), '__call__')
1318 testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
1319 if self.sortTestMethodsUsing:
1320 testFnNames.sort(key=CmpToKey(self.sortTestMethodsUsing))
1321 return testFnNames
1325 defaultTestLoader = TestLoader()
1328 ##############################################################################
1329 # Patches for old functions: these functions should be considered obsolete
1330 ##############################################################################
1332 def _makeLoader(prefix, sortUsing, suiteClass=None):
1333 loader = TestLoader()
1334 loader.sortTestMethodsUsing = sortUsing
1335 loader.testMethodPrefix = prefix
1336 if suiteClass: loader.suiteClass = suiteClass
1337 return loader
1339 def getTestCaseNames(testCaseClass, prefix, sortUsing=three_way_cmp):
1340 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1342 def makeSuite(testCaseClass, prefix='test', sortUsing=three_way_cmp,
1343 suiteClass=TestSuite):
1344 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(
1345 testCaseClass)
1347 def findTestCases(module, prefix='test', sortUsing=three_way_cmp,
1348 suiteClass=TestSuite):
1349 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(
1350 module)
1353 ##############################################################################
1354 # Text UI
1355 ##############################################################################
1357 class _WritelnDecorator(object):
1358 """Used to decorate file-like objects with a handy 'writeln' method"""
1359 def __init__(self,stream):
1360 self.stream = stream
1362 def __getattr__(self, attr):
1363 return getattr(self.stream,attr)
1365 def writeln(self, arg=None):
1366 if arg:
1367 self.write(arg)
1368 self.write('\n') # text-mode streams translate to \r\n if needed
1371 class _TextTestResult(TestResult):
1372 """A test result class that can print formatted text results to a stream.
1374 Used by TextTestRunner.
1376 separator1 = '=' * 70
1377 separator2 = '-' * 70
1379 def __init__(self, stream, descriptions, verbosity):
1380 super(_TextTestResult, self).__init__()
1381 self.stream = stream
1382 self.showAll = verbosity > 1
1383 self.dots = verbosity == 1
1384 self.descriptions = descriptions
1386 def getDescription(self, test):
1387 if self.descriptions:
1388 return test.shortDescription() or str(test)
1389 else:
1390 return str(test)
1392 def startTest(self, test):
1393 super(_TextTestResult, self).startTest(test)
1394 if self.showAll:
1395 self.stream.write(self.getDescription(test))
1396 self.stream.write(" ... ")
1397 self.stream.flush()
1399 def addSuccess(self, test):
1400 super(_TextTestResult, self).addSuccess(test)
1401 if self.showAll:
1402 self.stream.writeln("ok")
1403 elif self.dots:
1404 self.stream.write('.')
1405 self.stream.flush()
1407 def addError(self, test, err):
1408 super(_TextTestResult, self).addError(test, err)
1409 if self.showAll:
1410 self.stream.writeln("ERROR")
1411 elif self.dots:
1412 self.stream.write('E')
1413 self.stream.flush()
1415 def addFailure(self, test, err):
1416 super(_TextTestResult, self).addFailure(test, err)
1417 if self.showAll:
1418 self.stream.writeln("FAIL")
1419 elif self.dots:
1420 self.stream.write('F')
1421 self.stream.flush()
1423 def addSkip(self, test, reason):
1424 super(_TextTestResult, self).addSkip(test, reason)
1425 if self.showAll:
1426 self.stream.writeln("skipped {0!r}".format(reason))
1427 elif self.dots:
1428 self.stream.write("s")
1429 self.stream.flush()
1431 def addExpectedFailure(self, test, err):
1432 super(_TextTestResult, self).addExpectedFailure(test, err)
1433 if self.showAll:
1434 self.stream.writeln("expected failure")
1435 elif self.dots:
1436 self.stream.write("x")
1437 self.stream.flush()
1439 def addUnexpectedSuccess(self, test):
1440 super(_TextTestResult, self).addUnexpectedSuccess(test)
1441 if self.showAll:
1442 self.stream.writeln("unexpected success")
1443 elif self.dots:
1444 self.stream.write("u")
1445 self.stream.flush()
1447 def printErrors(self):
1448 if self.dots or self.showAll:
1449 self.stream.writeln()
1450 self.printErrorList('ERROR', self.errors)
1451 self.printErrorList('FAIL', self.failures)
1453 def printErrorList(self, flavour, errors):
1454 for test, err in errors:
1455 self.stream.writeln(self.separator1)
1456 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1457 self.stream.writeln(self.separator2)
1458 self.stream.writeln("%s" % err)
1461 class TextTestRunner(object):
1462 """A test runner class that displays results in textual form.
1464 It prints out the names of tests as they are run, errors as they
1465 occur, and a summary of the results at the end of the test run.
1467 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
1468 self.stream = _WritelnDecorator(stream)
1469 self.descriptions = descriptions
1470 self.verbosity = verbosity
1472 def _makeResult(self):
1473 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
1475 def run(self, test):
1476 "Run the given test case or test suite."
1477 result = self._makeResult()
1478 startTime = time.time()
1479 startTestRun = getattr(result, 'startTestRun', None)
1480 if startTestRun is not None:
1481 startTestRun()
1482 try:
1483 test(result)
1484 finally:
1485 stopTestRun = getattr(result, 'stopTestRun', None)
1486 if stopTestRun is not None:
1487 stopTestRun()
1488 stopTime = time.time()
1489 timeTaken = stopTime - startTime
1490 result.printErrors()
1491 self.stream.writeln(result.separator2)
1492 run = result.testsRun
1493 self.stream.writeln("Ran %d test%s in %.3fs" %
1494 (run, run != 1 and "s" or "", timeTaken))
1495 self.stream.writeln()
1496 results = map(len, (result.expectedFailures,
1497 result.unexpectedSuccesses,
1498 result.skipped))
1499 expectedFails, unexpectedSuccesses, skipped = results
1500 infos = []
1501 if not result.wasSuccessful():
1502 self.stream.write("FAILED")
1503 failed, errored = len(result.failures), len(result.errors)
1504 if failed:
1505 infos.append("failures=%d" % failed)
1506 if errored:
1507 infos.append("errors=%d" % errored)
1508 else:
1509 self.stream.write("OK")
1510 if skipped:
1511 infos.append("skipped=%d" % skipped)
1512 if expectedFails:
1513 infos.append("expected failures=%d" % expectedFails)
1514 if unexpectedSuccesses:
1515 infos.append("unexpected successes=%d" % unexpectedSuccesses)
1516 if infos:
1517 self.stream.writeln(" (%s)" % (", ".join(infos),))
1518 else:
1519 self.stream.write("\n")
1520 return result
1524 ##############################################################################
1525 # Facilities for running tests from the command line
1526 ##############################################################################
1528 class TestProgram(object):
1529 """A command-line program that runs a set of tests; this is primarily
1530 for making test modules conveniently executable.
1532 USAGE = """\
1533 Usage: %(progName)s [options] [test] [...]
1535 Options:
1536 -h, --help Show this message
1537 -v, --verbose Verbose output
1538 -q, --quiet Minimal output
1540 Examples:
1541 %(progName)s - run default set of tests
1542 %(progName)s MyTestSuite - run suite 'MyTestSuite'
1543 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1544 %(progName)s MyTestCase - run all 'test*' test methods
1545 in MyTestCase
1547 def __init__(self, module='__main__', defaultTest=None,
1548 argv=None, testRunner=TextTestRunner,
1549 testLoader=defaultTestLoader, exit=True):
1550 if isinstance(module, str):
1551 self.module = __import__(module)
1552 for part in module.split('.')[1:]:
1553 self.module = getattr(self.module, part)
1554 else:
1555 self.module = module
1556 if argv is None:
1557 argv = sys.argv
1559 self.exit = exit
1560 self.verbosity = 1
1561 self.defaultTest = defaultTest
1562 self.testRunner = testRunner
1563 self.testLoader = testLoader
1564 self.progName = os.path.basename(argv[0])
1565 self.parseArgs(argv)
1566 self.runTests()
1568 def usageExit(self, msg=None):
1569 if msg:
1570 print(msg)
1571 print(self.USAGE % self.__dict__)
1572 sys.exit(2)
1574 def parseArgs(self, argv):
1575 import getopt
1576 long_opts = ['help','verbose','quiet']
1577 try:
1578 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
1579 for opt, value in options:
1580 if opt in ('-h','-H','--help'):
1581 self.usageExit()
1582 if opt in ('-q','--quiet'):
1583 self.verbosity = 0
1584 if opt in ('-v','--verbose'):
1585 self.verbosity = 2
1586 if len(args) == 0 and self.defaultTest is None:
1587 self.test = self.testLoader.loadTestsFromModule(self.module)
1588 return
1589 if len(args) > 0:
1590 self.testNames = args
1591 else:
1592 self.testNames = (self.defaultTest,)
1593 self.createTests()
1594 except getopt.error as msg:
1595 self.usageExit(msg)
1597 def createTests(self):
1598 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1599 self.module)
1601 def runTests(self):
1602 if isinstance(self.testRunner, type):
1603 try:
1604 testRunner = self.testRunner(verbosity=self.verbosity)
1605 except TypeError:
1606 # didn't accept the verbosity argument
1607 testRunner = self.testRunner()
1608 else:
1609 # it is assumed to be a TestRunner instance
1610 testRunner = self.testRunner
1611 self.result = testRunner.run(self.test)
1612 if self.exit:
1613 sys.exit(not self.result.wasSuccessful())
1615 main = TestProgram
1618 ##############################################################################
1619 # Executing this module from the command line
1620 ##############################################################################
1622 if __name__ == "__main__":
1623 main(module=None)