1"""Test case implementation""" 2 3import sys 4import functools 5import difflib 6import logging 7import pprint 8import re 9import warnings 10import collections 11import contextlib 12import traceback 13import types 14 15from . import result 16from .util import (strclass, safe_repr, _count_diff_all_purpose, 17 _count_diff_hashable, _common_shorten_repr) 18 19__unittest = True 20 21_subtest_msg_sentinel = object() 22 23DIFF_OMITTED = ('\nDiff is %s characters long. ' 24 'Set self.maxDiff to None to see it.') 25 26class SkipTest(Exception): 27 """ 28 Raise this exception in a test to skip it. 29 30 Usually you can use TestCase.skipTest() or one of the skipping decorators 31 instead of raising this directly. 32 """ 33 34class _ShouldStop(Exception): 35 """ 36 The test should stop. 37 """ 38 39class _UnexpectedSuccess(Exception): 40 """ 41 The test was supposed to fail, but it didn't! 42 """ 43 44 45class _Outcome(object): 46 def __init__(self, result=None): 47 self.expecting_failure = False 48 self.result = result 49 self.result_supports_subtests = hasattr(result, "addSubTest") 50 self.success = True 51 self.skipped = [] 52 self.expectedFailure = None 53 self.errors = [] 54 55 @contextlib.contextmanager 56 def testPartExecutor(self, test_case, isTest=False): 57 old_success = self.success 58 self.success = True 59 try: 60 yield 61 except KeyboardInterrupt: 62 raise 63 except SkipTest as e: 64 self.success = False 65 self.skipped.append((test_case, str(e))) 66 except _ShouldStop: 67 pass 68 except: 69 exc_info = sys.exc_info() 70 if self.expecting_failure: 71 self.expectedFailure = exc_info 72 else: 73 self.success = False 74 self.errors.append((test_case, exc_info)) 75 # explicitly break a reference cycle: 76 # exc_info -> frame -> exc_info 77 exc_info = None 78 else: 79 if self.result_supports_subtests and self.success: 80 self.errors.append((test_case, None)) 81 finally: 82 self.success = self.success and old_success 83 84 85def _id(obj): 86 return obj 87 88 89_module_cleanups = [] 90def addModuleCleanup(function, /, *args, **kwargs): 91 """Same as addCleanup, except the cleanup items are called even if 92 setUpModule fails (unlike tearDownModule).""" 93 _module_cleanups.append((function, args, kwargs)) 94 95 96def doModuleCleanups(): 97 """Execute all module cleanup functions. Normally called for you after 98 tearDownModule.""" 99 exceptions = [] 100 while _module_cleanups: 101 function, args, kwargs = _module_cleanups.pop() 102 try: 103 function(*args, **kwargs) 104 except Exception as exc: 105 exceptions.append(exc) 106 if exceptions: 107 # Swallows all but first exception. If a multi-exception handler 108 # gets written we should use that here instead. 109 raise exceptions[0] 110 111 112def skip(reason): 113 """ 114 Unconditionally skip a test. 115 """ 116 def decorator(test_item): 117 if not isinstance(test_item, type): 118 @functools.wraps(test_item) 119 def skip_wrapper(*args, **kwargs): 120 raise SkipTest(reason) 121 test_item = skip_wrapper 122 123 test_item.__unittest_skip__ = True 124 test_item.__unittest_skip_why__ = reason 125 return test_item 126 if isinstance(reason, types.FunctionType): 127 test_item = reason 128 reason = '' 129 return decorator(test_item) 130 return decorator 131 132def skipIf(condition, reason): 133 """ 134 Skip a test if the condition is true. 135 """ 136 if condition: 137 return skip(reason) 138 return _id 139 140def skipUnless(condition, reason): 141 """ 142 Skip a test unless the condition is true. 143 """ 144 if not condition: 145 return skip(reason) 146 return _id 147 148def expectedFailure(test_item): 149 test_item.__unittest_expecting_failure__ = True 150 return test_item 151 152def _is_subtype(expected, basetype): 153 if isinstance(expected, tuple): 154 return all(_is_subtype(e, basetype) for e in expected) 155 return isinstance(expected, type) and issubclass(expected, basetype) 156 157class _BaseTestCaseContext: 158 159 def __init__(self, test_case): 160 self.test_case = test_case 161 162 def _raiseFailure(self, standardMsg): 163 msg = self.test_case._formatMessage(self.msg, standardMsg) 164 raise self.test_case.failureException(msg) 165 166class _AssertRaisesBaseContext(_BaseTestCaseContext): 167 168 def __init__(self, expected, test_case, expected_regex=None): 169 _BaseTestCaseContext.__init__(self, test_case) 170 self.expected = expected 171 self.test_case = test_case 172 if expected_regex is not None: 173 expected_regex = re.compile(expected_regex) 174 self.expected_regex = expected_regex 175 self.obj_name = None 176 self.msg = None 177 178 def handle(self, name, args, kwargs): 179 """ 180 If args is empty, assertRaises/Warns is being used as a 181 context manager, so check for a 'msg' kwarg and return self. 182 If args is not empty, call a callable passing positional and keyword 183 arguments. 184 """ 185 try: 186 if not _is_subtype(self.expected, self._base_type): 187 raise TypeError('%s() arg 1 must be %s' % 188 (name, self._base_type_str)) 189 if not args: 190 self.msg = kwargs.pop('msg', None) 191 if kwargs: 192 raise TypeError('%r is an invalid keyword argument for ' 193 'this function' % (next(iter(kwargs)),)) 194 return self 195 196 callable_obj, *args = args 197 try: 198 self.obj_name = callable_obj.__name__ 199 except AttributeError: 200 self.obj_name = str(callable_obj) 201 with self: 202 callable_obj(*args, **kwargs) 203 finally: 204 # bpo-23890: manually break a reference cycle 205 self = None 206 207 208class _AssertRaisesContext(_AssertRaisesBaseContext): 209 """A context manager used to implement TestCase.assertRaises* methods.""" 210 211 _base_type = BaseException 212 _base_type_str = 'an exception type or tuple of exception types' 213 214 def __enter__(self): 215 return self 216 217 def __exit__(self, exc_type, exc_value, tb): 218 if exc_type is None: 219 try: 220 exc_name = self.expected.__name__ 221 except AttributeError: 222 exc_name = str(self.expected) 223 if self.obj_name: 224 self._raiseFailure("{} not raised by {}".format(exc_name, 225 self.obj_name)) 226 else: 227 self._raiseFailure("{} not raised".format(exc_name)) 228 else: 229 traceback.clear_frames(tb) 230 if not issubclass(exc_type, self.expected): 231 # let unexpected exceptions pass through 232 return False 233 # store exception, without traceback, for later retrieval 234 self.exception = exc_value.with_traceback(None) 235 if self.expected_regex is None: 236 return True 237 238 expected_regex = self.expected_regex 239 if not expected_regex.search(str(exc_value)): 240 self._raiseFailure('"{}" does not match "{}"'.format( 241 expected_regex.pattern, str(exc_value))) 242 return True 243 244 245class _AssertWarnsContext(_AssertRaisesBaseContext): 246 """A context manager used to implement TestCase.assertWarns* methods.""" 247 248 _base_type = Warning 249 _base_type_str = 'a warning type or tuple of warning types' 250 251 def __enter__(self): 252 # The __warningregistry__'s need to be in a pristine state for tests 253 # to work properly. 254 for v in list(sys.modules.values()): 255 if getattr(v, '__warningregistry__', None): 256 v.__warningregistry__ = {} 257 self.warnings_manager = warnings.catch_warnings(record=True) 258 self.warnings = self.warnings_manager.__enter__() 259 warnings.simplefilter("always", self.expected) 260 return self 261 262 def __exit__(self, exc_type, exc_value, tb): 263 self.warnings_manager.__exit__(exc_type, exc_value, tb) 264 if exc_type is not None: 265 # let unexpected exceptions pass through 266 return 267 try: 268 exc_name = self.expected.__name__ 269 except AttributeError: 270 exc_name = str(self.expected) 271 first_matching = None 272 for m in self.warnings: 273 w = m.message 274 if not isinstance(w, self.expected): 275 continue 276 if first_matching is None: 277 first_matching = w 278 if (self.expected_regex is not None and 279 not self.expected_regex.search(str(w))): 280 continue 281 # store warning for later retrieval 282 self.warning = w 283 self.filename = m.filename 284 self.lineno = m.lineno 285 return 286 # Now we simply try to choose a helpful failure message 287 if first_matching is not None: 288 self._raiseFailure('"{}" does not match "{}"'.format( 289 self.expected_regex.pattern, str(first_matching))) 290 if self.obj_name: 291 self._raiseFailure("{} not triggered by {}".format(exc_name, 292 self.obj_name)) 293 else: 294 self._raiseFailure("{} not triggered".format(exc_name)) 295 296 297 298_LoggingWatcher = collections.namedtuple("_LoggingWatcher", 299 ["records", "output"]) 300 301 302class _CapturingHandler(logging.Handler): 303 """ 304 A logging handler capturing all (raw and formatted) logging output. 305 """ 306 307 def __init__(self): 308 logging.Handler.__init__(self) 309 self.watcher = _LoggingWatcher([], []) 310 311 def flush(self): 312 pass 313 314 def emit(self, record): 315 self.watcher.records.append(record) 316 msg = self.format(record) 317 self.watcher.output.append(msg) 318 319 320 321class _AssertLogsContext(_BaseTestCaseContext): 322 """A context manager used to implement TestCase.assertLogs().""" 323 324 LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s" 325 326 def __init__(self, test_case, logger_name, level): 327 _BaseTestCaseContext.__init__(self, test_case) 328 self.logger_name = logger_name 329 if level: 330 self.level = logging._nameToLevel.get(level, level) 331 else: 332 self.level = logging.INFO 333 self.msg = None 334 335 def __enter__(self): 336 if isinstance(self.logger_name, logging.Logger): 337 logger = self.logger = self.logger_name 338 else: 339 logger = self.logger = logging.getLogger(self.logger_name) 340 formatter = logging.Formatter(self.LOGGING_FORMAT) 341 handler = _CapturingHandler() 342 handler.setFormatter(formatter) 343 self.watcher = handler.watcher 344 self.old_handlers = logger.handlers[:] 345 self.old_level = logger.level 346 self.old_propagate = logger.propagate 347 logger.handlers = [handler] 348 logger.setLevel(self.level) 349 logger.propagate = False 350 return handler.watcher 351 352 def __exit__(self, exc_type, exc_value, tb): 353 self.logger.handlers = self.old_handlers 354 self.logger.propagate = self.old_propagate 355 self.logger.setLevel(self.old_level) 356 if exc_type is not None: 357 # let unexpected exceptions pass through 358 return False 359 if len(self.watcher.records) == 0: 360 self._raiseFailure( 361 "no logs of level {} or higher triggered on {}" 362 .format(logging.getLevelName(self.level), self.logger.name)) 363 364 365class _OrderedChainMap(collections.ChainMap): 366 def __iter__(self): 367 seen = set() 368 for mapping in self.maps: 369 for k in mapping: 370 if k not in seen: 371 seen.add(k) 372 yield k 373 374 375class TestCase(object): 376 """A class whose instances are single test cases. 377 378 By default, the test code itself should be placed in a method named 379 'runTest'. 380 381 If the fixture may be used for many test cases, create as 382 many test methods as are needed. When instantiating such a TestCase 383 subclass, specify in the constructor arguments the name of the test method 384 that the instance is to execute. 385 386 Test authors should subclass TestCase for their own tests. Construction 387 and deconstruction of the test's environment ('fixture') can be 388 implemented by overriding the 'setUp' and 'tearDown' methods respectively. 389 390 If it is necessary to override the __init__ method, the base class 391 __init__ method must always be called. It is important that subclasses 392 should not change the signature of their __init__ method, since instances 393 of the classes are instantiated automatically by parts of the framework 394 in order to be run. 395 396 When subclassing TestCase, you can set these attributes: 397 * failureException: determines which exception will be raised when 398 the instance's assertion methods fail; test methods raising this 399 exception will be deemed to have 'failed' rather than 'errored'. 400 * longMessage: determines whether long messages (including repr of 401 objects used in assert methods) will be printed on failure in *addition* 402 to any explicit message passed. 403 * maxDiff: sets the maximum length of a diff in failure messages 404 by assert methods using difflib. It is looked up as an instance 405 attribute so can be configured by individual tests if required. 406 """ 407 408 failureException = AssertionError 409 410 longMessage = True 411 412 maxDiff = 80*8 413 414 # If a string is longer than _diffThreshold, use normal comparison instead 415 # of difflib. See #11763. 416 _diffThreshold = 2**16 417 418 # Attribute used by TestSuite for classSetUp 419 420 _classSetupFailed = False 421 422 _class_cleanups = [] 423 424 def __init__(self, methodName='runTest'): 425 """Create an instance of the class that will use the named test 426 method when executed. Raises a ValueError if the instance does 427 not have a method with the specified name. 428 """ 429 self._testMethodName = methodName 430 self._outcome = None 431 self._testMethodDoc = 'No test' 432 try: 433 testMethod = getattr(self, methodName) 434 except AttributeError: 435 if methodName != 'runTest': 436 # we allow instantiation with no explicit method name 437 # but not an *incorrect* or missing method name 438 raise ValueError("no such test method in %s: %s" % 439 (self.__class__, methodName)) 440 else: 441 self._testMethodDoc = testMethod.__doc__ 442 self._cleanups = [] 443 self._subtest = None 444 445 # Map types to custom assertEqual functions that will compare 446 # instances of said type in more detail to generate a more useful 447 # error message. 448 self._type_equality_funcs = {} 449 self.addTypeEqualityFunc(dict, 'assertDictEqual') 450 self.addTypeEqualityFunc(list, 'assertListEqual') 451 self.addTypeEqualityFunc(tuple, 'assertTupleEqual') 452 self.addTypeEqualityFunc(set, 'assertSetEqual') 453 self.addTypeEqualityFunc(frozenset, 'assertSetEqual') 454 self.addTypeEqualityFunc(str, 'assertMultiLineEqual') 455 456 def addTypeEqualityFunc(self, typeobj, function): 457 """Add a type specific assertEqual style function to compare a type. 458 459 This method is for use by TestCase subclasses that need to register 460 their own type equality functions to provide nicer error messages. 461 462 Args: 463 typeobj: The data type to call this function on when both values 464 are of the same type in assertEqual(). 465 function: The callable taking two arguments and an optional 466 msg= argument that raises self.failureException with a 467 useful error message when the two arguments are not equal. 468 """ 469 self._type_equality_funcs[typeobj] = function 470 471 def addCleanup(*args, **kwargs): 472 """Add a function, with arguments, to be called when the test is 473 completed. Functions added are called on a LIFO basis and are 474 called after tearDown on test failure or success. 475 476 Cleanup items are called even if setUp fails (unlike tearDown).""" 477 if len(args) >= 2: 478 self, function, *args = args 479 elif not args: 480 raise TypeError("descriptor 'addCleanup' of 'TestCase' object " 481 "needs an argument") 482 elif 'function' in kwargs: 483 function = kwargs.pop('function') 484 self, *args = args 485 import warnings 486 warnings.warn("Passing 'function' as keyword argument is deprecated", 487 DeprecationWarning, stacklevel=2) 488 else: 489 raise TypeError('addCleanup expected at least 1 positional ' 490 'argument, got %d' % (len(args)-1)) 491 args = tuple(args) 492 493 self._cleanups.append((function, args, kwargs)) 494 addCleanup.__text_signature__ = '($self, function, /, *args, **kwargs)' 495 496 @classmethod 497 def addClassCleanup(cls, function, /, *args, **kwargs): 498 """Same as addCleanup, except the cleanup items are called even if 499 setUpClass fails (unlike tearDownClass).""" 500 cls._class_cleanups.append((function, args, kwargs)) 501 502 def setUp(self): 503 "Hook method for setting up the test fixture before exercising it." 504 pass 505 506 def tearDown(self): 507 "Hook method for deconstructing the test fixture after testing it." 508 pass 509 510 @classmethod 511 def setUpClass(cls): 512 "Hook method for setting up class fixture before running tests in the class." 513 514 @classmethod 515 def tearDownClass(cls): 516 "Hook method for deconstructing the class fixture after running all tests in the class." 517 518 def countTestCases(self): 519 return 1 520 521 def defaultTestResult(self): 522 return result.TestResult() 523 524 def shortDescription(self): 525 """Returns a one-line description of the test, or None if no 526 description has been provided. 527 528 The default implementation of this method returns the first line of 529 the specified test method's docstring. 530 """ 531 doc = self._testMethodDoc 532 return doc.strip().split("\n")[0].strip() if doc else None 533 534 535 def id(self): 536 return "%s.%s" % (strclass(self.__class__), self._testMethodName) 537 538 def __eq__(self, other): 539 if type(self) is not type(other): 540 return NotImplemented 541 542 return self._testMethodName == other._testMethodName 543 544 def __hash__(self): 545 return hash((type(self), self._testMethodName)) 546 547 def __str__(self): 548 return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) 549 550 def __repr__(self): 551 return "<%s testMethod=%s>" % \ 552 (strclass(self.__class__), self._testMethodName) 553 554 def _addSkip(self, result, test_case, reason): 555 addSkip = getattr(result, 'addSkip', None) 556 if addSkip is not None: 557 addSkip(test_case, reason) 558 else: 559 warnings.warn("TestResult has no addSkip method, skips not reported", 560 RuntimeWarning, 2) 561 result.addSuccess(test_case) 562 563 @contextlib.contextmanager 564 def subTest(self, msg=_subtest_msg_sentinel, **params): 565 """Return a context manager that will return the enclosed block 566 of code in a subtest identified by the optional message and 567 keyword parameters. A failure in the subtest marks the test 568 case as failed but resumes execution at the end of the enclosed 569 block, allowing further test code to be executed. 570 """ 571 if self._outcome is None or not self._outcome.result_supports_subtests: 572 yield 573 return 574 parent = self._subtest 575 if parent is None: 576 params_map = _OrderedChainMap(params) 577 else: 578 params_map = parent.params.new_child(params) 579 self._subtest = _SubTest(self, msg, params_map) 580 try: 581 with self._outcome.testPartExecutor(self._subtest, isTest=True): 582 yield 583 if not self._outcome.success: 584 result = self._outcome.result 585 if result is not None and result.failfast: 586 raise _ShouldStop 587 elif self._outcome.expectedFailure: 588 # If the test is expecting a failure, we really want to 589 # stop now and register the expected failure. 590 raise _ShouldStop 591 finally: 592 self._subtest = parent 593 594 def _feedErrorsToResult(self, result, errors): 595 for test, exc_info in errors: 596 if isinstance(test, _SubTest): 597 result.addSubTest(test.test_case, test, exc_info) 598 elif exc_info is not None: 599 if issubclass(exc_info[0], self.failureException): 600 result.addFailure(test, exc_info) 601 else: 602 result.addError(test, exc_info) 603 604 def _addExpectedFailure(self, result, exc_info): 605 try: 606 addExpectedFailure = result.addExpectedFailure 607 except AttributeError: 608 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes", 609 RuntimeWarning) 610 result.addSuccess(self) 611 else: 612 addExpectedFailure(self, exc_info) 613 614 def _addUnexpectedSuccess(self, result): 615 try: 616 addUnexpectedSuccess = result.addUnexpectedSuccess 617 except AttributeError: 618 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure", 619 RuntimeWarning) 620 # We need to pass an actual exception and traceback to addFailure, 621 # otherwise the legacy result can choke. 622 try: 623 raise _UnexpectedSuccess from None 624 except _UnexpectedSuccess: 625 result.addFailure(self, sys.exc_info()) 626 else: 627 addUnexpectedSuccess(self) 628 629 def _callSetUp(self): 630 self.setUp() 631 632 def _callTestMethod(self, method): 633 method() 634 635 def _callTearDown(self): 636 self.tearDown() 637 638 def _callCleanup(self, function, /, *args, **kwargs): 639 function(*args, **kwargs) 640 641 def run(self, result=None): 642 orig_result = result 643 if result is None: 644 result = self.defaultTestResult() 645 startTestRun = getattr(result, 'startTestRun', None) 646 if startTestRun is not None: 647 startTestRun() 648 649 result.startTest(self) 650 651 testMethod = getattr(self, self._testMethodName) 652 if (getattr(self.__class__, "__unittest_skip__", False) or 653 getattr(testMethod, "__unittest_skip__", False)): 654 # If the class or method was skipped. 655 try: 656 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 657 or getattr(testMethod, '__unittest_skip_why__', '')) 658 self._addSkip(result, self, skip_why) 659 finally: 660 result.stopTest(self) 661 return 662 expecting_failure_method = getattr(testMethod, 663 "__unittest_expecting_failure__", False) 664 expecting_failure_class = getattr(self, 665 "__unittest_expecting_failure__", False) 666 expecting_failure = expecting_failure_class or expecting_failure_method 667 outcome = _Outcome(result) 668 try: 669 self._outcome = outcome 670 671 with outcome.testPartExecutor(self): 672 self._callSetUp() 673 if outcome.success: 674 outcome.expecting_failure = expecting_failure 675 with outcome.testPartExecutor(self, isTest=True): 676 self._callTestMethod(testMethod) 677 outcome.expecting_failure = False 678 with outcome.testPartExecutor(self): 679 self._callTearDown() 680 681 self.doCleanups() 682 for test, reason in outcome.skipped: 683 self._addSkip(result, test, reason) 684 self._feedErrorsToResult(result, outcome.errors) 685 if outcome.success: 686 if expecting_failure: 687 if outcome.expectedFailure: 688 self._addExpectedFailure(result, outcome.expectedFailure) 689 else: 690 self._addUnexpectedSuccess(result) 691 else: 692 result.addSuccess(self) 693 return result 694 finally: 695 result.stopTest(self) 696 if orig_result is None: 697 stopTestRun = getattr(result, 'stopTestRun', None) 698 if stopTestRun is not None: 699 stopTestRun() 700 701 # explicitly break reference cycles: 702 # outcome.errors -> frame -> outcome -> outcome.errors 703 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure 704 outcome.errors.clear() 705 outcome.expectedFailure = None 706 707 # clear the outcome, no more needed 708 self._outcome = None 709 710 def doCleanups(self): 711 """Execute all cleanup functions. Normally called for you after 712 tearDown.""" 713 outcome = self._outcome or _Outcome() 714 while self._cleanups: 715 function, args, kwargs = self._cleanups.pop() 716 with outcome.testPartExecutor(self): 717 self._callCleanup(function, *args, **kwargs) 718 719 # return this for backwards compatibility 720 # even though we no longer use it internally 721 return outcome.success 722 723 @classmethod 724 def doClassCleanups(cls): 725 """Execute all class cleanup functions. Normally called for you after 726 tearDownClass.""" 727 cls.tearDown_exceptions = [] 728 while cls._class_cleanups: 729 function, args, kwargs = cls._class_cleanups.pop() 730 try: 731 function(*args, **kwargs) 732 except Exception as exc: 733 cls.tearDown_exceptions.append(sys.exc_info()) 734 735 def __call__(self, *args, **kwds): 736 return self.run(*args, **kwds) 737 738 def debug(self): 739 """Run the test without collecting errors in a TestResult""" 740 self.setUp() 741 getattr(self, self._testMethodName)() 742 self.tearDown() 743 while self._cleanups: 744 function, args, kwargs = self._cleanups.pop(-1) 745 function(*args, **kwargs) 746 747 def skipTest(self, reason): 748 """Skip this test.""" 749 raise SkipTest(reason) 750 751 def fail(self, msg=None): 752 """Fail immediately, with the given message.""" 753 raise self.failureException(msg) 754 755 def assertFalse(self, expr, msg=None): 756 """Check that the expression is false.""" 757 if expr: 758 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr)) 759 raise self.failureException(msg) 760 761 def assertTrue(self, expr, msg=None): 762 """Check that the expression is true.""" 763 if not expr: 764 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr)) 765 raise self.failureException(msg) 766 767 def _formatMessage(self, msg, standardMsg): 768 """Honour the longMessage attribute when generating failure messages. 769 If longMessage is False this means: 770 * Use only an explicit message if it is provided 771 * Otherwise use the standard message for the assert 772 773 If longMessage is True: 774 * Use the standard message 775 * If an explicit message is provided, plus ' : ' and the explicit message 776 """ 777 if not self.longMessage: 778 return msg or standardMsg 779 if msg is None: 780 return standardMsg 781 try: 782 # don't switch to '{}' formatting in Python 2.X 783 # it changes the way unicode input is handled 784 return '%s : %s' % (standardMsg, msg) 785 except UnicodeDecodeError: 786 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) 787 788 def assertRaises(self, expected_exception, *args, **kwargs): 789 """Fail unless an exception of class expected_exception is raised 790 by the callable when invoked with specified positional and 791 keyword arguments. If a different type of exception is 792 raised, it will not be caught, and the test case will be 793 deemed to have suffered an error, exactly as for an 794 unexpected exception. 795 796 If called with the callable and arguments omitted, will return a 797 context object used like this:: 798 799 with self.assertRaises(SomeException): 800 do_something() 801 802 An optional keyword argument 'msg' can be provided when assertRaises 803 is used as a context object. 804 805 The context manager keeps a reference to the exception as 806 the 'exception' attribute. This allows you to inspect the 807 exception after the assertion:: 808 809 with self.assertRaises(SomeException) as cm: 810 do_something() 811 the_exception = cm.exception 812 self.assertEqual(the_exception.error_code, 3) 813 """ 814 context = _AssertRaisesContext(expected_exception, self) 815 try: 816 return context.handle('assertRaises', args, kwargs) 817 finally: 818 # bpo-23890: manually break a reference cycle 819 context = None 820 821 def assertWarns(self, expected_warning, *args, **kwargs): 822 """Fail unless a warning of class warnClass is triggered 823 by the callable when invoked with specified positional and 824 keyword arguments. If a different type of warning is 825 triggered, it will not be handled: depending on the other 826 warning filtering rules in effect, it might be silenced, printed 827 out, or raised as an exception. 828 829 If called with the callable and arguments omitted, will return a 830 context object used like this:: 831 832 with self.assertWarns(SomeWarning): 833 do_something() 834 835 An optional keyword argument 'msg' can be provided when assertWarns 836 is used as a context object. 837 838 The context manager keeps a reference to the first matching 839 warning as the 'warning' attribute; similarly, the 'filename' 840 and 'lineno' attributes give you information about the line 841 of Python code from which the warning was triggered. 842 This allows you to inspect the warning after the assertion:: 843 844 with self.assertWarns(SomeWarning) as cm: 845 do_something() 846 the_warning = cm.warning 847 self.assertEqual(the_warning.some_attribute, 147) 848 """ 849 context = _AssertWarnsContext(expected_warning, self) 850 return context.handle('assertWarns', args, kwargs) 851 852 def assertLogs(self, logger=None, level=None): 853 """Fail unless a log message of level *level* or higher is emitted 854 on *logger_name* or its children. If omitted, *level* defaults to 855 INFO and *logger* defaults to the root logger. 856 857 This method must be used as a context manager, and will yield 858 a recording object with two attributes: `output` and `records`. 859 At the end of the context manager, the `output` attribute will 860 be a list of the matching formatted log messages and the 861 `records` attribute will be a list of the corresponding LogRecord 862 objects. 863 864 Example:: 865 866 with self.assertLogs('foo', level='INFO') as cm: 867 logging.getLogger('foo').info('first message') 868 logging.getLogger('foo.bar').error('second message') 869 self.assertEqual(cm.output, ['INFO:foo:first message', 870 'ERROR:foo.bar:second message']) 871 """ 872 return _AssertLogsContext(self, logger, level) 873 874 def _getAssertEqualityFunc(self, first, second): 875 """Get a detailed comparison function for the types of the two args. 876 877 Returns: A callable accepting (first, second, msg=None) that will 878 raise a failure exception if first != second with a useful human 879 readable error message for those types. 880 """ 881 # 882 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) 883 # and vice versa. I opted for the conservative approach in case 884 # subclasses are not intended to be compared in detail to their super 885 # class instances using a type equality func. This means testing 886 # subtypes won't automagically use the detailed comparison. Callers 887 # should use their type specific assertSpamEqual method to compare 888 # subclasses if the detailed comparison is desired and appropriate. 889 # See the discussion in http://bugs.python.org/issue2578. 890 # 891 if type(first) is type(second): 892 asserter = self._type_equality_funcs.get(type(first)) 893 if asserter is not None: 894 if isinstance(asserter, str): 895 asserter = getattr(self, asserter) 896 return asserter 897 898 return self._baseAssertEqual 899 900 def _baseAssertEqual(self, first, second, msg=None): 901 """The default assertEqual implementation, not type specific.""" 902 if not first == second: 903 standardMsg = '%s != %s' % _common_shorten_repr(first, second) 904 msg = self._formatMessage(msg, standardMsg) 905 raise self.failureException(msg) 906 907 def assertEqual(self, first, second, msg=None): 908 """Fail if the two objects are unequal as determined by the '==' 909 operator. 910 """ 911 assertion_func = self._getAssertEqualityFunc(first, second) 912 assertion_func(first, second, msg=msg) 913 914 def assertNotEqual(self, first, second, msg=None): 915 """Fail if the two objects are equal as determined by the '!=' 916 operator. 917 """ 918 if not first != second: 919 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), 920 safe_repr(second))) 921 raise self.failureException(msg) 922 923 def assertAlmostEqual(self, first, second, places=None, msg=None, 924 delta=None): 925 """Fail if the two objects are unequal as determined by their 926 difference rounded to the given number of decimal places 927 (default 7) and comparing to zero, or by comparing that the 928 difference between the two objects is more than the given 929 delta. 930 931 Note that decimal places (from zero) are usually not the same 932 as significant digits (measured from the most significant digit). 933 934 If the two objects compare equal then they will automatically 935 compare almost equal. 936 """ 937 if first == second: 938 # shortcut 939 return 940 if delta is not None and places is not None: 941 raise TypeError("specify delta or places not both") 942 943 diff = abs(first - second) 944 if delta is not None: 945 if diff <= delta: 946 return 947 948 standardMsg = '%s != %s within %s delta (%s difference)' % ( 949 safe_repr(first), 950 safe_repr(second), 951 safe_repr(delta), 952 safe_repr(diff)) 953 else: 954 if places is None: 955 places = 7 956 957 if round(diff, places) == 0: 958 return 959 960 standardMsg = '%s != %s within %r places (%s difference)' % ( 961 safe_repr(first), 962 safe_repr(second), 963 places, 964 safe_repr(diff)) 965 msg = self._formatMessage(msg, standardMsg) 966 raise self.failureException(msg) 967 968 def assertNotAlmostEqual(self, first, second, places=None, msg=None, 969 delta=None): 970 """Fail if the two objects are equal as determined by their 971 difference rounded to the given number of decimal places 972 (default 7) and comparing to zero, or by comparing that the 973 difference between the two objects is less than the given delta. 974 975 Note that decimal places (from zero) are usually not the same 976 as significant digits (measured from the most significant digit). 977 978 Objects that are equal automatically fail. 979 """ 980 if delta is not None and places is not None: 981 raise TypeError("specify delta or places not both") 982 diff = abs(first - second) 983 if delta is not None: 984 if not (first == second) and diff > delta: 985 return 986 standardMsg = '%s == %s within %s delta (%s difference)' % ( 987 safe_repr(first), 988 safe_repr(second), 989 safe_repr(delta), 990 safe_repr(diff)) 991 else: 992 if places is None: 993 places = 7 994 if not (first == second) and round(diff, places) != 0: 995 return 996 standardMsg = '%s == %s within %r places' % (safe_repr(first), 997 safe_repr(second), 998 places) 999 1000 msg = self._formatMessage(msg, standardMsg) 1001 raise self.failureException(msg) 1002 1003 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): 1004 """An equality assertion for ordered sequences (like lists and tuples). 1005 1006 For the purposes of this function, a valid ordered sequence type is one 1007 which can be indexed, has a length, and has an equality operator. 1008 1009 Args: 1010 seq1: The first sequence to compare. 1011 seq2: The second sequence to compare. 1012 seq_type: The expected datatype of the sequences, or None if no 1013 datatype should be enforced. 1014 msg: Optional message to use on failure instead of a list of 1015 differences. 1016 """ 1017 if seq_type is not None: 1018 seq_type_name = seq_type.__name__ 1019 if not isinstance(seq1, seq_type): 1020 raise self.failureException('First sequence is not a %s: %s' 1021 % (seq_type_name, safe_repr(seq1))) 1022 if not isinstance(seq2, seq_type): 1023 raise self.failureException('Second sequence is not a %s: %s' 1024 % (seq_type_name, safe_repr(seq2))) 1025 else: 1026 seq_type_name = "sequence" 1027 1028 differing = None 1029 try: 1030 len1 = len(seq1) 1031 except (TypeError, NotImplementedError): 1032 differing = 'First %s has no length. Non-sequence?' % ( 1033 seq_type_name) 1034 1035 if differing is None: 1036 try: 1037 len2 = len(seq2) 1038 except (TypeError, NotImplementedError): 1039 differing = 'Second %s has no length. Non-sequence?' % ( 1040 seq_type_name) 1041 1042 if differing is None: 1043 if seq1 == seq2: 1044 return 1045 1046 differing = '%ss differ: %s != %s\n' % ( 1047 (seq_type_name.capitalize(),) + 1048 _common_shorten_repr(seq1, seq2)) 1049 1050 for i in range(min(len1, len2)): 1051 try: 1052 item1 = seq1[i] 1053 except (TypeError, IndexError, NotImplementedError): 1054 differing += ('\nUnable to index element %d of first %s\n' % 1055 (i, seq_type_name)) 1056 break 1057 1058 try: 1059 item2 = seq2[i] 1060 except (TypeError, IndexError, NotImplementedError): 1061 differing += ('\nUnable to index element %d of second %s\n' % 1062 (i, seq_type_name)) 1063 break 1064 1065 if item1 != item2: 1066 differing += ('\nFirst differing element %d:\n%s\n%s\n' % 1067 ((i,) + _common_shorten_repr(item1, item2))) 1068 break 1069 else: 1070 if (len1 == len2 and seq_type is None and 1071 type(seq1) != type(seq2)): 1072 # The sequences are the same, but have differing types. 1073 return 1074 1075 if len1 > len2: 1076 differing += ('\nFirst %s contains %d additional ' 1077 'elements.\n' % (seq_type_name, len1 - len2)) 1078 try: 1079 differing += ('First extra element %d:\n%s\n' % 1080 (len2, safe_repr(seq1[len2]))) 1081 except (TypeError, IndexError, NotImplementedError): 1082 differing += ('Unable to index element %d ' 1083 'of first %s\n' % (len2, seq_type_name)) 1084 elif len1 < len2: 1085 differing += ('\nSecond %s contains %d additional ' 1086 'elements.\n' % (seq_type_name, len2 - len1)) 1087 try: 1088 differing += ('First extra element %d:\n%s\n' % 1089 (len1, safe_repr(seq2[len1]))) 1090 except (TypeError, IndexError, NotImplementedError): 1091 differing += ('Unable to index element %d ' 1092 'of second %s\n' % (len1, seq_type_name)) 1093 standardMsg = differing 1094 diffMsg = '\n' + '\n'.join( 1095 difflib.ndiff(pprint.pformat(seq1).splitlines(), 1096 pprint.pformat(seq2).splitlines())) 1097 1098 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1099 msg = self._formatMessage(msg, standardMsg) 1100 self.fail(msg) 1101 1102 def _truncateMessage(self, message, diff): 1103 max_diff = self.maxDiff 1104 if max_diff is None or len(diff) <= max_diff: 1105 return message + diff 1106 return message + (DIFF_OMITTED % len(diff)) 1107 1108 def assertListEqual(self, list1, list2, msg=None): 1109 """A list-specific equality assertion. 1110 1111 Args: 1112 list1: The first list to compare. 1113 list2: The second list to compare. 1114 msg: Optional message to use on failure instead of a list of 1115 differences. 1116 1117 """ 1118 self.assertSequenceEqual(list1, list2, msg, seq_type=list) 1119 1120 def assertTupleEqual(self, tuple1, tuple2, msg=None): 1121 """A tuple-specific equality assertion. 1122 1123 Args: 1124 tuple1: The first tuple to compare. 1125 tuple2: The second tuple to compare. 1126 msg: Optional message to use on failure instead of a list of 1127 differences. 1128 """ 1129 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) 1130 1131 def assertSetEqual(self, set1, set2, msg=None): 1132 """A set-specific equality assertion. 1133 1134 Args: 1135 set1: The first set to compare. 1136 set2: The second set to compare. 1137 msg: Optional message to use on failure instead of a list of 1138 differences. 1139 1140 assertSetEqual uses ducktyping to support different types of sets, and 1141 is optimized for sets specifically (parameters must support a 1142 difference method). 1143 """ 1144 try: 1145 difference1 = set1.difference(set2) 1146 except TypeError as e: 1147 self.fail('invalid type when attempting set difference: %s' % e) 1148 except AttributeError as e: 1149 self.fail('first argument does not support set difference: %s' % e) 1150 1151 try: 1152 difference2 = set2.difference(set1) 1153 except TypeError as e: 1154 self.fail('invalid type when attempting set difference: %s' % e) 1155 except AttributeError as e: 1156 self.fail('second argument does not support set difference: %s' % e) 1157 1158 if not (difference1 or difference2): 1159 return 1160 1161 lines = [] 1162 if difference1: 1163 lines.append('Items in the first set but not the second:') 1164 for item in difference1: 1165 lines.append(repr(item)) 1166 if difference2: 1167 lines.append('Items in the second set but not the first:') 1168 for item in difference2: 1169 lines.append(repr(item)) 1170 1171 standardMsg = '\n'.join(lines) 1172 self.fail(self._formatMessage(msg, standardMsg)) 1173 1174 def assertIn(self, member, container, msg=None): 1175 """Just like self.assertTrue(a in b), but with a nicer default message.""" 1176 if member not in container: 1177 standardMsg = '%s not found in %s' % (safe_repr(member), 1178 safe_repr(container)) 1179 self.fail(self._formatMessage(msg, standardMsg)) 1180 1181 def assertNotIn(self, member, container, msg=None): 1182 """Just like self.assertTrue(a not in b), but with a nicer default message.""" 1183 if member in container: 1184 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), 1185 safe_repr(container)) 1186 self.fail(self._formatMessage(msg, standardMsg)) 1187 1188 def assertIs(self, expr1, expr2, msg=None): 1189 """Just like self.assertTrue(a is b), but with a nicer default message.""" 1190 if expr1 is not expr2: 1191 standardMsg = '%s is not %s' % (safe_repr(expr1), 1192 safe_repr(expr2)) 1193 self.fail(self._formatMessage(msg, standardMsg)) 1194 1195 def assertIsNot(self, expr1, expr2, msg=None): 1196 """Just like self.assertTrue(a is not b), but with a nicer default message.""" 1197 if expr1 is expr2: 1198 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) 1199 self.fail(self._formatMessage(msg, standardMsg)) 1200 1201 def assertDictEqual(self, d1, d2, msg=None): 1202 self.assertIsInstance(d1, dict, 'First argument is not a dictionary') 1203 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') 1204 1205 if d1 != d2: 1206 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2) 1207 diff = ('\n' + '\n'.join(difflib.ndiff( 1208 pprint.pformat(d1).splitlines(), 1209 pprint.pformat(d2).splitlines()))) 1210 standardMsg = self._truncateMessage(standardMsg, diff) 1211 self.fail(self._formatMessage(msg, standardMsg)) 1212 1213 def assertDictContainsSubset(self, subset, dictionary, msg=None): 1214 """Checks whether dictionary is a superset of subset.""" 1215 warnings.warn('assertDictContainsSubset is deprecated', 1216 DeprecationWarning) 1217 missing = [] 1218 mismatched = [] 1219 for key, value in subset.items(): 1220 if key not in dictionary: 1221 missing.append(key) 1222 elif value != dictionary[key]: 1223 mismatched.append('%s, expected: %s, actual: %s' % 1224 (safe_repr(key), safe_repr(value), 1225 safe_repr(dictionary[key]))) 1226 1227 if not (missing or mismatched): 1228 return 1229 1230 standardMsg = '' 1231 if missing: 1232 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in 1233 missing) 1234 if mismatched: 1235 if standardMsg: 1236 standardMsg += '; ' 1237 standardMsg += 'Mismatched values: %s' % ','.join(mismatched) 1238 1239 self.fail(self._formatMessage(msg, standardMsg)) 1240 1241 1242 def assertCountEqual(self, first, second, msg=None): 1243 """Asserts that two iterables have the same elements, the same number of 1244 times, without regard to order. 1245 1246 self.assertEqual(Counter(list(first)), 1247 Counter(list(second))) 1248 1249 Example: 1250 - [0, 1, 1] and [1, 0, 1] compare equal. 1251 - [0, 0, 1] and [0, 1] compare unequal. 1252 1253 """ 1254 first_seq, second_seq = list(first), list(second) 1255 try: 1256 first = collections.Counter(first_seq) 1257 second = collections.Counter(second_seq) 1258 except TypeError: 1259 # Handle case with unhashable elements 1260 differences = _count_diff_all_purpose(first_seq, second_seq) 1261 else: 1262 if first == second: 1263 return 1264 differences = _count_diff_hashable(first_seq, second_seq) 1265 1266 if differences: 1267 standardMsg = 'Element counts were not equal:\n' 1268 lines = ['First has %d, Second has %d: %r' % diff for diff in differences] 1269 diffMsg = '\n'.join(lines) 1270 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1271 msg = self._formatMessage(msg, standardMsg) 1272 self.fail(msg) 1273 1274 def assertMultiLineEqual(self, first, second, msg=None): 1275 """Assert that two multi-line strings are equal.""" 1276 self.assertIsInstance(first, str, 'First argument is not a string') 1277 self.assertIsInstance(second, str, 'Second argument is not a string') 1278 1279 if first != second: 1280 # don't use difflib if the strings are too long 1281 if (len(first) > self._diffThreshold or 1282 len(second) > self._diffThreshold): 1283 self._baseAssertEqual(first, second, msg) 1284 firstlines = first.splitlines(keepends=True) 1285 secondlines = second.splitlines(keepends=True) 1286 if len(firstlines) == 1 and first.strip('\r\n') == first: 1287 firstlines = [first + '\n'] 1288 secondlines = [second + '\n'] 1289 standardMsg = '%s != %s' % _common_shorten_repr(first, second) 1290 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) 1291 standardMsg = self._truncateMessage(standardMsg, diff) 1292 self.fail(self._formatMessage(msg, standardMsg)) 1293 1294 def assertLess(self, a, b, msg=None): 1295 """Just like self.assertTrue(a < b), but with a nicer default message.""" 1296 if not a < b: 1297 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) 1298 self.fail(self._formatMessage(msg, standardMsg)) 1299 1300 def assertLessEqual(self, a, b, msg=None): 1301 """Just like self.assertTrue(a <= b), but with a nicer default message.""" 1302 if not a <= b: 1303 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) 1304 self.fail(self._formatMessage(msg, standardMsg)) 1305 1306 def assertGreater(self, a, b, msg=None): 1307 """Just like self.assertTrue(a > b), but with a nicer default message.""" 1308 if not a > b: 1309 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) 1310 self.fail(self._formatMessage(msg, standardMsg)) 1311 1312 def assertGreaterEqual(self, a, b, msg=None): 1313 """Just like self.assertTrue(a >= b), but with a nicer default message.""" 1314 if not a >= b: 1315 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) 1316 self.fail(self._formatMessage(msg, standardMsg)) 1317 1318 def assertIsNone(self, obj, msg=None): 1319 """Same as self.assertTrue(obj is None), with a nicer default message.""" 1320 if obj is not None: 1321 standardMsg = '%s is not None' % (safe_repr(obj),) 1322 self.fail(self._formatMessage(msg, standardMsg)) 1323 1324 def assertIsNotNone(self, obj, msg=None): 1325 """Included for symmetry with assertIsNone.""" 1326 if obj is None: 1327 standardMsg = 'unexpectedly None' 1328 self.fail(self._formatMessage(msg, standardMsg)) 1329 1330 def assertIsInstance(self, obj, cls, msg=None): 1331 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer 1332 default message.""" 1333 if not isinstance(obj, cls): 1334 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) 1335 self.fail(self._formatMessage(msg, standardMsg)) 1336 1337 def assertNotIsInstance(self, obj, cls, msg=None): 1338 """Included for symmetry with assertIsInstance.""" 1339 if isinstance(obj, cls): 1340 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) 1341 self.fail(self._formatMessage(msg, standardMsg)) 1342 1343 def assertRaisesRegex(self, expected_exception, expected_regex, 1344 *args, **kwargs): 1345 """Asserts that the message in a raised exception matches a regex. 1346 1347 Args: 1348 expected_exception: Exception class expected to be raised. 1349 expected_regex: Regex (re.Pattern object or string) expected 1350 to be found in error message. 1351 args: Function to be called and extra positional args. 1352 kwargs: Extra kwargs. 1353 msg: Optional message used in case of failure. Can only be used 1354 when assertRaisesRegex is used as a context manager. 1355 """ 1356 context = _AssertRaisesContext(expected_exception, self, expected_regex) 1357 return context.handle('assertRaisesRegex', args, kwargs) 1358 1359 def assertWarnsRegex(self, expected_warning, expected_regex, 1360 *args, **kwargs): 1361 """Asserts that the message in a triggered warning matches a regexp. 1362 Basic functioning is similar to assertWarns() with the addition 1363 that only warnings whose messages also match the regular expression 1364 are considered successful matches. 1365 1366 Args: 1367 expected_warning: Warning class expected to be triggered. 1368 expected_regex: Regex (re.Pattern object or string) expected 1369 to be found in error message. 1370 args: Function to be called and extra positional args. 1371 kwargs: Extra kwargs. 1372 msg: Optional message used in case of failure. Can only be used 1373 when assertWarnsRegex is used as a context manager. 1374 """ 1375 context = _AssertWarnsContext(expected_warning, self, expected_regex) 1376 return context.handle('assertWarnsRegex', args, kwargs) 1377 1378 def assertRegex(self, text, expected_regex, msg=None): 1379 """Fail the test unless the text matches the regular expression.""" 1380 if isinstance(expected_regex, (str, bytes)): 1381 assert expected_regex, "expected_regex must not be empty." 1382 expected_regex = re.compile(expected_regex) 1383 if not expected_regex.search(text): 1384 standardMsg = "Regex didn't match: %r not found in %r" % ( 1385 expected_regex.pattern, text) 1386 # _formatMessage ensures the longMessage option is respected 1387 msg = self._formatMessage(msg, standardMsg) 1388 raise self.failureException(msg) 1389 1390 def assertNotRegex(self, text, unexpected_regex, msg=None): 1391 """Fail the test if the text matches the regular expression.""" 1392 if isinstance(unexpected_regex, (str, bytes)): 1393 unexpected_regex = re.compile(unexpected_regex) 1394 match = unexpected_regex.search(text) 1395 if match: 1396 standardMsg = 'Regex matched: %r matches %r in %r' % ( 1397 text[match.start() : match.end()], 1398 unexpected_regex.pattern, 1399 text) 1400 # _formatMessage ensures the longMessage option is respected 1401 msg = self._formatMessage(msg, standardMsg) 1402 raise self.failureException(msg) 1403 1404 1405 def _deprecate(original_func): 1406 def deprecated_func(*args, **kwargs): 1407 warnings.warn( 1408 'Please use {0} instead.'.format(original_func.__name__), 1409 DeprecationWarning, 2) 1410 return original_func(*args, **kwargs) 1411 return deprecated_func 1412 1413 # see #9424 1414 failUnlessEqual = assertEquals = _deprecate(assertEqual) 1415 failIfEqual = assertNotEquals = _deprecate(assertNotEqual) 1416 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual) 1417 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual) 1418 failUnless = assert_ = _deprecate(assertTrue) 1419 failUnlessRaises = _deprecate(assertRaises) 1420 failIf = _deprecate(assertFalse) 1421 assertRaisesRegexp = _deprecate(assertRaisesRegex) 1422 assertRegexpMatches = _deprecate(assertRegex) 1423 assertNotRegexpMatches = _deprecate(assertNotRegex) 1424 1425 1426 1427class FunctionTestCase(TestCase): 1428 """A test case that wraps a test function. 1429 1430 This is useful for slipping pre-existing test functions into the 1431 unittest framework. Optionally, set-up and tidy-up functions can be 1432 supplied. As with TestCase, the tidy-up ('tearDown') function will 1433 always be called if the set-up ('setUp') function ran successfully. 1434 """ 1435 1436 def __init__(self, testFunc, setUp=None, tearDown=None, description=None): 1437 super(FunctionTestCase, self).__init__() 1438 self._setUpFunc = setUp 1439 self._tearDownFunc = tearDown 1440 self._testFunc = testFunc 1441 self._description = description 1442 1443 def setUp(self): 1444 if self._setUpFunc is not None: 1445 self._setUpFunc() 1446 1447 def tearDown(self): 1448 if self._tearDownFunc is not None: 1449 self._tearDownFunc() 1450 1451 def runTest(self): 1452 self._testFunc() 1453 1454 def id(self): 1455 return self._testFunc.__name__ 1456 1457 def __eq__(self, other): 1458 if not isinstance(other, self.__class__): 1459 return NotImplemented 1460 1461 return self._setUpFunc == other._setUpFunc and \ 1462 self._tearDownFunc == other._tearDownFunc and \ 1463 self._testFunc == other._testFunc and \ 1464 self._description == other._description 1465 1466 def __hash__(self): 1467 return hash((type(self), self._setUpFunc, self._tearDownFunc, 1468 self._testFunc, self._description)) 1469 1470 def __str__(self): 1471 return "%s (%s)" % (strclass(self.__class__), 1472 self._testFunc.__name__) 1473 1474 def __repr__(self): 1475 return "<%s tec=%s>" % (strclass(self.__class__), 1476 self._testFunc) 1477 1478 def shortDescription(self): 1479 if self._description is not None: 1480 return self._description 1481 doc = self._testFunc.__doc__ 1482 return doc and doc.split("\n")[0].strip() or None 1483 1484 1485class _SubTest(TestCase): 1486 1487 def __init__(self, test_case, message, params): 1488 super().__init__() 1489 self._message = message 1490 self.test_case = test_case 1491 self.params = params 1492 self.failureException = test_case.failureException 1493 1494 def runTest(self): 1495 raise NotImplementedError("subtests cannot be run directly") 1496 1497 def _subDescription(self): 1498 parts = [] 1499 if self._message is not _subtest_msg_sentinel: 1500 parts.append("[{}]".format(self._message)) 1501 if self.params: 1502 params_desc = ', '.join( 1503 "{}={!r}".format(k, v) 1504 for (k, v) in self.params.items()) 1505 parts.append("({})".format(params_desc)) 1506 return " ".join(parts) or '(<subtest>)' 1507 1508 def id(self): 1509 return "{} {}".format(self.test_case.id(), self._subDescription()) 1510 1511 def shortDescription(self): 1512 """Returns a one-line description of the subtest, or None if no 1513 description has been provided. 1514 """ 1515 return self.test_case.shortDescription() 1516 1517 def __str__(self): 1518 return "{} {}".format(self.test_case, self._subDescription()) 1519