unittest
Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework (used with permission).
This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner).
Simple usage:
import unittest
class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40)
if __name__ == '__main__': unittest.main()
Further information is available in the bundled documentation, and from
http://docs.python.org/library/unittest.html
Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form.
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1""" 2Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's 3Smalltalk testing framework (used with permission). 4 5This module contains the core framework classes that form the basis of 6specific test cases and suites (TestCase, TestSuite etc.), and also a 7text-based utility class for running the tests and reporting the results 8 (TextTestRunner). 9 10Simple usage: 11 12 import unittest 13 14 class IntegerArithmeticTestCase(unittest.TestCase): 15 def testAdd(self): # test method names begin with 'test' 16 self.assertEqual((1 + 2), 3) 17 self.assertEqual(0 + 1, 1) 18 def testMultiply(self): 19 self.assertEqual((0 * 10), 0) 20 self.assertEqual((5 * 8), 40) 21 22 if __name__ == '__main__': 23 unittest.main() 24 25Further information is available in the bundled documentation, and from 26 27 http://docs.python.org/library/unittest.html 28 29Copyright (c) 1999-2003 Steve Purcell 30Copyright (c) 2003-2010 Python Software Foundation 31This module is free software, and you may redistribute it and/or modify 32it under the same terms as Python itself, so long as this copyright message 33and disclaimer are retained in their original form. 34 35IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 36SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF 37THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 38DAMAGE. 39 40THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 41LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 42PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, 43AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 44SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 45""" 46 47__all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 48 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 49 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 50 'expectedFailure', 'TextTestResult', 'installHandler', 51 'registerResult', 'removeResult', 'removeHandler', 52 'addModuleCleanup', 'doModuleCleanups', 'enterModuleContext'] 53 54# Expose obsolete functions for backwards compatibility 55# bpo-5846: Deprecated in Python 3.11, scheduled for removal in Python 3.13. 56__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) 57 58__unittest = True 59 60from .result import TestResult 61from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, 62 skipIf, skipUnless, expectedFailure, doModuleCleanups, 63 enterModuleContext) 64from .suite import BaseTestSuite, TestSuite 65from .loader import TestLoader, defaultTestLoader 66from .main import TestProgram, main 67from .runner import TextTestRunner, TextTestResult 68from .signals import installHandler, registerResult, removeResult, removeHandler 69# IsolatedAsyncioTestCase will be imported lazily. 70from .loader import makeSuite, getTestCaseNames, findTestCases 71 72 73# Lazy import of IsolatedAsyncioTestCase from .async_case 74# It imports asyncio, which is relatively heavy, but most tests 75# do not need it. 76 77def __dir__(): 78 return globals().keys() | {'IsolatedAsyncioTestCase'} 79 80def __getattr__(name): 81 if name == 'IsolatedAsyncioTestCase': 82 global IsolatedAsyncioTestCase 83 from .async_case import IsolatedAsyncioTestCase 84 return IsolatedAsyncioTestCase 85 raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
25class TestResult(object): 26 """Holder for test result information. 27 28 Test results are automatically managed by the TestCase and TestSuite 29 classes, and do not need to be explicitly manipulated by writers of tests. 30 31 Each instance holds the total number of tests run, and collections of 32 failures and errors that occurred among those test runs. The collections 33 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the 34 formatted traceback of the error that occurred. 35 """ 36 _previousTestClass = None 37 _testRunEntered = False 38 _moduleSetUpFailed = False 39 def __init__(self, stream=None, descriptions=None, verbosity=None): 40 self.failfast = False 41 self.failures = [] 42 self.errors = [] 43 self.testsRun = 0 44 self.skipped = [] 45 self.expectedFailures = [] 46 self.unexpectedSuccesses = [] 47 self.collectedDurations = [] 48 self.shouldStop = False 49 self.buffer = False 50 self.tb_locals = False 51 self._stdout_buffer = None 52 self._stderr_buffer = None 53 self._original_stdout = sys.stdout 54 self._original_stderr = sys.stderr 55 self._mirrorOutput = False 56 57 def printErrors(self): 58 "Called by TestRunner after test run" 59 60 def startTest(self, test): 61 "Called when the given test is about to be run" 62 self.testsRun += 1 63 self._mirrorOutput = False 64 self._setupStdout() 65 66 def _setupStdout(self): 67 if self.buffer: 68 if self._stderr_buffer is None: 69 self._stderr_buffer = io.StringIO() 70 self._stdout_buffer = io.StringIO() 71 sys.stdout = self._stdout_buffer 72 sys.stderr = self._stderr_buffer 73 74 def startTestRun(self): 75 """Called once before any tests are executed. 76 77 See startTest for a method called before each test. 78 """ 79 80 def stopTest(self, test): 81 """Called when the given test has been run""" 82 self._restoreStdout() 83 self._mirrorOutput = False 84 85 def _restoreStdout(self): 86 if self.buffer: 87 if self._mirrorOutput: 88 output = sys.stdout.getvalue() 89 error = sys.stderr.getvalue() 90 if output: 91 if not output.endswith('\n'): 92 output += '\n' 93 self._original_stdout.write(STDOUT_LINE % output) 94 if error: 95 if not error.endswith('\n'): 96 error += '\n' 97 self._original_stderr.write(STDERR_LINE % error) 98 99 sys.stdout = self._original_stdout 100 sys.stderr = self._original_stderr 101 self._stdout_buffer.seek(0) 102 self._stdout_buffer.truncate() 103 self._stderr_buffer.seek(0) 104 self._stderr_buffer.truncate() 105 106 def stopTestRun(self): 107 """Called once after all tests are executed. 108 109 See stopTest for a method called after each test. 110 """ 111 112 @failfast 113 def addError(self, test, err): 114 """Called when an error has occurred. 'err' is a tuple of values as 115 returned by sys.exc_info(). 116 """ 117 self.errors.append((test, self._exc_info_to_string(err, test))) 118 self._mirrorOutput = True 119 120 @failfast 121 def addFailure(self, test, err): 122 """Called when an error has occurred. 'err' is a tuple of values as 123 returned by sys.exc_info().""" 124 self.failures.append((test, self._exc_info_to_string(err, test))) 125 self._mirrorOutput = True 126 127 def addSubTest(self, test, subtest, err): 128 """Called at the end of a subtest. 129 'err' is None if the subtest ended successfully, otherwise it's a 130 tuple of values as returned by sys.exc_info(). 131 """ 132 # By default, we don't do anything with successful subtests, but 133 # more sophisticated test results might want to record them. 134 if err is not None: 135 if getattr(self, 'failfast', False): 136 self.stop() 137 if issubclass(err[0], test.failureException): 138 errors = self.failures 139 else: 140 errors = self.errors 141 errors.append((subtest, self._exc_info_to_string(err, test))) 142 self._mirrorOutput = True 143 144 def addSuccess(self, test): 145 "Called when a test has completed successfully" 146 pass 147 148 def addSkip(self, test, reason): 149 """Called when a test is skipped.""" 150 self.skipped.append((test, reason)) 151 152 def addExpectedFailure(self, test, err): 153 """Called when an expected failure/error occurred.""" 154 self.expectedFailures.append( 155 (test, self._exc_info_to_string(err, test))) 156 157 @failfast 158 def addUnexpectedSuccess(self, test): 159 """Called when a test was expected to fail, but succeed.""" 160 self.unexpectedSuccesses.append(test) 161 162 def addDuration(self, test, elapsed): 163 """Called when a test finished to run, regardless of its outcome. 164 *test* is the test case corresponding to the test method. 165 *elapsed* is the time represented in seconds, and it includes the 166 execution of cleanup functions. 167 """ 168 # support for a TextTestRunner using an old TestResult class 169 if hasattr(self, "collectedDurations"): 170 # Pass test repr and not the test object itself to avoid resources leak 171 self.collectedDurations.append((str(test), elapsed)) 172 173 def wasSuccessful(self): 174 """Tells whether or not this result was a success.""" 175 # The hasattr check is for test_result's OldResult test. That 176 # way this method works on objects that lack the attribute. 177 # (where would such result instances come from? old stored pickles?) 178 return ((len(self.failures) == len(self.errors) == 0) and 179 (not hasattr(self, 'unexpectedSuccesses') or 180 len(self.unexpectedSuccesses) == 0)) 181 182 def stop(self): 183 """Indicates that the tests should be aborted.""" 184 self.shouldStop = True 185 186 def _exc_info_to_string(self, err, test): 187 """Converts a sys.exc_info()-style tuple of values into a string.""" 188 exctype, value, tb = err 189 tb = self._clean_tracebacks(exctype, value, tb, test) 190 tb_e = traceback.TracebackException( 191 exctype, value, tb, 192 capture_locals=self.tb_locals, compact=True) 193 msgLines = list(tb_e.format()) 194 195 if self.buffer: 196 output = sys.stdout.getvalue() 197 error = sys.stderr.getvalue() 198 if output: 199 if not output.endswith('\n'): 200 output += '\n' 201 msgLines.append(STDOUT_LINE % output) 202 if error: 203 if not error.endswith('\n'): 204 error += '\n' 205 msgLines.append(STDERR_LINE % error) 206 return ''.join(msgLines) 207 208 def _clean_tracebacks(self, exctype, value, tb, test): 209 ret = None 210 first = True 211 excs = [(exctype, value, tb)] 212 seen = {id(value)} # Detect loops in chained exceptions. 213 while excs: 214 (exctype, value, tb) = excs.pop() 215 # Skip test runner traceback levels 216 while tb and self._is_relevant_tb_level(tb): 217 tb = tb.tb_next 218 219 # Skip assert*() traceback levels 220 if exctype is test.failureException: 221 self._remove_unittest_tb_frames(tb) 222 223 if first: 224 ret = tb 225 first = False 226 else: 227 value.__traceback__ = tb 228 229 if value is not None: 230 for c in (value.__cause__, value.__context__): 231 if c is not None and id(c) not in seen: 232 excs.append((type(c), c, c.__traceback__)) 233 seen.add(id(c)) 234 return ret 235 236 def _is_relevant_tb_level(self, tb): 237 return '__unittest' in tb.tb_frame.f_globals 238 239 def _remove_unittest_tb_frames(self, tb): 240 '''Truncates usercode tb at the first unittest frame. 241 242 If the first frame of the traceback is in user code, 243 the prefix up to the first unittest frame is returned. 244 If the first frame is already in the unittest module, 245 the traceback is not modified. 246 ''' 247 prev = None 248 while tb and not self._is_relevant_tb_level(tb): 249 prev = tb 250 tb = tb.tb_next 251 if prev is not None: 252 prev.tb_next = None 253 254 def __repr__(self): 255 return ("<%s run=%i errors=%i failures=%i>" % 256 (util.strclass(self.__class__), self.testsRun, len(self.errors), 257 len(self.failures)))
Holder for test result information.
Test results are automatically managed by the TestCase and TestSuite classes, and do not need to be explicitly manipulated by writers of tests.
Each instance holds the total number of tests run, and collections of failures and errors that occurred among those test runs. The collections contain tuples of (testcase, exceptioninfo), where exceptioninfo is the formatted traceback of the error that occurred.
39 def __init__(self, stream=None, descriptions=None, verbosity=None): 40 self.failfast = False 41 self.failures = [] 42 self.errors = [] 43 self.testsRun = 0 44 self.skipped = [] 45 self.expectedFailures = [] 46 self.unexpectedSuccesses = [] 47 self.collectedDurations = [] 48 self.shouldStop = False 49 self.buffer = False 50 self.tb_locals = False 51 self._stdout_buffer = None 52 self._stderr_buffer = None 53 self._original_stdout = sys.stdout 54 self._original_stderr = sys.stderr 55 self._mirrorOutput = False
60 def startTest(self, test): 61 "Called when the given test is about to be run" 62 self.testsRun += 1 63 self._mirrorOutput = False 64 self._setupStdout()
Called when the given test is about to be run
74 def startTestRun(self): 75 """Called once before any tests are executed. 76 77 See startTest for a method called before each test. 78 """
Called once before any tests are executed.
See startTest for a method called before each test.
80 def stopTest(self, test): 81 """Called when the given test has been run""" 82 self._restoreStdout() 83 self._mirrorOutput = False
Called when the given test has been run
106 def stopTestRun(self): 107 """Called once after all tests are executed. 108 109 See stopTest for a method called after each test. 110 """
Called once after all tests are executed.
See stopTest for a method called after each test.
112 @failfast 113 def addError(self, test, err): 114 """Called when an error has occurred. 'err' is a tuple of values as 115 returned by sys.exc_info(). 116 """ 117 self.errors.append((test, self._exc_info_to_string(err, test))) 118 self._mirrorOutput = True
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
120 @failfast 121 def addFailure(self, test, err): 122 """Called when an error has occurred. 'err' is a tuple of values as 123 returned by sys.exc_info().""" 124 self.failures.append((test, self._exc_info_to_string(err, test))) 125 self._mirrorOutput = True
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
127 def addSubTest(self, test, subtest, err): 128 """Called at the end of a subtest. 129 'err' is None if the subtest ended successfully, otherwise it's a 130 tuple of values as returned by sys.exc_info(). 131 """ 132 # By default, we don't do anything with successful subtests, but 133 # more sophisticated test results might want to record them. 134 if err is not None: 135 if getattr(self, 'failfast', False): 136 self.stop() 137 if issubclass(err[0], test.failureException): 138 errors = self.failures 139 else: 140 errors = self.errors 141 errors.append((subtest, self._exc_info_to_string(err, test))) 142 self._mirrorOutput = True
Called at the end of a subtest. 'err' is None if the subtest ended successfully, otherwise it's a tuple of values as returned by sys.exc_info().
148 def addSkip(self, test, reason): 149 """Called when a test is skipped.""" 150 self.skipped.append((test, reason))
Called when a test is skipped.
152 def addExpectedFailure(self, test, err): 153 """Called when an expected failure/error occurred.""" 154 self.expectedFailures.append( 155 (test, self._exc_info_to_string(err, test)))
Called when an expected failure/error occurred.
157 @failfast 158 def addUnexpectedSuccess(self, test): 159 """Called when a test was expected to fail, but succeed.""" 160 self.unexpectedSuccesses.append(test)
Called when a test was expected to fail, but succeed.
162 def addDuration(self, test, elapsed): 163 """Called when a test finished to run, regardless of its outcome. 164 *test* is the test case corresponding to the test method. 165 *elapsed* is the time represented in seconds, and it includes the 166 execution of cleanup functions. 167 """ 168 # support for a TextTestRunner using an old TestResult class 169 if hasattr(self, "collectedDurations"): 170 # Pass test repr and not the test object itself to avoid resources leak 171 self.collectedDurations.append((str(test), elapsed))
Called when a test finished to run, regardless of its outcome. test is the test case corresponding to the test method. elapsed is the time represented in seconds, and it includes the execution of cleanup functions.
173 def wasSuccessful(self): 174 """Tells whether or not this result was a success.""" 175 # The hasattr check is for test_result's OldResult test. That 176 # way this method works on objects that lack the attribute. 177 # (where would such result instances come from? old stored pickles?) 178 return ((len(self.failures) == len(self.errors) == 0) and 179 (not hasattr(self, 'unexpectedSuccesses') or 180 len(self.unexpectedSuccesses) == 0))
Tells whether or not this result was a success.
346class TestCase(object): 347 """A class whose instances are single test cases. 348 349 By default, the test code itself should be placed in a method named 350 'runTest'. 351 352 If the fixture may be used for many test cases, create as 353 many test methods as are needed. When instantiating such a TestCase 354 subclass, specify in the constructor arguments the name of the test method 355 that the instance is to execute. 356 357 Test authors should subclass TestCase for their own tests. Construction 358 and deconstruction of the test's environment ('fixture') can be 359 implemented by overriding the 'setUp' and 'tearDown' methods respectively. 360 361 If it is necessary to override the __init__ method, the base class 362 __init__ method must always be called. It is important that subclasses 363 should not change the signature of their __init__ method, since instances 364 of the classes are instantiated automatically by parts of the framework 365 in order to be run. 366 367 When subclassing TestCase, you can set these attributes: 368 * failureException: determines which exception will be raised when 369 the instance's assertion methods fail; test methods raising this 370 exception will be deemed to have 'failed' rather than 'errored'. 371 * longMessage: determines whether long messages (including repr of 372 objects used in assert methods) will be printed on failure in *addition* 373 to any explicit message passed. 374 * maxDiff: sets the maximum length of a diff in failure messages 375 by assert methods using difflib. It is looked up as an instance 376 attribute so can be configured by individual tests if required. 377 """ 378 379 failureException = AssertionError 380 381 longMessage = True 382 383 maxDiff = 80*8 384 385 # If a string is longer than _diffThreshold, use normal comparison instead 386 # of difflib. See #11763. 387 _diffThreshold = 2**16 388 389 def __init_subclass__(cls, *args, **kwargs): 390 # Attribute used by TestSuite for classSetUp 391 cls._classSetupFailed = False 392 cls._class_cleanups = [] 393 super().__init_subclass__(*args, **kwargs) 394 395 def __init__(self, methodName='runTest'): 396 """Create an instance of the class that will use the named test 397 method when executed. Raises a ValueError if the instance does 398 not have a method with the specified name. 399 """ 400 self._testMethodName = methodName 401 self._outcome = None 402 self._testMethodDoc = 'No test' 403 try: 404 testMethod = getattr(self, methodName) 405 except AttributeError: 406 if methodName != 'runTest': 407 # we allow instantiation with no explicit method name 408 # but not an *incorrect* or missing method name 409 raise ValueError("no such test method in %s: %s" % 410 (self.__class__, methodName)) 411 else: 412 self._testMethodDoc = testMethod.__doc__ 413 self._cleanups = [] 414 self._subtest = None 415 416 # Map types to custom assertEqual functions that will compare 417 # instances of said type in more detail to generate a more useful 418 # error message. 419 self._type_equality_funcs = {} 420 self.addTypeEqualityFunc(dict, 'assertDictEqual') 421 self.addTypeEqualityFunc(list, 'assertListEqual') 422 self.addTypeEqualityFunc(tuple, 'assertTupleEqual') 423 self.addTypeEqualityFunc(set, 'assertSetEqual') 424 self.addTypeEqualityFunc(frozenset, 'assertSetEqual') 425 self.addTypeEqualityFunc(str, 'assertMultiLineEqual') 426 427 def addTypeEqualityFunc(self, typeobj, function): 428 """Add a type specific assertEqual style function to compare a type. 429 430 This method is for use by TestCase subclasses that need to register 431 their own type equality functions to provide nicer error messages. 432 433 Args: 434 typeobj: The data type to call this function on when both values 435 are of the same type in assertEqual(). 436 function: The callable taking two arguments and an optional 437 msg= argument that raises self.failureException with a 438 useful error message when the two arguments are not equal. 439 """ 440 self._type_equality_funcs[typeobj] = function 441 442 def addCleanup(self, function, /, *args, **kwargs): 443 """Add a function, with arguments, to be called when the test is 444 completed. Functions added are called on a LIFO basis and are 445 called after tearDown on test failure or success. 446 447 Cleanup items are called even if setUp fails (unlike tearDown).""" 448 self._cleanups.append((function, args, kwargs)) 449 450 def enterContext(self, cm): 451 """Enters the supplied context manager. 452 453 If successful, also adds its __exit__ method as a cleanup 454 function and returns the result of the __enter__ method. 455 """ 456 return _enter_context(cm, self.addCleanup) 457 458 @classmethod 459 def addClassCleanup(cls, function, /, *args, **kwargs): 460 """Same as addCleanup, except the cleanup items are called even if 461 setUpClass fails (unlike tearDownClass).""" 462 cls._class_cleanups.append((function, args, kwargs)) 463 464 @classmethod 465 def enterClassContext(cls, cm): 466 """Same as enterContext, but class-wide.""" 467 return _enter_context(cm, cls.addClassCleanup) 468 469 def setUp(self): 470 "Hook method for setting up the test fixture before exercising it." 471 pass 472 473 def tearDown(self): 474 "Hook method for deconstructing the test fixture after testing it." 475 pass 476 477 @classmethod 478 def setUpClass(cls): 479 "Hook method for setting up class fixture before running tests in the class." 480 481 @classmethod 482 def tearDownClass(cls): 483 "Hook method for deconstructing the class fixture after running all tests in the class." 484 485 def countTestCases(self): 486 return 1 487 488 def defaultTestResult(self): 489 return result.TestResult() 490 491 def shortDescription(self): 492 """Returns a one-line description of the test, or None if no 493 description has been provided. 494 495 The default implementation of this method returns the first line of 496 the specified test method's docstring. 497 """ 498 doc = self._testMethodDoc 499 return doc.strip().split("\n")[0].strip() if doc else None 500 501 502 def id(self): 503 return "%s.%s" % (strclass(self.__class__), self._testMethodName) 504 505 def __eq__(self, other): 506 if type(self) is not type(other): 507 return NotImplemented 508 509 return self._testMethodName == other._testMethodName 510 511 def __hash__(self): 512 return hash((type(self), self._testMethodName)) 513 514 def __str__(self): 515 return "%s (%s.%s)" % (self._testMethodName, strclass(self.__class__), self._testMethodName) 516 517 def __repr__(self): 518 return "<%s testMethod=%s>" % \ 519 (strclass(self.__class__), self._testMethodName) 520 521 @contextlib.contextmanager 522 def subTest(self, msg=_subtest_msg_sentinel, **params): 523 """Return a context manager that will return the enclosed block 524 of code in a subtest identified by the optional message and 525 keyword parameters. A failure in the subtest marks the test 526 case as failed but resumes execution at the end of the enclosed 527 block, allowing further test code to be executed. 528 """ 529 if self._outcome is None or not self._outcome.result_supports_subtests: 530 yield 531 return 532 parent = self._subtest 533 if parent is None: 534 params_map = _OrderedChainMap(params) 535 else: 536 params_map = parent.params.new_child(params) 537 self._subtest = _SubTest(self, msg, params_map) 538 try: 539 with self._outcome.testPartExecutor(self._subtest, subTest=True): 540 yield 541 if not self._outcome.success: 542 result = self._outcome.result 543 if result is not None and result.failfast: 544 raise _ShouldStop 545 elif self._outcome.expectedFailure: 546 # If the test is expecting a failure, we really want to 547 # stop now and register the expected failure. 548 raise _ShouldStop 549 finally: 550 self._subtest = parent 551 552 def _addExpectedFailure(self, result, exc_info): 553 try: 554 addExpectedFailure = result.addExpectedFailure 555 except AttributeError: 556 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes", 557 RuntimeWarning) 558 result.addSuccess(self) 559 else: 560 addExpectedFailure(self, exc_info) 561 562 def _addUnexpectedSuccess(self, result): 563 try: 564 addUnexpectedSuccess = result.addUnexpectedSuccess 565 except AttributeError: 566 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failure", 567 RuntimeWarning) 568 # We need to pass an actual exception and traceback to addFailure, 569 # otherwise the legacy result can choke. 570 try: 571 raise _UnexpectedSuccess from None 572 except _UnexpectedSuccess: 573 result.addFailure(self, sys.exc_info()) 574 else: 575 addUnexpectedSuccess(self) 576 577 def _addDuration(self, result, elapsed): 578 try: 579 addDuration = result.addDuration 580 except AttributeError: 581 warnings.warn("TestResult has no addDuration method", 582 RuntimeWarning) 583 else: 584 addDuration(self, elapsed) 585 586 def _callSetUp(self): 587 self.setUp() 588 589 def _callTestMethod(self, method): 590 if method() is not None: 591 warnings.warn(f'It is deprecated to return a value that is not None from a ' 592 f'test case ({method})', DeprecationWarning, stacklevel=3) 593 594 def _callTearDown(self): 595 self.tearDown() 596 597 def _callCleanup(self, function, /, *args, **kwargs): 598 function(*args, **kwargs) 599 600 def run(self, result=None): 601 if result is None: 602 result = self.defaultTestResult() 603 startTestRun = getattr(result, 'startTestRun', None) 604 stopTestRun = getattr(result, 'stopTestRun', None) 605 if startTestRun is not None: 606 startTestRun() 607 else: 608 stopTestRun = None 609 610 result.startTest(self) 611 try: 612 testMethod = getattr(self, self._testMethodName) 613 if (getattr(self.__class__, "__unittest_skip__", False) or 614 getattr(testMethod, "__unittest_skip__", False)): 615 # If the class or method was skipped. 616 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 617 or getattr(testMethod, '__unittest_skip_why__', '')) 618 _addSkip(result, self, skip_why) 619 return result 620 621 expecting_failure = ( 622 getattr(self, "__unittest_expecting_failure__", False) or 623 getattr(testMethod, "__unittest_expecting_failure__", False) 624 ) 625 outcome = _Outcome(result) 626 start_time = time.perf_counter() 627 try: 628 self._outcome = outcome 629 630 with outcome.testPartExecutor(self): 631 self._callSetUp() 632 if outcome.success: 633 outcome.expecting_failure = expecting_failure 634 with outcome.testPartExecutor(self): 635 self._callTestMethod(testMethod) 636 outcome.expecting_failure = False 637 with outcome.testPartExecutor(self): 638 self._callTearDown() 639 self.doCleanups() 640 self._addDuration(result, (time.perf_counter() - start_time)) 641 642 if outcome.success: 643 if expecting_failure: 644 if outcome.expectedFailure: 645 self._addExpectedFailure(result, outcome.expectedFailure) 646 else: 647 self._addUnexpectedSuccess(result) 648 else: 649 result.addSuccess(self) 650 return result 651 finally: 652 # explicitly break reference cycle: 653 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure 654 outcome.expectedFailure = None 655 outcome = None 656 657 # clear the outcome, no more needed 658 self._outcome = None 659 660 finally: 661 result.stopTest(self) 662 if stopTestRun is not None: 663 stopTestRun() 664 665 def doCleanups(self): 666 """Execute all cleanup functions. Normally called for you after 667 tearDown.""" 668 outcome = self._outcome or _Outcome() 669 while self._cleanups: 670 function, args, kwargs = self._cleanups.pop() 671 with outcome.testPartExecutor(self): 672 self._callCleanup(function, *args, **kwargs) 673 674 # return this for backwards compatibility 675 # even though we no longer use it internally 676 return outcome.success 677 678 @classmethod 679 def doClassCleanups(cls): 680 """Execute all class cleanup functions. Normally called for you after 681 tearDownClass.""" 682 cls.tearDown_exceptions = [] 683 while cls._class_cleanups: 684 function, args, kwargs = cls._class_cleanups.pop() 685 try: 686 function(*args, **kwargs) 687 except Exception: 688 cls.tearDown_exceptions.append(sys.exc_info()) 689 690 def __call__(self, *args, **kwds): 691 return self.run(*args, **kwds) 692 693 def debug(self): 694 """Run the test without collecting errors in a TestResult""" 695 testMethod = getattr(self, self._testMethodName) 696 if (getattr(self.__class__, "__unittest_skip__", False) or 697 getattr(testMethod, "__unittest_skip__", False)): 698 # If the class or method was skipped. 699 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 700 or getattr(testMethod, '__unittest_skip_why__', '')) 701 raise SkipTest(skip_why) 702 703 self._callSetUp() 704 self._callTestMethod(testMethod) 705 self._callTearDown() 706 while self._cleanups: 707 function, args, kwargs = self._cleanups.pop() 708 self._callCleanup(function, *args, **kwargs) 709 710 def skipTest(self, reason): 711 """Skip this test.""" 712 raise SkipTest(reason) 713 714 def fail(self, msg=None): 715 """Fail immediately, with the given message.""" 716 raise self.failureException(msg) 717 718 def assertFalse(self, expr, msg=None): 719 """Check that the expression is false.""" 720 if expr: 721 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr)) 722 raise self.failureException(msg) 723 724 def assertTrue(self, expr, msg=None): 725 """Check that the expression is true.""" 726 if not expr: 727 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr)) 728 raise self.failureException(msg) 729 730 def _formatMessage(self, msg, standardMsg): 731 """Honour the longMessage attribute when generating failure messages. 732 If longMessage is False this means: 733 * Use only an explicit message if it is provided 734 * Otherwise use the standard message for the assert 735 736 If longMessage is True: 737 * Use the standard message 738 * If an explicit message is provided, plus ' : ' and the explicit message 739 """ 740 if not self.longMessage: 741 return msg or standardMsg 742 if msg is None: 743 return standardMsg 744 try: 745 # don't switch to '{}' formatting in Python 2.X 746 # it changes the way unicode input is handled 747 return '%s : %s' % (standardMsg, msg) 748 except UnicodeDecodeError: 749 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) 750 751 def assertRaises(self, expected_exception, *args, **kwargs): 752 """Fail unless an exception of class expected_exception is raised 753 by the callable when invoked with specified positional and 754 keyword arguments. If a different type of exception is 755 raised, it will not be caught, and the test case will be 756 deemed to have suffered an error, exactly as for an 757 unexpected exception. 758 759 If called with the callable and arguments omitted, will return a 760 context object used like this:: 761 762 with self.assertRaises(SomeException): 763 do_something() 764 765 An optional keyword argument 'msg' can be provided when assertRaises 766 is used as a context object. 767 768 The context manager keeps a reference to the exception as 769 the 'exception' attribute. This allows you to inspect the 770 exception after the assertion:: 771 772 with self.assertRaises(SomeException) as cm: 773 do_something() 774 the_exception = cm.exception 775 self.assertEqual(the_exception.error_code, 3) 776 """ 777 context = _AssertRaisesContext(expected_exception, self) 778 try: 779 return context.handle('assertRaises', args, kwargs) 780 finally: 781 # bpo-23890: manually break a reference cycle 782 context = None 783 784 def assertWarns(self, expected_warning, *args, **kwargs): 785 """Fail unless a warning of class warnClass is triggered 786 by the callable when invoked with specified positional and 787 keyword arguments. If a different type of warning is 788 triggered, it will not be handled: depending on the other 789 warning filtering rules in effect, it might be silenced, printed 790 out, or raised as an exception. 791 792 If called with the callable and arguments omitted, will return a 793 context object used like this:: 794 795 with self.assertWarns(SomeWarning): 796 do_something() 797 798 An optional keyword argument 'msg' can be provided when assertWarns 799 is used as a context object. 800 801 The context manager keeps a reference to the first matching 802 warning as the 'warning' attribute; similarly, the 'filename' 803 and 'lineno' attributes give you information about the line 804 of Python code from which the warning was triggered. 805 This allows you to inspect the warning after the assertion:: 806 807 with self.assertWarns(SomeWarning) as cm: 808 do_something() 809 the_warning = cm.warning 810 self.assertEqual(the_warning.some_attribute, 147) 811 """ 812 context = _AssertWarnsContext(expected_warning, self) 813 return context.handle('assertWarns', args, kwargs) 814 815 def assertLogs(self, logger=None, level=None): 816 """Fail unless a log message of level *level* or higher is emitted 817 on *logger_name* or its children. If omitted, *level* defaults to 818 INFO and *logger* defaults to the root logger. 819 820 This method must be used as a context manager, and will yield 821 a recording object with two attributes: `output` and `records`. 822 At the end of the context manager, the `output` attribute will 823 be a list of the matching formatted log messages and the 824 `records` attribute will be a list of the corresponding LogRecord 825 objects. 826 827 Example:: 828 829 with self.assertLogs('foo', level='INFO') as cm: 830 logging.getLogger('foo').info('first message') 831 logging.getLogger('foo.bar').error('second message') 832 self.assertEqual(cm.output, ['INFO:foo:first message', 833 'ERROR:foo.bar:second message']) 834 """ 835 # Lazy import to avoid importing logging if it is not needed. 836 from ._log import _AssertLogsContext 837 return _AssertLogsContext(self, logger, level, no_logs=False) 838 839 def assertNoLogs(self, logger=None, level=None): 840 """ Fail unless no log messages of level *level* or higher are emitted 841 on *logger_name* or its children. 842 843 This method must be used as a context manager. 844 """ 845 from ._log import _AssertLogsContext 846 return _AssertLogsContext(self, logger, level, no_logs=True) 847 848 def _getAssertEqualityFunc(self, first, second): 849 """Get a detailed comparison function for the types of the two args. 850 851 Returns: A callable accepting (first, second, msg=None) that will 852 raise a failure exception if first != second with a useful human 853 readable error message for those types. 854 """ 855 # 856 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) 857 # and vice versa. I opted for the conservative approach in case 858 # subclasses are not intended to be compared in detail to their super 859 # class instances using a type equality func. This means testing 860 # subtypes won't automagically use the detailed comparison. Callers 861 # should use their type specific assertSpamEqual method to compare 862 # subclasses if the detailed comparison is desired and appropriate. 863 # See the discussion in http://bugs.python.org/issue2578. 864 # 865 if type(first) is type(second): 866 asserter = self._type_equality_funcs.get(type(first)) 867 if asserter is not None: 868 if isinstance(asserter, str): 869 asserter = getattr(self, asserter) 870 return asserter 871 872 return self._baseAssertEqual 873 874 def _baseAssertEqual(self, first, second, msg=None): 875 """The default assertEqual implementation, not type specific.""" 876 if not first == second: 877 standardMsg = '%s != %s' % _common_shorten_repr(first, second) 878 msg = self._formatMessage(msg, standardMsg) 879 raise self.failureException(msg) 880 881 def assertEqual(self, first, second, msg=None): 882 """Fail if the two objects are unequal as determined by the '==' 883 operator. 884 """ 885 assertion_func = self._getAssertEqualityFunc(first, second) 886 assertion_func(first, second, msg=msg) 887 888 def assertNotEqual(self, first, second, msg=None): 889 """Fail if the two objects are equal as determined by the '!=' 890 operator. 891 """ 892 if not first != second: 893 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), 894 safe_repr(second))) 895 raise self.failureException(msg) 896 897 def assertAlmostEqual(self, first, second, places=None, msg=None, 898 delta=None): 899 """Fail if the two objects are unequal as determined by their 900 difference rounded to the given number of decimal places 901 (default 7) and comparing to zero, or by comparing that the 902 difference between the two objects is more than the given 903 delta. 904 905 Note that decimal places (from zero) are usually not the same 906 as significant digits (measured from the most significant digit). 907 908 If the two objects compare equal then they will automatically 909 compare almost equal. 910 """ 911 if first == second: 912 # shortcut 913 return 914 if delta is not None and places is not None: 915 raise TypeError("specify delta or places not both") 916 917 diff = abs(first - second) 918 if delta is not None: 919 if diff <= delta: 920 return 921 922 standardMsg = '%s != %s within %s delta (%s difference)' % ( 923 safe_repr(first), 924 safe_repr(second), 925 safe_repr(delta), 926 safe_repr(diff)) 927 else: 928 if places is None: 929 places = 7 930 931 if round(diff, places) == 0: 932 return 933 934 standardMsg = '%s != %s within %r places (%s difference)' % ( 935 safe_repr(first), 936 safe_repr(second), 937 places, 938 safe_repr(diff)) 939 msg = self._formatMessage(msg, standardMsg) 940 raise self.failureException(msg) 941 942 def assertNotAlmostEqual(self, first, second, places=None, msg=None, 943 delta=None): 944 """Fail if the two objects are equal as determined by their 945 difference rounded to the given number of decimal places 946 (default 7) and comparing to zero, or by comparing that the 947 difference between the two objects is less than the given delta. 948 949 Note that decimal places (from zero) are usually not the same 950 as significant digits (measured from the most significant digit). 951 952 Objects that are equal automatically fail. 953 """ 954 if delta is not None and places is not None: 955 raise TypeError("specify delta or places not both") 956 diff = abs(first - second) 957 if delta is not None: 958 if not (first == second) and diff > delta: 959 return 960 standardMsg = '%s == %s within %s delta (%s difference)' % ( 961 safe_repr(first), 962 safe_repr(second), 963 safe_repr(delta), 964 safe_repr(diff)) 965 else: 966 if places is None: 967 places = 7 968 if not (first == second) and round(diff, places) != 0: 969 return 970 standardMsg = '%s == %s within %r places' % (safe_repr(first), 971 safe_repr(second), 972 places) 973 974 msg = self._formatMessage(msg, standardMsg) 975 raise self.failureException(msg) 976 977 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): 978 """An equality assertion for ordered sequences (like lists and tuples). 979 980 For the purposes of this function, a valid ordered sequence type is one 981 which can be indexed, has a length, and has an equality operator. 982 983 Args: 984 seq1: The first sequence to compare. 985 seq2: The second sequence to compare. 986 seq_type: The expected datatype of the sequences, or None if no 987 datatype should be enforced. 988 msg: Optional message to use on failure instead of a list of 989 differences. 990 """ 991 if seq_type is not None: 992 seq_type_name = seq_type.__name__ 993 if not isinstance(seq1, seq_type): 994 raise self.failureException('First sequence is not a %s: %s' 995 % (seq_type_name, safe_repr(seq1))) 996 if not isinstance(seq2, seq_type): 997 raise self.failureException('Second sequence is not a %s: %s' 998 % (seq_type_name, safe_repr(seq2))) 999 else: 1000 seq_type_name = "sequence" 1001 1002 differing = None 1003 try: 1004 len1 = len(seq1) 1005 except (TypeError, NotImplementedError): 1006 differing = 'First %s has no length. Non-sequence?' % ( 1007 seq_type_name) 1008 1009 if differing is None: 1010 try: 1011 len2 = len(seq2) 1012 except (TypeError, NotImplementedError): 1013 differing = 'Second %s has no length. Non-sequence?' % ( 1014 seq_type_name) 1015 1016 if differing is None: 1017 if seq1 == seq2: 1018 return 1019 1020 differing = '%ss differ: %s != %s\n' % ( 1021 (seq_type_name.capitalize(),) + 1022 _common_shorten_repr(seq1, seq2)) 1023 1024 for i in range(min(len1, len2)): 1025 try: 1026 item1 = seq1[i] 1027 except (TypeError, IndexError, NotImplementedError): 1028 differing += ('\nUnable to index element %d of first %s\n' % 1029 (i, seq_type_name)) 1030 break 1031 1032 try: 1033 item2 = seq2[i] 1034 except (TypeError, IndexError, NotImplementedError): 1035 differing += ('\nUnable to index element %d of second %s\n' % 1036 (i, seq_type_name)) 1037 break 1038 1039 if item1 != item2: 1040 differing += ('\nFirst differing element %d:\n%s\n%s\n' % 1041 ((i,) + _common_shorten_repr(item1, item2))) 1042 break 1043 else: 1044 if (len1 == len2 and seq_type is None and 1045 type(seq1) != type(seq2)): 1046 # The sequences are the same, but have differing types. 1047 return 1048 1049 if len1 > len2: 1050 differing += ('\nFirst %s contains %d additional ' 1051 'elements.\n' % (seq_type_name, len1 - len2)) 1052 try: 1053 differing += ('First extra element %d:\n%s\n' % 1054 (len2, safe_repr(seq1[len2]))) 1055 except (TypeError, IndexError, NotImplementedError): 1056 differing += ('Unable to index element %d ' 1057 'of first %s\n' % (len2, seq_type_name)) 1058 elif len1 < len2: 1059 differing += ('\nSecond %s contains %d additional ' 1060 'elements.\n' % (seq_type_name, len2 - len1)) 1061 try: 1062 differing += ('First extra element %d:\n%s\n' % 1063 (len1, safe_repr(seq2[len1]))) 1064 except (TypeError, IndexError, NotImplementedError): 1065 differing += ('Unable to index element %d ' 1066 'of second %s\n' % (len1, seq_type_name)) 1067 standardMsg = differing 1068 diffMsg = '\n' + '\n'.join( 1069 difflib.ndiff(pprint.pformat(seq1).splitlines(), 1070 pprint.pformat(seq2).splitlines())) 1071 1072 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1073 msg = self._formatMessage(msg, standardMsg) 1074 self.fail(msg) 1075 1076 def _truncateMessage(self, message, diff): 1077 max_diff = self.maxDiff 1078 if max_diff is None or len(diff) <= max_diff: 1079 return message + diff 1080 return message + (DIFF_OMITTED % len(diff)) 1081 1082 def assertListEqual(self, list1, list2, msg=None): 1083 """A list-specific equality assertion. 1084 1085 Args: 1086 list1: The first list to compare. 1087 list2: The second list to compare. 1088 msg: Optional message to use on failure instead of a list of 1089 differences. 1090 1091 """ 1092 self.assertSequenceEqual(list1, list2, msg, seq_type=list) 1093 1094 def assertTupleEqual(self, tuple1, tuple2, msg=None): 1095 """A tuple-specific equality assertion. 1096 1097 Args: 1098 tuple1: The first tuple to compare. 1099 tuple2: The second tuple to compare. 1100 msg: Optional message to use on failure instead of a list of 1101 differences. 1102 """ 1103 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) 1104 1105 def assertSetEqual(self, set1, set2, msg=None): 1106 """A set-specific equality assertion. 1107 1108 Args: 1109 set1: The first set to compare. 1110 set2: The second set to compare. 1111 msg: Optional message to use on failure instead of a list of 1112 differences. 1113 1114 assertSetEqual uses ducktyping to support different types of sets, and 1115 is optimized for sets specifically (parameters must support a 1116 difference method). 1117 """ 1118 try: 1119 difference1 = set1.difference(set2) 1120 except TypeError as e: 1121 self.fail('invalid type when attempting set difference: %s' % e) 1122 except AttributeError as e: 1123 self.fail('first argument does not support set difference: %s' % e) 1124 1125 try: 1126 difference2 = set2.difference(set1) 1127 except TypeError as e: 1128 self.fail('invalid type when attempting set difference: %s' % e) 1129 except AttributeError as e: 1130 self.fail('second argument does not support set difference: %s' % e) 1131 1132 if not (difference1 or difference2): 1133 return 1134 1135 lines = [] 1136 if difference1: 1137 lines.append('Items in the first set but not the second:') 1138 for item in difference1: 1139 lines.append(repr(item)) 1140 if difference2: 1141 lines.append('Items in the second set but not the first:') 1142 for item in difference2: 1143 lines.append(repr(item)) 1144 1145 standardMsg = '\n'.join(lines) 1146 self.fail(self._formatMessage(msg, standardMsg)) 1147 1148 def assertIn(self, member, container, msg=None): 1149 """Just like self.assertTrue(a in b), but with a nicer default message.""" 1150 if member not in container: 1151 standardMsg = '%s not found in %s' % (safe_repr(member), 1152 safe_repr(container)) 1153 self.fail(self._formatMessage(msg, standardMsg)) 1154 1155 def assertNotIn(self, member, container, msg=None): 1156 """Just like self.assertTrue(a not in b), but with a nicer default message.""" 1157 if member in container: 1158 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), 1159 safe_repr(container)) 1160 self.fail(self._formatMessage(msg, standardMsg)) 1161 1162 def assertIs(self, expr1, expr2, msg=None): 1163 """Just like self.assertTrue(a is b), but with a nicer default message.""" 1164 if expr1 is not expr2: 1165 standardMsg = '%s is not %s' % (safe_repr(expr1), 1166 safe_repr(expr2)) 1167 self.fail(self._formatMessage(msg, standardMsg)) 1168 1169 def assertIsNot(self, expr1, expr2, msg=None): 1170 """Just like self.assertTrue(a is not b), but with a nicer default message.""" 1171 if expr1 is expr2: 1172 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) 1173 self.fail(self._formatMessage(msg, standardMsg)) 1174 1175 def assertDictEqual(self, d1, d2, msg=None): 1176 self.assertIsInstance(d1, dict, 'First argument is not a dictionary') 1177 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') 1178 1179 if d1 != d2: 1180 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2) 1181 diff = ('\n' + '\n'.join(difflib.ndiff( 1182 pprint.pformat(d1).splitlines(), 1183 pprint.pformat(d2).splitlines()))) 1184 standardMsg = self._truncateMessage(standardMsg, diff) 1185 self.fail(self._formatMessage(msg, standardMsg)) 1186 1187 def assertCountEqual(self, first, second, msg=None): 1188 """Asserts that two iterables have the same elements, the same number of 1189 times, without regard to order. 1190 1191 self.assertEqual(Counter(list(first)), 1192 Counter(list(second))) 1193 1194 Example: 1195 - [0, 1, 1] and [1, 0, 1] compare equal. 1196 - [0, 0, 1] and [0, 1] compare unequal. 1197 1198 """ 1199 first_seq, second_seq = list(first), list(second) 1200 try: 1201 first = collections.Counter(first_seq) 1202 second = collections.Counter(second_seq) 1203 except TypeError: 1204 # Handle case with unhashable elements 1205 differences = _count_diff_all_purpose(first_seq, second_seq) 1206 else: 1207 if first == second: 1208 return 1209 differences = _count_diff_hashable(first_seq, second_seq) 1210 1211 if differences: 1212 standardMsg = 'Element counts were not equal:\n' 1213 lines = ['First has %d, Second has %d: %r' % diff for diff in differences] 1214 diffMsg = '\n'.join(lines) 1215 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1216 msg = self._formatMessage(msg, standardMsg) 1217 self.fail(msg) 1218 1219 def assertMultiLineEqual(self, first, second, msg=None): 1220 """Assert that two multi-line strings are equal.""" 1221 self.assertIsInstance(first, str, "First argument is not a string") 1222 self.assertIsInstance(second, str, "Second argument is not a string") 1223 1224 if first != second: 1225 # Don't use difflib if the strings are too long 1226 if (len(first) > self._diffThreshold or 1227 len(second) > self._diffThreshold): 1228 self._baseAssertEqual(first, second, msg) 1229 1230 # Append \n to both strings if either is missing the \n. 1231 # This allows the final ndiff to show the \n difference. The 1232 # exception here is if the string is empty, in which case no 1233 # \n should be added 1234 first_presplit = first 1235 second_presplit = second 1236 if first and second: 1237 if first[-1] != '\n' or second[-1] != '\n': 1238 first_presplit += '\n' 1239 second_presplit += '\n' 1240 elif second and second[-1] != '\n': 1241 second_presplit += '\n' 1242 elif first and first[-1] != '\n': 1243 first_presplit += '\n' 1244 1245 firstlines = first_presplit.splitlines(keepends=True) 1246 secondlines = second_presplit.splitlines(keepends=True) 1247 1248 # Generate the message and diff, then raise the exception 1249 standardMsg = '%s != %s' % _common_shorten_repr(first, second) 1250 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) 1251 standardMsg = self._truncateMessage(standardMsg, diff) 1252 self.fail(self._formatMessage(msg, standardMsg)) 1253 1254 def assertLess(self, a, b, msg=None): 1255 """Just like self.assertTrue(a < b), but with a nicer default message.""" 1256 if not a < b: 1257 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) 1258 self.fail(self._formatMessage(msg, standardMsg)) 1259 1260 def assertLessEqual(self, a, b, msg=None): 1261 """Just like self.assertTrue(a <= b), but with a nicer default message.""" 1262 if not a <= b: 1263 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) 1264 self.fail(self._formatMessage(msg, standardMsg)) 1265 1266 def assertGreater(self, a, b, msg=None): 1267 """Just like self.assertTrue(a > b), but with a nicer default message.""" 1268 if not a > b: 1269 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) 1270 self.fail(self._formatMessage(msg, standardMsg)) 1271 1272 def assertGreaterEqual(self, a, b, msg=None): 1273 """Just like self.assertTrue(a >= b), but with a nicer default message.""" 1274 if not a >= b: 1275 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) 1276 self.fail(self._formatMessage(msg, standardMsg)) 1277 1278 def assertIsNone(self, obj, msg=None): 1279 """Same as self.assertTrue(obj is None), with a nicer default message.""" 1280 if obj is not None: 1281 standardMsg = '%s is not None' % (safe_repr(obj),) 1282 self.fail(self._formatMessage(msg, standardMsg)) 1283 1284 def assertIsNotNone(self, obj, msg=None): 1285 """Included for symmetry with assertIsNone.""" 1286 if obj is None: 1287 standardMsg = 'unexpectedly None' 1288 self.fail(self._formatMessage(msg, standardMsg)) 1289 1290 def assertIsInstance(self, obj, cls, msg=None): 1291 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer 1292 default message.""" 1293 if not isinstance(obj, cls): 1294 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) 1295 self.fail(self._formatMessage(msg, standardMsg)) 1296 1297 def assertNotIsInstance(self, obj, cls, msg=None): 1298 """Included for symmetry with assertIsInstance.""" 1299 if isinstance(obj, cls): 1300 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) 1301 self.fail(self._formatMessage(msg, standardMsg)) 1302 1303 def assertRaisesRegex(self, expected_exception, expected_regex, 1304 *args, **kwargs): 1305 """Asserts that the message in a raised exception matches a regex. 1306 1307 Args: 1308 expected_exception: Exception class expected to be raised. 1309 expected_regex: Regex (re.Pattern object or string) expected 1310 to be found in error message. 1311 args: Function to be called and extra positional args. 1312 kwargs: Extra kwargs. 1313 msg: Optional message used in case of failure. Can only be used 1314 when assertRaisesRegex is used as a context manager. 1315 """ 1316 context = _AssertRaisesContext(expected_exception, self, expected_regex) 1317 return context.handle('assertRaisesRegex', args, kwargs) 1318 1319 def assertWarnsRegex(self, expected_warning, expected_regex, 1320 *args, **kwargs): 1321 """Asserts that the message in a triggered warning matches a regexp. 1322 Basic functioning is similar to assertWarns() with the addition 1323 that only warnings whose messages also match the regular expression 1324 are considered successful matches. 1325 1326 Args: 1327 expected_warning: Warning class expected to be triggered. 1328 expected_regex: Regex (re.Pattern object or string) expected 1329 to be found in error message. 1330 args: Function to be called and extra positional args. 1331 kwargs: Extra kwargs. 1332 msg: Optional message used in case of failure. Can only be used 1333 when assertWarnsRegex is used as a context manager. 1334 """ 1335 context = _AssertWarnsContext(expected_warning, self, expected_regex) 1336 return context.handle('assertWarnsRegex', args, kwargs) 1337 1338 def assertRegex(self, text, expected_regex, msg=None): 1339 """Fail the test unless the text matches the regular expression.""" 1340 if isinstance(expected_regex, (str, bytes)): 1341 assert expected_regex, "expected_regex must not be empty." 1342 expected_regex = re.compile(expected_regex) 1343 if not expected_regex.search(text): 1344 standardMsg = "Regex didn't match: %r not found in %r" % ( 1345 expected_regex.pattern, text) 1346 # _formatMessage ensures the longMessage option is respected 1347 msg = self._formatMessage(msg, standardMsg) 1348 raise self.failureException(msg) 1349 1350 def assertNotRegex(self, text, unexpected_regex, msg=None): 1351 """Fail the test if the text matches the regular expression.""" 1352 if isinstance(unexpected_regex, (str, bytes)): 1353 unexpected_regex = re.compile(unexpected_regex) 1354 match = unexpected_regex.search(text) 1355 if match: 1356 standardMsg = 'Regex matched: %r matches %r in %r' % ( 1357 text[match.start() : match.end()], 1358 unexpected_regex.pattern, 1359 text) 1360 # _formatMessage ensures the longMessage option is respected 1361 msg = self._formatMessage(msg, standardMsg) 1362 raise self.failureException(msg)
A class whose instances are single test cases.
By default, the test code itself should be placed in a method named 'runTest'.
If the fixture may be used for many test cases, create as many test methods as are needed. When instantiating such a TestCase subclass, specify in the constructor arguments the name of the test method that the instance is to execute.
Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively.
If it is necessary to override the __init__ method, the base class __init__ method must always be called. It is important that subclasses should not change the signature of their __init__ method, since instances of the classes are instantiated automatically by parts of the framework in order to be run.
When subclassing TestCase, you can set these attributes:
- failureException: determines which exception will be raised when the instance's assertion methods fail; test methods raising this exception will be deemed to have 'failed' rather than 'errored'.
- longMessage: determines whether long messages (including repr of objects used in assert methods) will be printed on failure in addition to any explicit message passed.
- maxDiff: sets the maximum length of a diff in failure messages by assert methods using difflib. It is looked up as an instance attribute so can be configured by individual tests if required.
395 def __init__(self, methodName='runTest'): 396 """Create an instance of the class that will use the named test 397 method when executed. Raises a ValueError if the instance does 398 not have a method with the specified name. 399 """ 400 self._testMethodName = methodName 401 self._outcome = None 402 self._testMethodDoc = 'No test' 403 try: 404 testMethod = getattr(self, methodName) 405 except AttributeError: 406 if methodName != 'runTest': 407 # we allow instantiation with no explicit method name 408 # but not an *incorrect* or missing method name 409 raise ValueError("no such test method in %s: %s" % 410 (self.__class__, methodName)) 411 else: 412 self._testMethodDoc = testMethod.__doc__ 413 self._cleanups = [] 414 self._subtest = None 415 416 # Map types to custom assertEqual functions that will compare 417 # instances of said type in more detail to generate a more useful 418 # error message. 419 self._type_equality_funcs = {} 420 self.addTypeEqualityFunc(dict, 'assertDictEqual') 421 self.addTypeEqualityFunc(list, 'assertListEqual') 422 self.addTypeEqualityFunc(tuple, 'assertTupleEqual') 423 self.addTypeEqualityFunc(set, 'assertSetEqual') 424 self.addTypeEqualityFunc(frozenset, 'assertSetEqual') 425 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.
427 def addTypeEqualityFunc(self, typeobj, function): 428 """Add a type specific assertEqual style function to compare a type. 429 430 This method is for use by TestCase subclasses that need to register 431 their own type equality functions to provide nicer error messages. 432 433 Args: 434 typeobj: The data type to call this function on when both values 435 are of the same type in assertEqual(). 436 function: The callable taking two arguments and an optional 437 msg= argument that raises self.failureException with a 438 useful error message when the two arguments are not equal. 439 """ 440 self._type_equality_funcs[typeobj] = function
Add a type specific assertEqual style function to compare a type.
This method is for use by TestCase subclasses that need to register their own type equality functions to provide nicer error messages.
Arguments:
- typeobj: The data type to call this function on when both values are of the same type in assertEqual().
- function: The callable taking two arguments and an optional msg= argument that raises self.failureException with a useful error message when the two arguments are not equal.
442 def addCleanup(self, function, /, *args, **kwargs): 443 """Add a function, with arguments, to be called when the test is 444 completed. Functions added are called on a LIFO basis and are 445 called after tearDown on test failure or success. 446 447 Cleanup items are called even if setUp fails (unlike tearDown).""" 448 self._cleanups.append((function, args, kwargs))
Add a function, with arguments, to be called when the test is completed. Functions added are called on a LIFO basis and are called after tearDown on test failure or success.
Cleanup items are called even if setUp fails (unlike tearDown).
450 def enterContext(self, cm): 451 """Enters the supplied context manager. 452 453 If successful, also adds its __exit__ method as a cleanup 454 function and returns the result of the __enter__ method. 455 """ 456 return _enter_context(cm, self.addCleanup)
Enters the supplied context manager.
If successful, also adds its __exit__ method as a cleanup function and returns the result of the __enter__ method.
458 @classmethod 459 def addClassCleanup(cls, function, /, *args, **kwargs): 460 """Same as addCleanup, except the cleanup items are called even if 461 setUpClass fails (unlike tearDownClass).""" 462 cls._class_cleanups.append((function, args, kwargs))
Same as addCleanup, except the cleanup items are called even if setUpClass fails (unlike tearDownClass).
464 @classmethod 465 def enterClassContext(cls, cm): 466 """Same as enterContext, but class-wide.""" 467 return _enter_context(cm, cls.addClassCleanup)
Same as enterContext, but class-wide.
469 def setUp(self): 470 "Hook method for setting up the test fixture before exercising it." 471 pass
Hook method for setting up the test fixture before exercising it.
473 def tearDown(self): 474 "Hook method for deconstructing the test fixture after testing it." 475 pass
Hook method for deconstructing the test fixture after testing it.
477 @classmethod 478 def setUpClass(cls): 479 "Hook method for setting up class fixture before running tests in the class."
Hook method for setting up class fixture before running tests in the class.
481 @classmethod 482 def tearDownClass(cls): 483 "Hook method for deconstructing the class fixture after running all tests in the class."
Hook method for deconstructing the class fixture after running all tests in the class.
491 def shortDescription(self): 492 """Returns a one-line description of the test, or None if no 493 description has been provided. 494 495 The default implementation of this method returns the first line of 496 the specified test method's docstring. 497 """ 498 doc = self._testMethodDoc 499 return doc.strip().split("\n")[0].strip() if doc else None
Returns a one-line description of the test, or None if no description has been provided.
The default implementation of this method returns the first line of the specified test method's docstring.
521 @contextlib.contextmanager 522 def subTest(self, msg=_subtest_msg_sentinel, **params): 523 """Return a context manager that will return the enclosed block 524 of code in a subtest identified by the optional message and 525 keyword parameters. A failure in the subtest marks the test 526 case as failed but resumes execution at the end of the enclosed 527 block, allowing further test code to be executed. 528 """ 529 if self._outcome is None or not self._outcome.result_supports_subtests: 530 yield 531 return 532 parent = self._subtest 533 if parent is None: 534 params_map = _OrderedChainMap(params) 535 else: 536 params_map = parent.params.new_child(params) 537 self._subtest = _SubTest(self, msg, params_map) 538 try: 539 with self._outcome.testPartExecutor(self._subtest, subTest=True): 540 yield 541 if not self._outcome.success: 542 result = self._outcome.result 543 if result is not None and result.failfast: 544 raise _ShouldStop 545 elif self._outcome.expectedFailure: 546 # If the test is expecting a failure, we really want to 547 # stop now and register the expected failure. 548 raise _ShouldStop 549 finally: 550 self._subtest = parent
Return a context manager that will return the enclosed block of code in a subtest identified by the optional message and keyword parameters. A failure in the subtest marks the test case as failed but resumes execution at the end of the enclosed block, allowing further test code to be executed.
600 def run(self, result=None): 601 if result is None: 602 result = self.defaultTestResult() 603 startTestRun = getattr(result, 'startTestRun', None) 604 stopTestRun = getattr(result, 'stopTestRun', None) 605 if startTestRun is not None: 606 startTestRun() 607 else: 608 stopTestRun = None 609 610 result.startTest(self) 611 try: 612 testMethod = getattr(self, self._testMethodName) 613 if (getattr(self.__class__, "__unittest_skip__", False) or 614 getattr(testMethod, "__unittest_skip__", False)): 615 # If the class or method was skipped. 616 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 617 or getattr(testMethod, '__unittest_skip_why__', '')) 618 _addSkip(result, self, skip_why) 619 return result 620 621 expecting_failure = ( 622 getattr(self, "__unittest_expecting_failure__", False) or 623 getattr(testMethod, "__unittest_expecting_failure__", False) 624 ) 625 outcome = _Outcome(result) 626 start_time = time.perf_counter() 627 try: 628 self._outcome = outcome 629 630 with outcome.testPartExecutor(self): 631 self._callSetUp() 632 if outcome.success: 633 outcome.expecting_failure = expecting_failure 634 with outcome.testPartExecutor(self): 635 self._callTestMethod(testMethod) 636 outcome.expecting_failure = False 637 with outcome.testPartExecutor(self): 638 self._callTearDown() 639 self.doCleanups() 640 self._addDuration(result, (time.perf_counter() - start_time)) 641 642 if outcome.success: 643 if expecting_failure: 644 if outcome.expectedFailure: 645 self._addExpectedFailure(result, outcome.expectedFailure) 646 else: 647 self._addUnexpectedSuccess(result) 648 else: 649 result.addSuccess(self) 650 return result 651 finally: 652 # explicitly break reference cycle: 653 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure 654 outcome.expectedFailure = None 655 outcome = None 656 657 # clear the outcome, no more needed 658 self._outcome = None 659 660 finally: 661 result.stopTest(self) 662 if stopTestRun is not None: 663 stopTestRun()
665 def doCleanups(self): 666 """Execute all cleanup functions. Normally called for you after 667 tearDown.""" 668 outcome = self._outcome or _Outcome() 669 while self._cleanups: 670 function, args, kwargs = self._cleanups.pop() 671 with outcome.testPartExecutor(self): 672 self._callCleanup(function, *args, **kwargs) 673 674 # return this for backwards compatibility 675 # even though we no longer use it internally 676 return outcome.success
Execute all cleanup functions. Normally called for you after tearDown.
678 @classmethod 679 def doClassCleanups(cls): 680 """Execute all class cleanup functions. Normally called for you after 681 tearDownClass.""" 682 cls.tearDown_exceptions = [] 683 while cls._class_cleanups: 684 function, args, kwargs = cls._class_cleanups.pop() 685 try: 686 function(*args, **kwargs) 687 except Exception: 688 cls.tearDown_exceptions.append(sys.exc_info())
Execute all class cleanup functions. Normally called for you after tearDownClass.
693 def debug(self): 694 """Run the test without collecting errors in a TestResult""" 695 testMethod = getattr(self, self._testMethodName) 696 if (getattr(self.__class__, "__unittest_skip__", False) or 697 getattr(testMethod, "__unittest_skip__", False)): 698 # If the class or method was skipped. 699 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 700 or getattr(testMethod, '__unittest_skip_why__', '')) 701 raise SkipTest(skip_why) 702 703 self._callSetUp() 704 self._callTestMethod(testMethod) 705 self._callTearDown() 706 while self._cleanups: 707 function, args, kwargs = self._cleanups.pop() 708 self._callCleanup(function, *args, **kwargs)
Run the test without collecting errors in a TestResult
714 def fail(self, msg=None): 715 """Fail immediately, with the given message.""" 716 raise self.failureException(msg)
Fail immediately, with the given message.
718 def assertFalse(self, expr, msg=None): 719 """Check that the expression is false.""" 720 if expr: 721 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr)) 722 raise self.failureException(msg)
Check that the expression is false.
724 def assertTrue(self, expr, msg=None): 725 """Check that the expression is true.""" 726 if not expr: 727 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr)) 728 raise self.failureException(msg)
Check that the expression is true.
751 def assertRaises(self, expected_exception, *args, **kwargs): 752 """Fail unless an exception of class expected_exception is raised 753 by the callable when invoked with specified positional and 754 keyword arguments. If a different type of exception is 755 raised, it will not be caught, and the test case will be 756 deemed to have suffered an error, exactly as for an 757 unexpected exception. 758 759 If called with the callable and arguments omitted, will return a 760 context object used like this:: 761 762 with self.assertRaises(SomeException): 763 do_something() 764 765 An optional keyword argument 'msg' can be provided when assertRaises 766 is used as a context object. 767 768 The context manager keeps a reference to the exception as 769 the 'exception' attribute. This allows you to inspect the 770 exception after the assertion:: 771 772 with self.assertRaises(SomeException) as cm: 773 do_something() 774 the_exception = cm.exception 775 self.assertEqual(the_exception.error_code, 3) 776 """ 777 context = _AssertRaisesContext(expected_exception, self) 778 try: 779 return context.handle('assertRaises', args, kwargs) 780 finally: 781 # bpo-23890: manually break a reference cycle 782 context = None
Fail unless an exception of class expected_exception is raised by the callable when invoked with specified positional and keyword arguments. If a different type of exception is raised, it will not be caught, and the test case will be deemed to have suffered an error, exactly as for an unexpected exception.
If called with the callable and arguments omitted, will return a context object used like this::
with self.assertRaises(SomeException):
do_something()
An optional keyword argument 'msg' can be provided when assertRaises is used as a context object.
The context manager keeps a reference to the exception as the 'exception' attribute. This allows you to inspect the exception after the assertion::
with self.assertRaises(SomeException) as cm:
do_something()
the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)
784 def assertWarns(self, expected_warning, *args, **kwargs): 785 """Fail unless a warning of class warnClass is triggered 786 by the callable when invoked with specified positional and 787 keyword arguments. If a different type of warning is 788 triggered, it will not be handled: depending on the other 789 warning filtering rules in effect, it might be silenced, printed 790 out, or raised as an exception. 791 792 If called with the callable and arguments omitted, will return a 793 context object used like this:: 794 795 with self.assertWarns(SomeWarning): 796 do_something() 797 798 An optional keyword argument 'msg' can be provided when assertWarns 799 is used as a context object. 800 801 The context manager keeps a reference to the first matching 802 warning as the 'warning' attribute; similarly, the 'filename' 803 and 'lineno' attributes give you information about the line 804 of Python code from which the warning was triggered. 805 This allows you to inspect the warning after the assertion:: 806 807 with self.assertWarns(SomeWarning) as cm: 808 do_something() 809 the_warning = cm.warning 810 self.assertEqual(the_warning.some_attribute, 147) 811 """ 812 context = _AssertWarnsContext(expected_warning, self) 813 return context.handle('assertWarns', args, kwargs)
Fail unless a warning of class warnClass is triggered by the callable when invoked with specified positional and keyword arguments. If a different type of warning is triggered, it will not be handled: depending on the other warning filtering rules in effect, it might be silenced, printed out, or raised as an exception.
If called with the callable and arguments omitted, will return a context object used like this::
with self.assertWarns(SomeWarning):
do_something()
An optional keyword argument 'msg' can be provided when assertWarns is used as a context object.
The context manager keeps a reference to the first matching warning as the 'warning' attribute; similarly, the 'filename' and 'lineno' attributes give you information about the line of Python code from which the warning was triggered. This allows you to inspect the warning after the assertion::
with self.assertWarns(SomeWarning) as cm:
do_something()
the_warning = cm.warning
self.assertEqual(the_warning.some_attribute, 147)
815 def assertLogs(self, logger=None, level=None): 816 """Fail unless a log message of level *level* or higher is emitted 817 on *logger_name* or its children. If omitted, *level* defaults to 818 INFO and *logger* defaults to the root logger. 819 820 This method must be used as a context manager, and will yield 821 a recording object with two attributes: `output` and `records`. 822 At the end of the context manager, the `output` attribute will 823 be a list of the matching formatted log messages and the 824 `records` attribute will be a list of the corresponding LogRecord 825 objects. 826 827 Example:: 828 829 with self.assertLogs('foo', level='INFO') as cm: 830 logging.getLogger('foo').info('first message') 831 logging.getLogger('foo.bar').error('second message') 832 self.assertEqual(cm.output, ['INFO:foo:first message', 833 'ERROR:foo.bar:second message']) 834 """ 835 # Lazy import to avoid importing logging if it is not needed. 836 from ._log import _AssertLogsContext 837 return _AssertLogsContext(self, logger, level, no_logs=False)
Fail unless a log message of level level or higher is emitted on logger_name or its children. If omitted, level defaults to INFO and logger defaults to the root logger.
This method must be used as a context manager, and will yield
a recording object with two attributes: output
and records
.
At the end of the context manager, the output
attribute will
be a list of the matching formatted log messages and the
records
attribute will be a list of the corresponding LogRecord
objects.
Example::
with self.assertLogs('foo', level='INFO') as cm:
logging.getLogger('foo').info('first message')
logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
'ERROR:foo.bar:second message'])
839 def assertNoLogs(self, logger=None, level=None): 840 """ Fail unless no log messages of level *level* or higher are emitted 841 on *logger_name* or its children. 842 843 This method must be used as a context manager. 844 """ 845 from ._log import _AssertLogsContext 846 return _AssertLogsContext(self, logger, level, no_logs=True)
Fail unless no log messages of level level or higher are emitted on logger_name or its children.
This method must be used as a context manager.
881 def assertEqual(self, first, second, msg=None): 882 """Fail if the two objects are unequal as determined by the '==' 883 operator. 884 """ 885 assertion_func = self._getAssertEqualityFunc(first, second) 886 assertion_func(first, second, msg=msg)
Fail if the two objects are unequal as determined by the '==' operator.
888 def assertNotEqual(self, first, second, msg=None): 889 """Fail if the two objects are equal as determined by the '!=' 890 operator. 891 """ 892 if not first != second: 893 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), 894 safe_repr(second))) 895 raise self.failureException(msg)
Fail if the two objects are equal as determined by the '!=' operator.
897 def assertAlmostEqual(self, first, second, places=None, msg=None, 898 delta=None): 899 """Fail if the two objects are unequal as determined by their 900 difference rounded to the given number of decimal places 901 (default 7) and comparing to zero, or by comparing that the 902 difference between the two objects is more than the given 903 delta. 904 905 Note that decimal places (from zero) are usually not the same 906 as significant digits (measured from the most significant digit). 907 908 If the two objects compare equal then they will automatically 909 compare almost equal. 910 """ 911 if first == second: 912 # shortcut 913 return 914 if delta is not None and places is not None: 915 raise TypeError("specify delta or places not both") 916 917 diff = abs(first - second) 918 if delta is not None: 919 if diff <= delta: 920 return 921 922 standardMsg = '%s != %s within %s delta (%s difference)' % ( 923 safe_repr(first), 924 safe_repr(second), 925 safe_repr(delta), 926 safe_repr(diff)) 927 else: 928 if places is None: 929 places = 7 930 931 if round(diff, places) == 0: 932 return 933 934 standardMsg = '%s != %s within %r places (%s difference)' % ( 935 safe_repr(first), 936 safe_repr(second), 937 places, 938 safe_repr(diff)) 939 msg = self._formatMessage(msg, standardMsg) 940 raise self.failureException(msg)
Fail if the two objects are unequal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero, or by comparing that the difference between the two objects is more than the given delta.
Note that decimal places (from zero) are usually not the same as significant digits (measured from the most significant digit).
If the two objects compare equal then they will automatically compare almost equal.
942 def assertNotAlmostEqual(self, first, second, places=None, msg=None, 943 delta=None): 944 """Fail if the two objects are equal as determined by their 945 difference rounded to the given number of decimal places 946 (default 7) and comparing to zero, or by comparing that the 947 difference between the two objects is less than the given delta. 948 949 Note that decimal places (from zero) are usually not the same 950 as significant digits (measured from the most significant digit). 951 952 Objects that are equal automatically fail. 953 """ 954 if delta is not None and places is not None: 955 raise TypeError("specify delta or places not both") 956 diff = abs(first - second) 957 if delta is not None: 958 if not (first == second) and diff > delta: 959 return 960 standardMsg = '%s == %s within %s delta (%s difference)' % ( 961 safe_repr(first), 962 safe_repr(second), 963 safe_repr(delta), 964 safe_repr(diff)) 965 else: 966 if places is None: 967 places = 7 968 if not (first == second) and round(diff, places) != 0: 969 return 970 standardMsg = '%s == %s within %r places' % (safe_repr(first), 971 safe_repr(second), 972 places) 973 974 msg = self._formatMessage(msg, standardMsg) 975 raise self.failureException(msg)
Fail if the two objects are equal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero, or by comparing that the difference between the two objects is less than the given delta.
Note that decimal places (from zero) are usually not the same as significant digits (measured from the most significant digit).
Objects that are equal automatically fail.
977 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): 978 """An equality assertion for ordered sequences (like lists and tuples). 979 980 For the purposes of this function, a valid ordered sequence type is one 981 which can be indexed, has a length, and has an equality operator. 982 983 Args: 984 seq1: The first sequence to compare. 985 seq2: The second sequence to compare. 986 seq_type: The expected datatype of the sequences, or None if no 987 datatype should be enforced. 988 msg: Optional message to use on failure instead of a list of 989 differences. 990 """ 991 if seq_type is not None: 992 seq_type_name = seq_type.__name__ 993 if not isinstance(seq1, seq_type): 994 raise self.failureException('First sequence is not a %s: %s' 995 % (seq_type_name, safe_repr(seq1))) 996 if not isinstance(seq2, seq_type): 997 raise self.failureException('Second sequence is not a %s: %s' 998 % (seq_type_name, safe_repr(seq2))) 999 else: 1000 seq_type_name = "sequence" 1001 1002 differing = None 1003 try: 1004 len1 = len(seq1) 1005 except (TypeError, NotImplementedError): 1006 differing = 'First %s has no length. Non-sequence?' % ( 1007 seq_type_name) 1008 1009 if differing is None: 1010 try: 1011 len2 = len(seq2) 1012 except (TypeError, NotImplementedError): 1013 differing = 'Second %s has no length. Non-sequence?' % ( 1014 seq_type_name) 1015 1016 if differing is None: 1017 if seq1 == seq2: 1018 return 1019 1020 differing = '%ss differ: %s != %s\n' % ( 1021 (seq_type_name.capitalize(),) + 1022 _common_shorten_repr(seq1, seq2)) 1023 1024 for i in range(min(len1, len2)): 1025 try: 1026 item1 = seq1[i] 1027 except (TypeError, IndexError, NotImplementedError): 1028 differing += ('\nUnable to index element %d of first %s\n' % 1029 (i, seq_type_name)) 1030 break 1031 1032 try: 1033 item2 = seq2[i] 1034 except (TypeError, IndexError, NotImplementedError): 1035 differing += ('\nUnable to index element %d of second %s\n' % 1036 (i, seq_type_name)) 1037 break 1038 1039 if item1 != item2: 1040 differing += ('\nFirst differing element %d:\n%s\n%s\n' % 1041 ((i,) + _common_shorten_repr(item1, item2))) 1042 break 1043 else: 1044 if (len1 == len2 and seq_type is None and 1045 type(seq1) != type(seq2)): 1046 # The sequences are the same, but have differing types. 1047 return 1048 1049 if len1 > len2: 1050 differing += ('\nFirst %s contains %d additional ' 1051 'elements.\n' % (seq_type_name, len1 - len2)) 1052 try: 1053 differing += ('First extra element %d:\n%s\n' % 1054 (len2, safe_repr(seq1[len2]))) 1055 except (TypeError, IndexError, NotImplementedError): 1056 differing += ('Unable to index element %d ' 1057 'of first %s\n' % (len2, seq_type_name)) 1058 elif len1 < len2: 1059 differing += ('\nSecond %s contains %d additional ' 1060 'elements.\n' % (seq_type_name, len2 - len1)) 1061 try: 1062 differing += ('First extra element %d:\n%s\n' % 1063 (len1, safe_repr(seq2[len1]))) 1064 except (TypeError, IndexError, NotImplementedError): 1065 differing += ('Unable to index element %d ' 1066 'of second %s\n' % (len1, seq_type_name)) 1067 standardMsg = differing 1068 diffMsg = '\n' + '\n'.join( 1069 difflib.ndiff(pprint.pformat(seq1).splitlines(), 1070 pprint.pformat(seq2).splitlines())) 1071 1072 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1073 msg = self._formatMessage(msg, standardMsg) 1074 self.fail(msg)
An equality assertion for ordered sequences (like lists and tuples).
For the purposes of this function, a valid ordered sequence type is one which can be indexed, has a length, and has an equality operator.
Arguments:
- seq1: The first sequence to compare.
- seq2: The second sequence to compare.
- seq_type: The expected datatype of the sequences, or None if no datatype should be enforced.
- msg: Optional message to use on failure instead of a list of differences.
1082 def assertListEqual(self, list1, list2, msg=None): 1083 """A list-specific equality assertion. 1084 1085 Args: 1086 list1: The first list to compare. 1087 list2: The second list to compare. 1088 msg: Optional message to use on failure instead of a list of 1089 differences. 1090 1091 """ 1092 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
A list-specific equality assertion.
Arguments:
- list1: The first list to compare.
- list2: The second list to compare.
- msg: Optional message to use on failure instead of a list of differences.
1094 def assertTupleEqual(self, tuple1, tuple2, msg=None): 1095 """A tuple-specific equality assertion. 1096 1097 Args: 1098 tuple1: The first tuple to compare. 1099 tuple2: The second tuple to compare. 1100 msg: Optional message to use on failure instead of a list of 1101 differences. 1102 """ 1103 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
A tuple-specific equality assertion.
Arguments:
- tuple1: The first tuple to compare.
- tuple2: The second tuple to compare.
- msg: Optional message to use on failure instead of a list of differences.
1105 def assertSetEqual(self, set1, set2, msg=None): 1106 """A set-specific equality assertion. 1107 1108 Args: 1109 set1: The first set to compare. 1110 set2: The second set to compare. 1111 msg: Optional message to use on failure instead of a list of 1112 differences. 1113 1114 assertSetEqual uses ducktyping to support different types of sets, and 1115 is optimized for sets specifically (parameters must support a 1116 difference method). 1117 """ 1118 try: 1119 difference1 = set1.difference(set2) 1120 except TypeError as e: 1121 self.fail('invalid type when attempting set difference: %s' % e) 1122 except AttributeError as e: 1123 self.fail('first argument does not support set difference: %s' % e) 1124 1125 try: 1126 difference2 = set2.difference(set1) 1127 except TypeError as e: 1128 self.fail('invalid type when attempting set difference: %s' % e) 1129 except AttributeError as e: 1130 self.fail('second argument does not support set difference: %s' % e) 1131 1132 if not (difference1 or difference2): 1133 return 1134 1135 lines = [] 1136 if difference1: 1137 lines.append('Items in the first set but not the second:') 1138 for item in difference1: 1139 lines.append(repr(item)) 1140 if difference2: 1141 lines.append('Items in the second set but not the first:') 1142 for item in difference2: 1143 lines.append(repr(item)) 1144 1145 standardMsg = '\n'.join(lines) 1146 self.fail(self._formatMessage(msg, standardMsg))
A set-specific equality assertion.
Arguments:
- set1: The first set to compare.
- set2: The second set to compare.
- msg: Optional message to use on failure instead of a list of differences.
assertSetEqual uses ducktyping to support different types of sets, and is optimized for sets specifically (parameters must support a difference method).
1148 def assertIn(self, member, container, msg=None): 1149 """Just like self.assertTrue(a in b), but with a nicer default message.""" 1150 if member not in container: 1151 standardMsg = '%s not found in %s' % (safe_repr(member), 1152 safe_repr(container)) 1153 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a in b), but with a nicer default message.
1155 def assertNotIn(self, member, container, msg=None): 1156 """Just like self.assertTrue(a not in b), but with a nicer default message.""" 1157 if member in container: 1158 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), 1159 safe_repr(container)) 1160 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a not in b), but with a nicer default message.
1162 def assertIs(self, expr1, expr2, msg=None): 1163 """Just like self.assertTrue(a is b), but with a nicer default message.""" 1164 if expr1 is not expr2: 1165 standardMsg = '%s is not %s' % (safe_repr(expr1), 1166 safe_repr(expr2)) 1167 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a is b), but with a nicer default message.
1169 def assertIsNot(self, expr1, expr2, msg=None): 1170 """Just like self.assertTrue(a is not b), but with a nicer default message.""" 1171 if expr1 is expr2: 1172 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) 1173 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a is not b), but with a nicer default message.
1175 def assertDictEqual(self, d1, d2, msg=None): 1176 self.assertIsInstance(d1, dict, 'First argument is not a dictionary') 1177 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') 1178 1179 if d1 != d2: 1180 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2) 1181 diff = ('\n' + '\n'.join(difflib.ndiff( 1182 pprint.pformat(d1).splitlines(), 1183 pprint.pformat(d2).splitlines()))) 1184 standardMsg = self._truncateMessage(standardMsg, diff) 1185 self.fail(self._formatMessage(msg, standardMsg))
1187 def assertCountEqual(self, first, second, msg=None): 1188 """Asserts that two iterables have the same elements, the same number of 1189 times, without regard to order. 1190 1191 self.assertEqual(Counter(list(first)), 1192 Counter(list(second))) 1193 1194 Example: 1195 - [0, 1, 1] and [1, 0, 1] compare equal. 1196 - [0, 0, 1] and [0, 1] compare unequal. 1197 1198 """ 1199 first_seq, second_seq = list(first), list(second) 1200 try: 1201 first = collections.Counter(first_seq) 1202 second = collections.Counter(second_seq) 1203 except TypeError: 1204 # Handle case with unhashable elements 1205 differences = _count_diff_all_purpose(first_seq, second_seq) 1206 else: 1207 if first == second: 1208 return 1209 differences = _count_diff_hashable(first_seq, second_seq) 1210 1211 if differences: 1212 standardMsg = 'Element counts were not equal:\n' 1213 lines = ['First has %d, Second has %d: %r' % diff for diff in differences] 1214 diffMsg = '\n'.join(lines) 1215 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1216 msg = self._formatMessage(msg, standardMsg) 1217 self.fail(msg)
Asserts that two iterables have the same elements, the same number of times, without regard to order.
self.assertEqual(Counter(list(first)),
Counter(list(second)))
Example: - [0, 1, 1] and [1, 0, 1] compare equal. - [0, 0, 1] and [0, 1] compare unequal.
1219 def assertMultiLineEqual(self, first, second, msg=None): 1220 """Assert that two multi-line strings are equal.""" 1221 self.assertIsInstance(first, str, "First argument is not a string") 1222 self.assertIsInstance(second, str, "Second argument is not a string") 1223 1224 if first != second: 1225 # Don't use difflib if the strings are too long 1226 if (len(first) > self._diffThreshold or 1227 len(second) > self._diffThreshold): 1228 self._baseAssertEqual(first, second, msg) 1229 1230 # Append \n to both strings if either is missing the \n. 1231 # This allows the final ndiff to show the \n difference. The 1232 # exception here is if the string is empty, in which case no 1233 # \n should be added 1234 first_presplit = first 1235 second_presplit = second 1236 if first and second: 1237 if first[-1] != '\n' or second[-1] != '\n': 1238 first_presplit += '\n' 1239 second_presplit += '\n' 1240 elif second and second[-1] != '\n': 1241 second_presplit += '\n' 1242 elif first and first[-1] != '\n': 1243 first_presplit += '\n' 1244 1245 firstlines = first_presplit.splitlines(keepends=True) 1246 secondlines = second_presplit.splitlines(keepends=True) 1247 1248 # Generate the message and diff, then raise the exception 1249 standardMsg = '%s != %s' % _common_shorten_repr(first, second) 1250 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) 1251 standardMsg = self._truncateMessage(standardMsg, diff) 1252 self.fail(self._formatMessage(msg, standardMsg))
Assert that two multi-line strings are equal.
1254 def assertLess(self, a, b, msg=None): 1255 """Just like self.assertTrue(a < b), but with a nicer default message.""" 1256 if not a < b: 1257 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) 1258 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a < b), but with a nicer default message.
1260 def assertLessEqual(self, a, b, msg=None): 1261 """Just like self.assertTrue(a <= b), but with a nicer default message.""" 1262 if not a <= b: 1263 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) 1264 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a <= b), but with a nicer default message.
1266 def assertGreater(self, a, b, msg=None): 1267 """Just like self.assertTrue(a > b), but with a nicer default message.""" 1268 if not a > b: 1269 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) 1270 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a > b), but with a nicer default message.
1272 def assertGreaterEqual(self, a, b, msg=None): 1273 """Just like self.assertTrue(a >= b), but with a nicer default message.""" 1274 if not a >= b: 1275 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) 1276 self.fail(self._formatMessage(msg, standardMsg))
Just like self.assertTrue(a >= b), but with a nicer default message.
1278 def assertIsNone(self, obj, msg=None): 1279 """Same as self.assertTrue(obj is None), with a nicer default message.""" 1280 if obj is not None: 1281 standardMsg = '%s is not None' % (safe_repr(obj),) 1282 self.fail(self._formatMessage(msg, standardMsg))
Same as self.assertTrue(obj is None), with a nicer default message.
1284 def assertIsNotNone(self, obj, msg=None): 1285 """Included for symmetry with assertIsNone.""" 1286 if obj is None: 1287 standardMsg = 'unexpectedly None' 1288 self.fail(self._formatMessage(msg, standardMsg))
Included for symmetry with assertIsNone.
1290 def assertIsInstance(self, obj, cls, msg=None): 1291 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer 1292 default message.""" 1293 if not isinstance(obj, cls): 1294 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) 1295 self.fail(self._formatMessage(msg, standardMsg))
Same as self.assertTrue(isinstance(obj, cls)), with a nicer default message.
1297 def assertNotIsInstance(self, obj, cls, msg=None): 1298 """Included for symmetry with assertIsInstance.""" 1299 if isinstance(obj, cls): 1300 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) 1301 self.fail(self._formatMessage(msg, standardMsg))
Included for symmetry with assertIsInstance.
1303 def assertRaisesRegex(self, expected_exception, expected_regex, 1304 *args, **kwargs): 1305 """Asserts that the message in a raised exception matches a regex. 1306 1307 Args: 1308 expected_exception: Exception class expected to be raised. 1309 expected_regex: Regex (re.Pattern object or string) expected 1310 to be found in error message. 1311 args: Function to be called and extra positional args. 1312 kwargs: Extra kwargs. 1313 msg: Optional message used in case of failure. Can only be used 1314 when assertRaisesRegex is used as a context manager. 1315 """ 1316 context = _AssertRaisesContext(expected_exception, self, expected_regex) 1317 return context.handle('assertRaisesRegex', args, kwargs)
Asserts that the message in a raised exception matches a regex.
Arguments:
- expected_exception: Exception class expected to be raised.
- expected_regex: Regex (re.Pattern object or string) expected to be found in error message.
- args: Function to be called and extra positional args.
- kwargs: Extra kwargs.
- msg: Optional message used in case of failure. Can only be used when assertRaisesRegex is used as a context manager.
1319 def assertWarnsRegex(self, expected_warning, expected_regex, 1320 *args, **kwargs): 1321 """Asserts that the message in a triggered warning matches a regexp. 1322 Basic functioning is similar to assertWarns() with the addition 1323 that only warnings whose messages also match the regular expression 1324 are considered successful matches. 1325 1326 Args: 1327 expected_warning: Warning class expected to be triggered. 1328 expected_regex: Regex (re.Pattern object or string) expected 1329 to be found in error message. 1330 args: Function to be called and extra positional args. 1331 kwargs: Extra kwargs. 1332 msg: Optional message used in case of failure. Can only be used 1333 when assertWarnsRegex is used as a context manager. 1334 """ 1335 context = _AssertWarnsContext(expected_warning, self, expected_regex) 1336 return context.handle('assertWarnsRegex', args, kwargs)
Asserts that the message in a triggered warning matches a regexp. Basic functioning is similar to assertWarns() with the addition that only warnings whose messages also match the regular expression are considered successful matches.
Arguments:
- expected_warning: Warning class expected to be triggered.
- expected_regex: Regex (re.Pattern object or string) expected to be found in error message.
- args: Function to be called and extra positional args.
- kwargs: Extra kwargs.
- msg: Optional message used in case of failure. Can only be used when assertWarnsRegex is used as a context manager.
1338 def assertRegex(self, text, expected_regex, msg=None): 1339 """Fail the test unless the text matches the regular expression.""" 1340 if isinstance(expected_regex, (str, bytes)): 1341 assert expected_regex, "expected_regex must not be empty." 1342 expected_regex = re.compile(expected_regex) 1343 if not expected_regex.search(text): 1344 standardMsg = "Regex didn't match: %r not found in %r" % ( 1345 expected_regex.pattern, text) 1346 # _formatMessage ensures the longMessage option is respected 1347 msg = self._formatMessage(msg, standardMsg) 1348 raise self.failureException(msg)
Fail the test unless the text matches the regular expression.
1350 def assertNotRegex(self, text, unexpected_regex, msg=None): 1351 """Fail the test if the text matches the regular expression.""" 1352 if isinstance(unexpected_regex, (str, bytes)): 1353 unexpected_regex = re.compile(unexpected_regex) 1354 match = unexpected_regex.search(text) 1355 if match: 1356 standardMsg = 'Regex matched: %r matches %r in %r' % ( 1357 text[match.start() : match.end()], 1358 unexpected_regex.pattern, 1359 text) 1360 # _formatMessage ensures the longMessage option is respected 1361 msg = self._formatMessage(msg, standardMsg) 1362 raise self.failureException(msg)
Fail the test if the text matches the regular expression.
10class IsolatedAsyncioTestCase(TestCase): 11 # Names intentionally have a long prefix 12 # to reduce a chance of clashing with user-defined attributes 13 # from inherited test case 14 # 15 # The class doesn't call loop.run_until_complete(self.setUp()) and family 16 # but uses a different approach: 17 # 1. create a long-running task that reads self.setUp() 18 # awaitable from queue along with a future 19 # 2. await the awaitable object passing in and set the result 20 # into the future object 21 # 3. Outer code puts the awaitable and the future object into a queue 22 # with waiting for the future 23 # The trick is necessary because every run_until_complete() call 24 # creates a new task with embedded ContextVar context. 25 # To share contextvars between setUp(), test and tearDown() we need to execute 26 # them inside the same task. 27 28 # Note: the test case modifies event loop policy if the policy was not instantiated 29 # yet. 30 # asyncio.get_event_loop_policy() creates a default policy on demand but never 31 # returns None 32 # I believe this is not an issue in user level tests but python itself for testing 33 # should reset a policy in every test module 34 # by calling asyncio.set_event_loop_policy(None) in tearDownModule() 35 36 def __init__(self, methodName='runTest'): 37 super().__init__(methodName) 38 self._asyncioRunner = None 39 self._asyncioTestContext = contextvars.copy_context() 40 41 async def asyncSetUp(self): 42 pass 43 44 async def asyncTearDown(self): 45 pass 46 47 def addAsyncCleanup(self, func, /, *args, **kwargs): 48 # A trivial trampoline to addCleanup() 49 # the function exists because it has a different semantics 50 # and signature: 51 # addCleanup() accepts regular functions 52 # but addAsyncCleanup() accepts coroutines 53 # 54 # We intentionally don't add inspect.iscoroutinefunction() check 55 # for func argument because there is no way 56 # to check for async function reliably: 57 # 1. It can be "async def func()" itself 58 # 2. Class can implement "async def __call__()" method 59 # 3. Regular "def func()" that returns awaitable object 60 self.addCleanup(*(func, *args), **kwargs) 61 62 async def enterAsyncContext(self, cm): 63 """Enters the supplied asynchronous context manager. 64 65 If successful, also adds its __aexit__ method as a cleanup 66 function and returns the result of the __aenter__ method. 67 """ 68 # We look up the special methods on the type to match the with 69 # statement. 70 cls = type(cm) 71 try: 72 enter = cls.__aenter__ 73 exit = cls.__aexit__ 74 except AttributeError: 75 raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does " 76 f"not support the asynchronous context manager protocol" 77 ) from None 78 result = await enter(cm) 79 self.addAsyncCleanup(exit, cm, None, None, None) 80 return result 81 82 def _callSetUp(self): 83 # Force loop to be initialized and set as the current loop 84 # so that setUp functions can use get_event_loop() and get the 85 # correct loop instance. 86 self._asyncioRunner.get_loop() 87 self._asyncioTestContext.run(self.setUp) 88 self._callAsync(self.asyncSetUp) 89 90 def _callTestMethod(self, method): 91 if self._callMaybeAsync(method) is not None: 92 warnings.warn(f'It is deprecated to return a value that is not None from a ' 93 f'test case ({method})', DeprecationWarning, stacklevel=4) 94 95 def _callTearDown(self): 96 self._callAsync(self.asyncTearDown) 97 self._asyncioTestContext.run(self.tearDown) 98 99 def _callCleanup(self, function, *args, **kwargs): 100 self._callMaybeAsync(function, *args, **kwargs) 101 102 def _callAsync(self, func, /, *args, **kwargs): 103 assert self._asyncioRunner is not None, 'asyncio runner is not initialized' 104 assert inspect.iscoroutinefunction(func), f'{func!r} is not an async function' 105 return self._asyncioRunner.run( 106 func(*args, **kwargs), 107 context=self._asyncioTestContext 108 ) 109 110 def _callMaybeAsync(self, func, /, *args, **kwargs): 111 assert self._asyncioRunner is not None, 'asyncio runner is not initialized' 112 if inspect.iscoroutinefunction(func): 113 return self._asyncioRunner.run( 114 func(*args, **kwargs), 115 context=self._asyncioTestContext, 116 ) 117 else: 118 return self._asyncioTestContext.run(func, *args, **kwargs) 119 120 def _setupAsyncioRunner(self): 121 assert self._asyncioRunner is None, 'asyncio runner is already initialized' 122 runner = asyncio.Runner(debug=True) 123 self._asyncioRunner = runner 124 125 def _tearDownAsyncioRunner(self): 126 runner = self._asyncioRunner 127 runner.close() 128 129 def run(self, result=None): 130 self._setupAsyncioRunner() 131 try: 132 return super().run(result) 133 finally: 134 self._tearDownAsyncioRunner() 135 136 def debug(self): 137 self._setupAsyncioRunner() 138 super().debug() 139 self._tearDownAsyncioRunner() 140 141 def __del__(self): 142 if self._asyncioRunner is not None: 143 self._tearDownAsyncioRunner()
A class whose instances are single test cases.
By default, the test code itself should be placed in a method named 'runTest'.
If the fixture may be used for many test cases, create as many test methods as are needed. When instantiating such a TestCase subclass, specify in the constructor arguments the name of the test method that the instance is to execute.
Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively.
If it is necessary to override the __init__ method, the base class __init__ method must always be called. It is important that subclasses should not change the signature of their __init__ method, since instances of the classes are instantiated automatically by parts of the framework in order to be run.
When subclassing TestCase, you can set these attributes:
- failureException: determines which exception will be raised when the instance's assertion methods fail; test methods raising this exception will be deemed to have 'failed' rather than 'errored'.
- longMessage: determines whether long messages (including repr of objects used in assert methods) will be printed on failure in addition to any explicit message passed.
- maxDiff: sets the maximum length of a diff in failure messages by assert methods using difflib. It is looked up as an instance attribute so can be configured by individual tests if required.
36 def __init__(self, methodName='runTest'): 37 super().__init__(methodName) 38 self._asyncioRunner = None 39 self._asyncioTestContext = contextvars.copy_context()
Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.
47 def addAsyncCleanup(self, func, /, *args, **kwargs): 48 # A trivial trampoline to addCleanup() 49 # the function exists because it has a different semantics 50 # and signature: 51 # addCleanup() accepts regular functions 52 # but addAsyncCleanup() accepts coroutines 53 # 54 # We intentionally don't add inspect.iscoroutinefunction() check 55 # for func argument because there is no way 56 # to check for async function reliably: 57 # 1. It can be "async def func()" itself 58 # 2. Class can implement "async def __call__()" method 59 # 3. Regular "def func()" that returns awaitable object 60 self.addCleanup(*(func, *args), **kwargs)
62 async def enterAsyncContext(self, cm): 63 """Enters the supplied asynchronous context manager. 64 65 If successful, also adds its __aexit__ method as a cleanup 66 function and returns the result of the __aenter__ method. 67 """ 68 # We look up the special methods on the type to match the with 69 # statement. 70 cls = type(cm) 71 try: 72 enter = cls.__aenter__ 73 exit = cls.__aexit__ 74 except AttributeError: 75 raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does " 76 f"not support the asynchronous context manager protocol" 77 ) from None 78 result = await enter(cm) 79 self.addAsyncCleanup(exit, cm, None, None, None) 80 return result
Enters the supplied asynchronous context manager.
If successful, also adds its __aexit__ method as a cleanup function and returns the result of the __aenter__ method.
136 def debug(self): 137 self._setupAsyncioRunner() 138 super().debug() 139 self._tearDownAsyncioRunner()
Run the test without collecting errors in a TestResult
Inherited Members
- TestCase
- failureException
- longMessage
- maxDiff
- addTypeEqualityFunc
- addCleanup
- enterContext
- addClassCleanup
- enterClassContext
- setUp
- tearDown
- setUpClass
- tearDownClass
- countTestCases
- defaultTestResult
- shortDescription
- id
- subTest
- doCleanups
- doClassCleanups
- skipTest
- fail
- assertFalse
- assertTrue
- assertRaises
- assertWarns
- assertLogs
- assertNoLogs
- assertEqual
- assertNotEqual
- assertAlmostEqual
- assertNotAlmostEqual
- assertSequenceEqual
- assertListEqual
- assertTupleEqual
- assertSetEqual
- assertIn
- assertNotIn
- assertIs
- assertIsNot
- assertDictEqual
- assertCountEqual
- assertMultiLineEqual
- assertLess
- assertLessEqual
- assertGreater
- assertGreaterEqual
- assertIsNone
- assertIsNotNone
- assertIsInstance
- assertNotIsInstance
- assertRaisesRegex
- assertWarnsRegex
- assertRegex
- assertNotRegex
93class TestSuite(BaseTestSuite): 94 """A test suite is a composite test consisting of a number of TestCases. 95 96 For use, create an instance of TestSuite, then add test case instances. 97 When all tests have been added, the suite can be passed to a test 98 runner, such as TextTestRunner. It will run the individual test cases 99 in the order in which they were added, aggregating the results. When 100 subclassing, do not forget to call the base class constructor. 101 """ 102 103 def run(self, result, debug=False): 104 topLevel = False 105 if getattr(result, '_testRunEntered', False) is False: 106 result._testRunEntered = topLevel = True 107 108 for index, test in enumerate(self): 109 if result.shouldStop: 110 break 111 112 if _isnotsuite(test): 113 self._tearDownPreviousClass(test, result) 114 self._handleModuleFixture(test, result) 115 self._handleClassSetUp(test, result) 116 result._previousTestClass = test.__class__ 117 118 if (getattr(test.__class__, '_classSetupFailed', False) or 119 getattr(result, '_moduleSetUpFailed', False)): 120 continue 121 122 if not debug: 123 test(result) 124 else: 125 test.debug() 126 127 if self._cleanup: 128 self._removeTestAtIndex(index) 129 130 if topLevel: 131 self._tearDownPreviousClass(None, result) 132 self._handleModuleTearDown(result) 133 result._testRunEntered = False 134 return result 135 136 def debug(self): 137 """Run the tests without collecting errors in a TestResult""" 138 debug = _DebugResult() 139 self.run(debug, True) 140 141 ################################ 142 143 def _handleClassSetUp(self, test, result): 144 previousClass = getattr(result, '_previousTestClass', None) 145 currentClass = test.__class__ 146 if currentClass == previousClass: 147 return 148 if result._moduleSetUpFailed: 149 return 150 if getattr(currentClass, "__unittest_skip__", False): 151 return 152 153 failed = False 154 try: 155 currentClass._classSetupFailed = False 156 except TypeError: 157 # test may actually be a function 158 # so its class will be a builtin-type 159 pass 160 161 setUpClass = getattr(currentClass, 'setUpClass', None) 162 doClassCleanups = getattr(currentClass, 'doClassCleanups', None) 163 if setUpClass is not None: 164 _call_if_exists(result, '_setupStdout') 165 try: 166 try: 167 setUpClass() 168 except Exception as e: 169 if isinstance(result, _DebugResult): 170 raise 171 failed = True 172 try: 173 currentClass._classSetupFailed = True 174 except TypeError: 175 pass 176 className = util.strclass(currentClass) 177 self._createClassOrModuleLevelException(result, e, 178 'setUpClass', 179 className) 180 if failed and doClassCleanups is not None: 181 doClassCleanups() 182 for exc_info in currentClass.tearDown_exceptions: 183 self._createClassOrModuleLevelException( 184 result, exc_info[1], 'setUpClass', className, 185 info=exc_info) 186 finally: 187 _call_if_exists(result, '_restoreStdout') 188 189 def _get_previous_module(self, result): 190 previousModule = None 191 previousClass = getattr(result, '_previousTestClass', None) 192 if previousClass is not None: 193 previousModule = previousClass.__module__ 194 return previousModule 195 196 197 def _handleModuleFixture(self, test, result): 198 previousModule = self._get_previous_module(result) 199 currentModule = test.__class__.__module__ 200 if currentModule == previousModule: 201 return 202 203 self._handleModuleTearDown(result) 204 205 206 result._moduleSetUpFailed = False 207 try: 208 module = sys.modules[currentModule] 209 except KeyError: 210 return 211 setUpModule = getattr(module, 'setUpModule', None) 212 if setUpModule is not None: 213 _call_if_exists(result, '_setupStdout') 214 try: 215 try: 216 setUpModule() 217 except Exception as e: 218 if isinstance(result, _DebugResult): 219 raise 220 result._moduleSetUpFailed = True 221 self._createClassOrModuleLevelException(result, e, 222 'setUpModule', 223 currentModule) 224 if result._moduleSetUpFailed: 225 try: 226 case.doModuleCleanups() 227 except Exception as e: 228 self._createClassOrModuleLevelException(result, e, 229 'setUpModule', 230 currentModule) 231 finally: 232 _call_if_exists(result, '_restoreStdout') 233 234 def _createClassOrModuleLevelException(self, result, exc, method_name, 235 parent, info=None): 236 errorName = f'{method_name} ({parent})' 237 self._addClassOrModuleLevelException(result, exc, errorName, info) 238 239 def _addClassOrModuleLevelException(self, result, exception, errorName, 240 info=None): 241 error = _ErrorHolder(errorName) 242 addSkip = getattr(result, 'addSkip', None) 243 if addSkip is not None and isinstance(exception, case.SkipTest): 244 addSkip(error, str(exception)) 245 else: 246 if not info: 247 result.addError(error, sys.exc_info()) 248 else: 249 result.addError(error, info) 250 251 def _handleModuleTearDown(self, result): 252 previousModule = self._get_previous_module(result) 253 if previousModule is None: 254 return 255 if result._moduleSetUpFailed: 256 return 257 258 try: 259 module = sys.modules[previousModule] 260 except KeyError: 261 return 262 263 _call_if_exists(result, '_setupStdout') 264 try: 265 tearDownModule = getattr(module, 'tearDownModule', None) 266 if tearDownModule is not None: 267 try: 268 tearDownModule() 269 except Exception as e: 270 if isinstance(result, _DebugResult): 271 raise 272 self._createClassOrModuleLevelException(result, e, 273 'tearDownModule', 274 previousModule) 275 try: 276 case.doModuleCleanups() 277 except Exception as e: 278 if isinstance(result, _DebugResult): 279 raise 280 self._createClassOrModuleLevelException(result, e, 281 'tearDownModule', 282 previousModule) 283 finally: 284 _call_if_exists(result, '_restoreStdout') 285 286 def _tearDownPreviousClass(self, test, result): 287 previousClass = getattr(result, '_previousTestClass', None) 288 currentClass = test.__class__ 289 if currentClass == previousClass or previousClass is None: 290 return 291 if getattr(previousClass, '_classSetupFailed', False): 292 return 293 if getattr(result, '_moduleSetUpFailed', False): 294 return 295 if getattr(previousClass, "__unittest_skip__", False): 296 return 297 298 tearDownClass = getattr(previousClass, 'tearDownClass', None) 299 doClassCleanups = getattr(previousClass, 'doClassCleanups', None) 300 if tearDownClass is None and doClassCleanups is None: 301 return 302 303 _call_if_exists(result, '_setupStdout') 304 try: 305 if tearDownClass is not None: 306 try: 307 tearDownClass() 308 except Exception as e: 309 if isinstance(result, _DebugResult): 310 raise 311 className = util.strclass(previousClass) 312 self._createClassOrModuleLevelException(result, e, 313 'tearDownClass', 314 className) 315 if doClassCleanups is not None: 316 doClassCleanups() 317 for exc_info in previousClass.tearDown_exceptions: 318 if isinstance(result, _DebugResult): 319 raise exc_info[1] 320 className = util.strclass(previousClass) 321 self._createClassOrModuleLevelException(result, exc_info[1], 322 'tearDownClass', 323 className, 324 info=exc_info) 325 finally: 326 _call_if_exists(result, '_restoreStdout')
A test suite is a composite test consisting of a number of TestCases.
For use, create an instance of TestSuite, then add test case instances. When all tests have been added, the suite can be passed to a test runner, such as TextTestRunner. It will run the individual test cases in the order in which they were added, aggregating the results. When subclassing, do not forget to call the base class constructor.
103 def run(self, result, debug=False): 104 topLevel = False 105 if getattr(result, '_testRunEntered', False) is False: 106 result._testRunEntered = topLevel = True 107 108 for index, test in enumerate(self): 109 if result.shouldStop: 110 break 111 112 if _isnotsuite(test): 113 self._tearDownPreviousClass(test, result) 114 self._handleModuleFixture(test, result) 115 self._handleClassSetUp(test, result) 116 result._previousTestClass = test.__class__ 117 118 if (getattr(test.__class__, '_classSetupFailed', False) or 119 getattr(result, '_moduleSetUpFailed', False)): 120 continue 121 122 if not debug: 123 test(result) 124 else: 125 test.debug() 126 127 if self._cleanup: 128 self._removeTestAtIndex(index) 129 130 if topLevel: 131 self._tearDownPreviousClass(None, result) 132 self._handleModuleTearDown(result) 133 result._testRunEntered = False 134 return result
136 def debug(self): 137 """Run the tests without collecting errors in a TestResult""" 138 debug = _DebugResult() 139 self.run(debug, True)
Run the tests without collecting errors in a TestResult
Inherited Members
- unittest.suite.BaseTestSuite
- BaseTestSuite
- countTestCases
- addTest
- addTests
165class TextTestRunner(object): 166 """A test runner class that displays results in textual form. 167 168 It prints out the names of tests as they are run, errors as they 169 occur, and a summary of the results at the end of the test run. 170 """ 171 resultclass = TextTestResult 172 173 def __init__(self, stream=None, descriptions=True, verbosity=1, 174 failfast=False, buffer=False, resultclass=None, warnings=None, 175 *, tb_locals=False, durations=None): 176 """Construct a TextTestRunner. 177 178 Subclasses should accept **kwargs to ensure compatibility as the 179 interface changes. 180 """ 181 if stream is None: 182 stream = sys.stderr 183 self.stream = _WritelnDecorator(stream) 184 self.descriptions = descriptions 185 self.verbosity = verbosity 186 self.failfast = failfast 187 self.buffer = buffer 188 self.tb_locals = tb_locals 189 self.durations = durations 190 self.warnings = warnings 191 if resultclass is not None: 192 self.resultclass = resultclass 193 194 def _makeResult(self): 195 try: 196 return self.resultclass(self.stream, self.descriptions, 197 self.verbosity, durations=self.durations) 198 except TypeError: 199 # didn't accept the durations argument 200 return self.resultclass(self.stream, self.descriptions, 201 self.verbosity) 202 203 def _printDurations(self, result): 204 if not result.collectedDurations: 205 return 206 ls = sorted(result.collectedDurations, key=lambda x: x[1], 207 reverse=True) 208 if self.durations > 0: 209 ls = ls[:self.durations] 210 self.stream.writeln("Slowest test durations") 211 if hasattr(result, 'separator2'): 212 self.stream.writeln(result.separator2) 213 hidden = False 214 for test, elapsed in ls: 215 if self.verbosity < 2 and elapsed < 0.001: 216 hidden = True 217 continue 218 self.stream.writeln("%-10s %s" % ("%.3fs" % elapsed, test)) 219 if hidden: 220 self.stream.writeln("\n(durations < 0.001s were hidden; " 221 "use -v to show these durations)") 222 else: 223 self.stream.writeln("") 224 225 def run(self, test): 226 "Run the given test case or test suite." 227 result = self._makeResult() 228 registerResult(result) 229 result.failfast = self.failfast 230 result.buffer = self.buffer 231 result.tb_locals = self.tb_locals 232 with warnings.catch_warnings(): 233 if self.warnings: 234 # if self.warnings is set, use it to filter all the warnings 235 warnings.simplefilter(self.warnings) 236 startTime = time.perf_counter() 237 startTestRun = getattr(result, 'startTestRun', None) 238 if startTestRun is not None: 239 startTestRun() 240 try: 241 test(result) 242 finally: 243 stopTestRun = getattr(result, 'stopTestRun', None) 244 if stopTestRun is not None: 245 stopTestRun() 246 stopTime = time.perf_counter() 247 timeTaken = stopTime - startTime 248 result.printErrors() 249 if self.durations is not None: 250 self._printDurations(result) 251 252 if hasattr(result, 'separator2'): 253 self.stream.writeln(result.separator2) 254 255 run = result.testsRun 256 self.stream.writeln("Ran %d test%s in %.3fs" % 257 (run, run != 1 and "s" or "", timeTaken)) 258 self.stream.writeln() 259 260 expectedFails = unexpectedSuccesses = skipped = 0 261 try: 262 results = map(len, (result.expectedFailures, 263 result.unexpectedSuccesses, 264 result.skipped)) 265 except AttributeError: 266 pass 267 else: 268 expectedFails, unexpectedSuccesses, skipped = results 269 270 infos = [] 271 if not result.wasSuccessful(): 272 self.stream.write("FAILED") 273 failed, errored = len(result.failures), len(result.errors) 274 if failed: 275 infos.append("failures=%d" % failed) 276 if errored: 277 infos.append("errors=%d" % errored) 278 elif run == 0: 279 self.stream.write("NO TESTS RAN") 280 else: 281 self.stream.write("OK") 282 if skipped: 283 infos.append("skipped=%d" % skipped) 284 if expectedFails: 285 infos.append("expected failures=%d" % expectedFails) 286 if unexpectedSuccesses: 287 infos.append("unexpected successes=%d" % unexpectedSuccesses) 288 if infos: 289 self.stream.writeln(" (%s)" % (", ".join(infos),)) 290 else: 291 self.stream.write("\n") 292 self.stream.flush() 293 return result
A test runner class that displays results in textual form.
It prints out the names of tests as they are run, errors as they occur, and a summary of the results at the end of the test run.
173 def __init__(self, stream=None, descriptions=True, verbosity=1, 174 failfast=False, buffer=False, resultclass=None, warnings=None, 175 *, tb_locals=False, durations=None): 176 """Construct a TextTestRunner. 177 178 Subclasses should accept **kwargs to ensure compatibility as the 179 interface changes. 180 """ 181 if stream is None: 182 stream = sys.stderr 183 self.stream = _WritelnDecorator(stream) 184 self.descriptions = descriptions 185 self.verbosity = verbosity 186 self.failfast = failfast 187 self.buffer = buffer 188 self.tb_locals = tb_locals 189 self.durations = durations 190 self.warnings = warnings 191 if resultclass is not None: 192 self.resultclass = resultclass
Construct a TextTestRunner.
Subclasses should accept **kwargs to ensure compatibility as the interface changes.
225 def run(self, test): 226 "Run the given test case or test suite." 227 result = self._makeResult() 228 registerResult(result) 229 result.failfast = self.failfast 230 result.buffer = self.buffer 231 result.tb_locals = self.tb_locals 232 with warnings.catch_warnings(): 233 if self.warnings: 234 # if self.warnings is set, use it to filter all the warnings 235 warnings.simplefilter(self.warnings) 236 startTime = time.perf_counter() 237 startTestRun = getattr(result, 'startTestRun', None) 238 if startTestRun is not None: 239 startTestRun() 240 try: 241 test(result) 242 finally: 243 stopTestRun = getattr(result, 'stopTestRun', None) 244 if stopTestRun is not None: 245 stopTestRun() 246 stopTime = time.perf_counter() 247 timeTaken = stopTime - startTime 248 result.printErrors() 249 if self.durations is not None: 250 self._printDurations(result) 251 252 if hasattr(result, 'separator2'): 253 self.stream.writeln(result.separator2) 254 255 run = result.testsRun 256 self.stream.writeln("Ran %d test%s in %.3fs" % 257 (run, run != 1 and "s" or "", timeTaken)) 258 self.stream.writeln() 259 260 expectedFails = unexpectedSuccesses = skipped = 0 261 try: 262 results = map(len, (result.expectedFailures, 263 result.unexpectedSuccesses, 264 result.skipped)) 265 except AttributeError: 266 pass 267 else: 268 expectedFails, unexpectedSuccesses, skipped = results 269 270 infos = [] 271 if not result.wasSuccessful(): 272 self.stream.write("FAILED") 273 failed, errored = len(result.failures), len(result.errors) 274 if failed: 275 infos.append("failures=%d" % failed) 276 if errored: 277 infos.append("errors=%d" % errored) 278 elif run == 0: 279 self.stream.write("NO TESTS RAN") 280 else: 281 self.stream.write("OK") 282 if skipped: 283 infos.append("skipped=%d" % skipped) 284 if expectedFails: 285 infos.append("expected failures=%d" % expectedFails) 286 if unexpectedSuccesses: 287 infos.append("unexpected successes=%d" % unexpectedSuccesses) 288 if infos: 289 self.stream.writeln(" (%s)" % (", ".join(infos),)) 290 else: 291 self.stream.write("\n") 292 self.stream.flush() 293 return result
Run the given test case or test suite.
64class TestLoader(object): 65 """ 66 This class is responsible for loading tests according to various criteria 67 and returning them wrapped in a TestSuite 68 """ 69 testMethodPrefix = 'test' 70 sortTestMethodsUsing = staticmethod(util.three_way_cmp) 71 testNamePatterns = None 72 suiteClass = suite.TestSuite 73 _top_level_dir = None 74 75 def __init__(self): 76 super(TestLoader, self).__init__() 77 self.errors = [] 78 # Tracks packages which we have called into via load_tests, to 79 # avoid infinite re-entrancy. 80 self._loading_packages = set() 81 82 def loadTestsFromTestCase(self, testCaseClass): 83 """Return a suite of all test cases contained in testCaseClass""" 84 if issubclass(testCaseClass, suite.TestSuite): 85 raise TypeError("Test cases should not be derived from " 86 "TestSuite. Maybe you meant to derive from " 87 "TestCase?") 88 testCaseNames = self.getTestCaseNames(testCaseClass) 89 if not testCaseNames and hasattr(testCaseClass, 'runTest'): 90 testCaseNames = ['runTest'] 91 loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) 92 return loaded_suite 93 94 def loadTestsFromModule(self, module, *, pattern=None): 95 """Return a suite of all test cases contained in the given module""" 96 tests = [] 97 for name in dir(module): 98 obj = getattr(module, name) 99 if isinstance(obj, type) and issubclass(obj, case.TestCase): 100 tests.append(self.loadTestsFromTestCase(obj)) 101 102 load_tests = getattr(module, 'load_tests', None) 103 tests = self.suiteClass(tests) 104 if load_tests is not None: 105 try: 106 return load_tests(self, tests, pattern) 107 except Exception as e: 108 error_case, error_message = _make_failed_load_tests( 109 module.__name__, e, self.suiteClass) 110 self.errors.append(error_message) 111 return error_case 112 return tests 113 114 def loadTestsFromName(self, name, module=None): 115 """Return a suite of all test cases given a string specifier. 116 117 The name may resolve either to a module, a test case class, a 118 test method within a test case class, or a callable object which 119 returns a TestCase or TestSuite instance. 120 121 The method optionally resolves the names relative to a given module. 122 """ 123 parts = name.split('.') 124 error_case, error_message = None, None 125 if module is None: 126 parts_copy = parts[:] 127 while parts_copy: 128 try: 129 module_name = '.'.join(parts_copy) 130 module = __import__(module_name) 131 break 132 except ImportError: 133 next_attribute = parts_copy.pop() 134 # Last error so we can give it to the user if needed. 135 error_case, error_message = _make_failed_import_test( 136 next_attribute, self.suiteClass) 137 if not parts_copy: 138 # Even the top level import failed: report that error. 139 self.errors.append(error_message) 140 return error_case 141 parts = parts[1:] 142 obj = module 143 for part in parts: 144 try: 145 parent, obj = obj, getattr(obj, part) 146 except AttributeError as e: 147 # We can't traverse some part of the name. 148 if (getattr(obj, '__path__', None) is not None 149 and error_case is not None): 150 # This is a package (no __path__ per importlib docs), and we 151 # encountered an error importing something. We cannot tell 152 # the difference between package.WrongNameTestClass and 153 # package.wrong_module_name so we just report the 154 # ImportError - it is more informative. 155 self.errors.append(error_message) 156 return error_case 157 else: 158 # Otherwise, we signal that an AttributeError has occurred. 159 error_case, error_message = _make_failed_test( 160 part, e, self.suiteClass, 161 'Failed to access attribute:\n%s' % ( 162 traceback.format_exc(),)) 163 self.errors.append(error_message) 164 return error_case 165 166 if isinstance(obj, types.ModuleType): 167 return self.loadTestsFromModule(obj) 168 elif isinstance(obj, type) and issubclass(obj, case.TestCase): 169 return self.loadTestsFromTestCase(obj) 170 elif (isinstance(obj, types.FunctionType) and 171 isinstance(parent, type) and 172 issubclass(parent, case.TestCase)): 173 name = parts[-1] 174 inst = parent(name) 175 # static methods follow a different path 176 if not isinstance(getattr(inst, name), types.FunctionType): 177 return self.suiteClass([inst]) 178 elif isinstance(obj, suite.TestSuite): 179 return obj 180 if callable(obj): 181 test = obj() 182 if isinstance(test, suite.TestSuite): 183 return test 184 elif isinstance(test, case.TestCase): 185 return self.suiteClass([test]) 186 else: 187 raise TypeError("calling %s returned %s, not a test" % 188 (obj, test)) 189 else: 190 raise TypeError("don't know how to make test from: %s" % obj) 191 192 def loadTestsFromNames(self, names, module=None): 193 """Return a suite of all test cases found using the given sequence 194 of string specifiers. See 'loadTestsFromName()'. 195 """ 196 suites = [self.loadTestsFromName(name, module) for name in names] 197 return self.suiteClass(suites) 198 199 def getTestCaseNames(self, testCaseClass): 200 """Return a sorted sequence of method names found within testCaseClass 201 """ 202 def shouldIncludeMethod(attrname): 203 if not attrname.startswith(self.testMethodPrefix): 204 return False 205 testFunc = getattr(testCaseClass, attrname) 206 if not callable(testFunc): 207 return False 208 fullName = f'%s.%s.%s' % ( 209 testCaseClass.__module__, testCaseClass.__qualname__, attrname 210 ) 211 return self.testNamePatterns is None or \ 212 any(fnmatchcase(fullName, pattern) for pattern in self.testNamePatterns) 213 testFnNames = list(filter(shouldIncludeMethod, dir(testCaseClass))) 214 if self.sortTestMethodsUsing: 215 testFnNames.sort(key=functools.cmp_to_key(self.sortTestMethodsUsing)) 216 return testFnNames 217 218 def discover(self, start_dir, pattern='test*.py', top_level_dir=None): 219 """Find and return all test modules from the specified start 220 directory, recursing into subdirectories to find them and return all 221 tests found within them. Only test files that match the pattern will 222 be loaded. (Using shell style pattern matching.) 223 224 All test modules must be importable from the top level of the project. 225 If the start directory is not the top level directory then the top 226 level directory must be specified separately. 227 228 If a test package name (directory with '__init__.py') matches the 229 pattern then the package will be checked for a 'load_tests' function. If 230 this exists then it will be called with (loader, tests, pattern) unless 231 the package has already had load_tests called from the same discovery 232 invocation, in which case the package module object is not scanned for 233 tests - this ensures that when a package uses discover to further 234 discover child tests that infinite recursion does not happen. 235 236 If load_tests exists then discovery does *not* recurse into the package, 237 load_tests is responsible for loading all tests in the package. 238 239 The pattern is deliberately not stored as a loader attribute so that 240 packages can continue discovery themselves. top_level_dir is stored so 241 load_tests does not need to pass this argument in to loader.discover(). 242 243 Paths are sorted before being imported to ensure reproducible execution 244 order even on filesystems with non-alphabetical ordering like ext3/4. 245 """ 246 set_implicit_top = False 247 if top_level_dir is None and self._top_level_dir is not None: 248 # make top_level_dir optional if called from load_tests in a package 249 top_level_dir = self._top_level_dir 250 elif top_level_dir is None: 251 set_implicit_top = True 252 top_level_dir = start_dir 253 254 top_level_dir = os.path.abspath(top_level_dir) 255 256 if not top_level_dir in sys.path: 257 # all test modules must be importable from the top level directory 258 # should we *unconditionally* put the start directory in first 259 # in sys.path to minimise likelihood of conflicts between installed 260 # modules and development versions? 261 sys.path.insert(0, top_level_dir) 262 self._top_level_dir = top_level_dir 263 264 is_not_importable = False 265 if os.path.isdir(os.path.abspath(start_dir)): 266 start_dir = os.path.abspath(start_dir) 267 if start_dir != top_level_dir: 268 is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py')) 269 else: 270 # support for discovery from dotted module names 271 try: 272 __import__(start_dir) 273 except ImportError: 274 is_not_importable = True 275 else: 276 the_module = sys.modules[start_dir] 277 top_part = start_dir.split('.')[0] 278 try: 279 start_dir = os.path.abspath( 280 os.path.dirname((the_module.__file__))) 281 except AttributeError: 282 if the_module.__name__ in sys.builtin_module_names: 283 # builtin module 284 raise TypeError('Can not use builtin modules ' 285 'as dotted module names') from None 286 else: 287 raise TypeError( 288 f"don't know how to discover from {the_module!r}" 289 ) from None 290 291 if set_implicit_top: 292 self._top_level_dir = self._get_directory_containing_module(top_part) 293 sys.path.remove(top_level_dir) 294 295 if is_not_importable: 296 raise ImportError('Start directory is not importable: %r' % start_dir) 297 298 tests = list(self._find_tests(start_dir, pattern)) 299 return self.suiteClass(tests) 300 301 def _get_directory_containing_module(self, module_name): 302 module = sys.modules[module_name] 303 full_path = os.path.abspath(module.__file__) 304 305 if os.path.basename(full_path).lower().startswith('__init__.py'): 306 return os.path.dirname(os.path.dirname(full_path)) 307 else: 308 # here we have been given a module rather than a package - so 309 # all we can do is search the *same* directory the module is in 310 # should an exception be raised instead 311 return os.path.dirname(full_path) 312 313 def _get_name_from_path(self, path): 314 if path == self._top_level_dir: 315 return '.' 316 path = _splitext(os.path.normpath(path)) 317 318 _relpath = os.path.relpath(path, self._top_level_dir) 319 assert not os.path.isabs(_relpath), "Path must be within the project" 320 assert not _relpath.startswith('..'), "Path must be within the project" 321 322 name = _relpath.replace(os.path.sep, '.') 323 return name 324 325 def _get_module_from_name(self, name): 326 __import__(name) 327 return sys.modules[name] 328 329 def _match_path(self, path, full_path, pattern): 330 # override this method to use alternative matching strategy 331 return fnmatch(path, pattern) 332 333 def _find_tests(self, start_dir, pattern): 334 """Used by discovery. Yields test suites it loads.""" 335 # Handle the __init__ in this package 336 name = self._get_name_from_path(start_dir) 337 # name is '.' when start_dir == top_level_dir (and top_level_dir is by 338 # definition not a package). 339 if name != '.' and name not in self._loading_packages: 340 # name is in self._loading_packages while we have called into 341 # loadTestsFromModule with name. 342 tests, should_recurse = self._find_test_path(start_dir, pattern) 343 if tests is not None: 344 yield tests 345 if not should_recurse: 346 # Either an error occurred, or load_tests was used by the 347 # package. 348 return 349 # Handle the contents. 350 paths = sorted(os.listdir(start_dir)) 351 for path in paths: 352 full_path = os.path.join(start_dir, path) 353 tests, should_recurse = self._find_test_path(full_path, pattern) 354 if tests is not None: 355 yield tests 356 if should_recurse: 357 # we found a package that didn't use load_tests. 358 name = self._get_name_from_path(full_path) 359 self._loading_packages.add(name) 360 try: 361 yield from self._find_tests(full_path, pattern) 362 finally: 363 self._loading_packages.discard(name) 364 365 def _find_test_path(self, full_path, pattern): 366 """Used by discovery. 367 368 Loads tests from a single file, or a directories' __init__.py when 369 passed the directory. 370 371 Returns a tuple (None_or_tests_from_file, should_recurse). 372 """ 373 basename = os.path.basename(full_path) 374 if os.path.isfile(full_path): 375 if not VALID_MODULE_NAME.match(basename): 376 # valid Python identifiers only 377 return None, False 378 if not self._match_path(basename, full_path, pattern): 379 return None, False 380 # if the test file matches, load it 381 name = self._get_name_from_path(full_path) 382 try: 383 module = self._get_module_from_name(name) 384 except case.SkipTest as e: 385 return _make_skipped_test(name, e, self.suiteClass), False 386 except: 387 error_case, error_message = \ 388 _make_failed_import_test(name, self.suiteClass) 389 self.errors.append(error_message) 390 return error_case, False 391 else: 392 mod_file = os.path.abspath( 393 getattr(module, '__file__', full_path)) 394 realpath = _splitext( 395 os.path.realpath(mod_file)) 396 fullpath_noext = _splitext( 397 os.path.realpath(full_path)) 398 if realpath.lower() != fullpath_noext.lower(): 399 module_dir = os.path.dirname(realpath) 400 mod_name = _splitext( 401 os.path.basename(full_path)) 402 expected_dir = os.path.dirname(full_path) 403 msg = ("%r module incorrectly imported from %r. Expected " 404 "%r. Is this module globally installed?") 405 raise ImportError( 406 msg % (mod_name, module_dir, expected_dir)) 407 return self.loadTestsFromModule(module, pattern=pattern), False 408 elif os.path.isdir(full_path): 409 if not os.path.isfile(os.path.join(full_path, '__init__.py')): 410 return None, False 411 412 load_tests = None 413 tests = None 414 name = self._get_name_from_path(full_path) 415 try: 416 package = self._get_module_from_name(name) 417 except case.SkipTest as e: 418 return _make_skipped_test(name, e, self.suiteClass), False 419 except: 420 error_case, error_message = \ 421 _make_failed_import_test(name, self.suiteClass) 422 self.errors.append(error_message) 423 return error_case, False 424 else: 425 load_tests = getattr(package, 'load_tests', None) 426 # Mark this package as being in load_tests (possibly ;)) 427 self._loading_packages.add(name) 428 try: 429 tests = self.loadTestsFromModule(package, pattern=pattern) 430 if load_tests is not None: 431 # loadTestsFromModule(package) has loaded tests for us. 432 return tests, False 433 return tests, True 434 finally: 435 self._loading_packages.discard(name) 436 else: 437 return None, False
This class is responsible for loading tests according to various criteria and returning them wrapped in a TestSuite
116def three_way_cmp(x, y): 117 """Return -1 if x < y, 0 if x == y and 1 if x > y""" 118 return (x > y) - (x < y)
Return -1 if x < y, 0 if x == y and 1 if x > y
82 def loadTestsFromTestCase(self, testCaseClass): 83 """Return a suite of all test cases contained in testCaseClass""" 84 if issubclass(testCaseClass, suite.TestSuite): 85 raise TypeError("Test cases should not be derived from " 86 "TestSuite. Maybe you meant to derive from " 87 "TestCase?") 88 testCaseNames = self.getTestCaseNames(testCaseClass) 89 if not testCaseNames and hasattr(testCaseClass, 'runTest'): 90 testCaseNames = ['runTest'] 91 loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) 92 return loaded_suite
Return a suite of all test cases contained in testCaseClass
94 def loadTestsFromModule(self, module, *, pattern=None): 95 """Return a suite of all test cases contained in the given module""" 96 tests = [] 97 for name in dir(module): 98 obj = getattr(module, name) 99 if isinstance(obj, type) and issubclass(obj, case.TestCase): 100 tests.append(self.loadTestsFromTestCase(obj)) 101 102 load_tests = getattr(module, 'load_tests', None) 103 tests = self.suiteClass(tests) 104 if load_tests is not None: 105 try: 106 return load_tests(self, tests, pattern) 107 except Exception as e: 108 error_case, error_message = _make_failed_load_tests( 109 module.__name__, e, self.suiteClass) 110 self.errors.append(error_message) 111 return error_case 112 return tests
Return a suite of all test cases contained in the given module
114 def loadTestsFromName(self, name, module=None): 115 """Return a suite of all test cases given a string specifier. 116 117 The name may resolve either to a module, a test case class, a 118 test method within a test case class, or a callable object which 119 returns a TestCase or TestSuite instance. 120 121 The method optionally resolves the names relative to a given module. 122 """ 123 parts = name.split('.') 124 error_case, error_message = None, None 125 if module is None: 126 parts_copy = parts[:] 127 while parts_copy: 128 try: 129 module_name = '.'.join(parts_copy) 130 module = __import__(module_name) 131 break 132 except ImportError: 133 next_attribute = parts_copy.pop() 134 # Last error so we can give it to the user if needed. 135 error_case, error_message = _make_failed_import_test( 136 next_attribute, self.suiteClass) 137 if not parts_copy: 138 # Even the top level import failed: report that error. 139 self.errors.append(error_message) 140 return error_case 141 parts = parts[1:] 142 obj = module 143 for part in parts: 144 try: 145 parent, obj = obj, getattr(obj, part) 146 except AttributeError as e: 147 # We can't traverse some part of the name. 148 if (getattr(obj, '__path__', None) is not None 149 and error_case is not None): 150 # This is a package (no __path__ per importlib docs), and we 151 # encountered an error importing something. We cannot tell 152 # the difference between package.WrongNameTestClass and 153 # package.wrong_module_name so we just report the 154 # ImportError - it is more informative. 155 self.errors.append(error_message) 156 return error_case 157 else: 158 # Otherwise, we signal that an AttributeError has occurred. 159 error_case, error_message = _make_failed_test( 160 part, e, self.suiteClass, 161 'Failed to access attribute:\n%s' % ( 162 traceback.format_exc(),)) 163 self.errors.append(error_message) 164 return error_case 165 166 if isinstance(obj, types.ModuleType): 167 return self.loadTestsFromModule(obj) 168 elif isinstance(obj, type) and issubclass(obj, case.TestCase): 169 return self.loadTestsFromTestCase(obj) 170 elif (isinstance(obj, types.FunctionType) and 171 isinstance(parent, type) and 172 issubclass(parent, case.TestCase)): 173 name = parts[-1] 174 inst = parent(name) 175 # static methods follow a different path 176 if not isinstance(getattr(inst, name), types.FunctionType): 177 return self.suiteClass([inst]) 178 elif isinstance(obj, suite.TestSuite): 179 return obj 180 if callable(obj): 181 test = obj() 182 if isinstance(test, suite.TestSuite): 183 return test 184 elif isinstance(test, case.TestCase): 185 return self.suiteClass([test]) 186 else: 187 raise TypeError("calling %s returned %s, not a test" % 188 (obj, test)) 189 else: 190 raise TypeError("don't know how to make test from: %s" % obj)
Return a suite of all test cases given a string specifier.
The name may resolve either to a module, a test case class, a test method within a test case class, or a callable object which returns a TestCase or TestSuite instance.
The method optionally resolves the names relative to a given module.
192 def loadTestsFromNames(self, names, module=None): 193 """Return a suite of all test cases found using the given sequence 194 of string specifiers. See 'loadTestsFromName()'. 195 """ 196 suites = [self.loadTestsFromName(name, module) for name in names] 197 return self.suiteClass(suites)
Return a suite of all test cases found using the given sequence of string specifiers. See 'loadTestsFromName()'.
199 def getTestCaseNames(self, testCaseClass): 200 """Return a sorted sequence of method names found within testCaseClass 201 """ 202 def shouldIncludeMethod(attrname): 203 if not attrname.startswith(self.testMethodPrefix): 204 return False 205 testFunc = getattr(testCaseClass, attrname) 206 if not callable(testFunc): 207 return False 208 fullName = f'%s.%s.%s' % ( 209 testCaseClass.__module__, testCaseClass.__qualname__, attrname 210 ) 211 return self.testNamePatterns is None or \ 212 any(fnmatchcase(fullName, pattern) for pattern in self.testNamePatterns) 213 testFnNames = list(filter(shouldIncludeMethod, dir(testCaseClass))) 214 if self.sortTestMethodsUsing: 215 testFnNames.sort(key=functools.cmp_to_key(self.sortTestMethodsUsing)) 216 return testFnNames
Return a sorted sequence of method names found within testCaseClass
218 def discover(self, start_dir, pattern='test*.py', top_level_dir=None): 219 """Find and return all test modules from the specified start 220 directory, recursing into subdirectories to find them and return all 221 tests found within them. Only test files that match the pattern will 222 be loaded. (Using shell style pattern matching.) 223 224 All test modules must be importable from the top level of the project. 225 If the start directory is not the top level directory then the top 226 level directory must be specified separately. 227 228 If a test package name (directory with '__init__.py') matches the 229 pattern then the package will be checked for a 'load_tests' function. If 230 this exists then it will be called with (loader, tests, pattern) unless 231 the package has already had load_tests called from the same discovery 232 invocation, in which case the package module object is not scanned for 233 tests - this ensures that when a package uses discover to further 234 discover child tests that infinite recursion does not happen. 235 236 If load_tests exists then discovery does *not* recurse into the package, 237 load_tests is responsible for loading all tests in the package. 238 239 The pattern is deliberately not stored as a loader attribute so that 240 packages can continue discovery themselves. top_level_dir is stored so 241 load_tests does not need to pass this argument in to loader.discover(). 242 243 Paths are sorted before being imported to ensure reproducible execution 244 order even on filesystems with non-alphabetical ordering like ext3/4. 245 """ 246 set_implicit_top = False 247 if top_level_dir is None and self._top_level_dir is not None: 248 # make top_level_dir optional if called from load_tests in a package 249 top_level_dir = self._top_level_dir 250 elif top_level_dir is None: 251 set_implicit_top = True 252 top_level_dir = start_dir 253 254 top_level_dir = os.path.abspath(top_level_dir) 255 256 if not top_level_dir in sys.path: 257 # all test modules must be importable from the top level directory 258 # should we *unconditionally* put the start directory in first 259 # in sys.path to minimise likelihood of conflicts between installed 260 # modules and development versions? 261 sys.path.insert(0, top_level_dir) 262 self._top_level_dir = top_level_dir 263 264 is_not_importable = False 265 if os.path.isdir(os.path.abspath(start_dir)): 266 start_dir = os.path.abspath(start_dir) 267 if start_dir != top_level_dir: 268 is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py')) 269 else: 270 # support for discovery from dotted module names 271 try: 272 __import__(start_dir) 273 except ImportError: 274 is_not_importable = True 275 else: 276 the_module = sys.modules[start_dir] 277 top_part = start_dir.split('.')[0] 278 try: 279 start_dir = os.path.abspath( 280 os.path.dirname((the_module.__file__))) 281 except AttributeError: 282 if the_module.__name__ in sys.builtin_module_names: 283 # builtin module 284 raise TypeError('Can not use builtin modules ' 285 'as dotted module names') from None 286 else: 287 raise TypeError( 288 f"don't know how to discover from {the_module!r}" 289 ) from None 290 291 if set_implicit_top: 292 self._top_level_dir = self._get_directory_containing_module(top_part) 293 sys.path.remove(top_level_dir) 294 295 if is_not_importable: 296 raise ImportError('Start directory is not importable: %r' % start_dir) 297 298 tests = list(self._find_tests(start_dir, pattern)) 299 return self.suiteClass(tests)
Find and return all test modules from the specified start directory, recursing into subdirectories to find them and return all tests found within them. Only test files that match the pattern will be loaded. (Using shell style pattern matching.)
All test modules must be importable from the top level of the project. If the start directory is not the top level directory then the top level directory must be specified separately.
If a test package name (directory with '__init__.py') matches the pattern then the package will be checked for a 'load_tests' function. If this exists then it will be called with (loader, tests, pattern) unless the package has already had load_tests called from the same discovery invocation, in which case the package module object is not scanned for tests - this ensures that when a package uses discover to further discover child tests that infinite recursion does not happen.
If load_tests exists then discovery does not recurse into the package, load_tests is responsible for loading all tests in the package.
The pattern is deliberately not stored as a loader attribute so that packages can continue discovery themselves. top_level_dir is stored so load_tests does not need to pass this argument in to loader.discover().
Paths are sorted before being imported to ensure reproducible execution order even on filesystems with non-alphabetical ordering like ext3/4.
1366class FunctionTestCase(TestCase): 1367 """A test case that wraps a test function. 1368 1369 This is useful for slipping pre-existing test functions into the 1370 unittest framework. Optionally, set-up and tidy-up functions can be 1371 supplied. As with TestCase, the tidy-up ('tearDown') function will 1372 always be called if the set-up ('setUp') function ran successfully. 1373 """ 1374 1375 def __init__(self, testFunc, setUp=None, tearDown=None, description=None): 1376 super(FunctionTestCase, self).__init__() 1377 self._setUpFunc = setUp 1378 self._tearDownFunc = tearDown 1379 self._testFunc = testFunc 1380 self._description = description 1381 1382 def setUp(self): 1383 if self._setUpFunc is not None: 1384 self._setUpFunc() 1385 1386 def tearDown(self): 1387 if self._tearDownFunc is not None: 1388 self._tearDownFunc() 1389 1390 def runTest(self): 1391 self._testFunc() 1392 1393 def id(self): 1394 return self._testFunc.__name__ 1395 1396 def __eq__(self, other): 1397 if not isinstance(other, self.__class__): 1398 return NotImplemented 1399 1400 return self._setUpFunc == other._setUpFunc and \ 1401 self._tearDownFunc == other._tearDownFunc and \ 1402 self._testFunc == other._testFunc and \ 1403 self._description == other._description 1404 1405 def __hash__(self): 1406 return hash((type(self), self._setUpFunc, self._tearDownFunc, 1407 self._testFunc, self._description)) 1408 1409 def __str__(self): 1410 return "%s (%s)" % (strclass(self.__class__), 1411 self._testFunc.__name__) 1412 1413 def __repr__(self): 1414 return "<%s tec=%s>" % (strclass(self.__class__), 1415 self._testFunc) 1416 1417 def shortDescription(self): 1418 if self._description is not None: 1419 return self._description 1420 doc = self._testFunc.__doc__ 1421 return doc and doc.split("\n")[0].strip() or None
A test case that wraps a test function.
This is useful for slipping pre-existing test functions into the unittest framework. Optionally, set-up and tidy-up functions can be supplied. As with TestCase, the tidy-up ('tearDown') function will always be called if the set-up ('setUp') function ran successfully.
1375 def __init__(self, testFunc, setUp=None, tearDown=None, description=None): 1376 super(FunctionTestCase, self).__init__() 1377 self._setUpFunc = setUp 1378 self._tearDownFunc = tearDown 1379 self._testFunc = testFunc 1380 self._description = description
Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.
1417 def shortDescription(self): 1418 if self._description is not None: 1419 return self._description 1420 doc = self._testFunc.__doc__ 1421 return doc and doc.split("\n")[0].strip() or None
Returns a one-line description of the test, or None if no description has been provided.
The default implementation of this method returns the first line of the specified test method's docstring.
Inherited Members
- TestCase
- failureException
- longMessage
- maxDiff
- addTypeEqualityFunc
- addCleanup
- enterContext
- addClassCleanup
- enterClassContext
- setUpClass
- tearDownClass
- countTestCases
- defaultTestResult
- subTest
- run
- doCleanups
- doClassCleanups
- debug
- skipTest
- fail
- assertFalse
- assertTrue
- assertRaises
- assertWarns
- assertLogs
- assertNoLogs
- assertEqual
- assertNotEqual
- assertAlmostEqual
- assertNotAlmostEqual
- assertSequenceEqual
- assertListEqual
- assertTupleEqual
- assertSetEqual
- assertIn
- assertNotIn
- assertIs
- assertIsNot
- assertDictEqual
- assertCountEqual
- assertMultiLineEqual
- assertLess
- assertLessEqual
- assertGreater
- assertGreaterEqual
- assertIsNone
- assertIsNotNone
- assertIsInstance
- assertNotIsInstance
- assertRaisesRegex
- assertWarnsRegex
- assertRegex
- assertNotRegex
27class SkipTest(Exception): 28 """ 29 Raise this exception in a test to skip it. 30 31 Usually you can use TestCase.skipTest() or one of the skipping decorators 32 instead of raising this directly. 33 """
Raise this exception in a test to skip it.
Usually you can use TestCase.skipTest() or one of the skipping decorators instead of raising this directly.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
- add_note
- args
149def skip(reason): 150 """ 151 Unconditionally skip a test. 152 """ 153 def decorator(test_item): 154 if not isinstance(test_item, type): 155 @functools.wraps(test_item) 156 def skip_wrapper(*args, **kwargs): 157 raise SkipTest(reason) 158 test_item = skip_wrapper 159 160 test_item.__unittest_skip__ = True 161 test_item.__unittest_skip_why__ = reason 162 return test_item 163 if isinstance(reason, types.FunctionType): 164 test_item = reason 165 reason = '' 166 return decorator(test_item) 167 return decorator
Unconditionally skip a test.
169def skipIf(condition, reason): 170 """ 171 Skip a test if the condition is true. 172 """ 173 if condition: 174 return skip(reason) 175 return _id
Skip a test if the condition is true.
177def skipUnless(condition, reason): 178 """ 179 Skip a test unless the condition is true. 180 """ 181 if not condition: 182 return skip(reason) 183 return _id
Skip a test unless the condition is true.
31class TextTestResult(result.TestResult): 32 """A test result class that can print formatted text results to a stream. 33 34 Used by TextTestRunner. 35 """ 36 separator1 = '=' * 70 37 separator2 = '-' * 70 38 39 def __init__(self, stream, descriptions, verbosity, *, durations=None): 40 """Construct a TextTestResult. Subclasses should accept **kwargs 41 to ensure compatibility as the interface changes.""" 42 super(TextTestResult, self).__init__(stream, descriptions, verbosity) 43 self.stream = stream 44 self.showAll = verbosity > 1 45 self.dots = verbosity == 1 46 self.descriptions = descriptions 47 self._newline = True 48 self.durations = durations 49 50 def getDescription(self, test): 51 doc_first_line = test.shortDescription() 52 if self.descriptions and doc_first_line: 53 return '\n'.join((str(test), doc_first_line)) 54 else: 55 return str(test) 56 57 def startTest(self, test): 58 super(TextTestResult, self).startTest(test) 59 if self.showAll: 60 self.stream.write(self.getDescription(test)) 61 self.stream.write(" ... ") 62 self.stream.flush() 63 self._newline = False 64 65 def _write_status(self, test, status): 66 is_subtest = isinstance(test, _SubTest) 67 if is_subtest or self._newline: 68 if not self._newline: 69 self.stream.writeln() 70 if is_subtest: 71 self.stream.write(" ") 72 self.stream.write(self.getDescription(test)) 73 self.stream.write(" ... ") 74 self.stream.writeln(status) 75 self.stream.flush() 76 self._newline = True 77 78 def addSubTest(self, test, subtest, err): 79 if err is not None: 80 if self.showAll: 81 if issubclass(err[0], subtest.failureException): 82 self._write_status(subtest, "FAIL") 83 else: 84 self._write_status(subtest, "ERROR") 85 elif self.dots: 86 if issubclass(err[0], subtest.failureException): 87 self.stream.write('F') 88 else: 89 self.stream.write('E') 90 self.stream.flush() 91 super(TextTestResult, self).addSubTest(test, subtest, err) 92 93 def addSuccess(self, test): 94 super(TextTestResult, self).addSuccess(test) 95 if self.showAll: 96 self._write_status(test, "ok") 97 elif self.dots: 98 self.stream.write('.') 99 self.stream.flush() 100 101 def addError(self, test, err): 102 super(TextTestResult, self).addError(test, err) 103 if self.showAll: 104 self._write_status(test, "ERROR") 105 elif self.dots: 106 self.stream.write('E') 107 self.stream.flush() 108 109 def addFailure(self, test, err): 110 super(TextTestResult, self).addFailure(test, err) 111 if self.showAll: 112 self._write_status(test, "FAIL") 113 elif self.dots: 114 self.stream.write('F') 115 self.stream.flush() 116 117 def addSkip(self, test, reason): 118 super(TextTestResult, self).addSkip(test, reason) 119 if self.showAll: 120 self._write_status(test, "skipped {0!r}".format(reason)) 121 elif self.dots: 122 self.stream.write("s") 123 self.stream.flush() 124 125 def addExpectedFailure(self, test, err): 126 super(TextTestResult, self).addExpectedFailure(test, err) 127 if self.showAll: 128 self.stream.writeln("expected failure") 129 self.stream.flush() 130 elif self.dots: 131 self.stream.write("x") 132 self.stream.flush() 133 134 def addUnexpectedSuccess(self, test): 135 super(TextTestResult, self).addUnexpectedSuccess(test) 136 if self.showAll: 137 self.stream.writeln("unexpected success") 138 self.stream.flush() 139 elif self.dots: 140 self.stream.write("u") 141 self.stream.flush() 142 143 def printErrors(self): 144 if self.dots or self.showAll: 145 self.stream.writeln() 146 self.stream.flush() 147 self.printErrorList('ERROR', self.errors) 148 self.printErrorList('FAIL', self.failures) 149 unexpectedSuccesses = getattr(self, 'unexpectedSuccesses', ()) 150 if unexpectedSuccesses: 151 self.stream.writeln(self.separator1) 152 for test in unexpectedSuccesses: 153 self.stream.writeln(f"UNEXPECTED SUCCESS: {self.getDescription(test)}") 154 self.stream.flush() 155 156 def printErrorList(self, flavour, errors): 157 for test, err in errors: 158 self.stream.writeln(self.separator1) 159 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) 160 self.stream.writeln(self.separator2) 161 self.stream.writeln("%s" % err) 162 self.stream.flush()
A test result class that can print formatted text results to a stream.
Used by TextTestRunner.
39 def __init__(self, stream, descriptions, verbosity, *, durations=None): 40 """Construct a TextTestResult. Subclasses should accept **kwargs 41 to ensure compatibility as the interface changes.""" 42 super(TextTestResult, self).__init__(stream, descriptions, verbosity) 43 self.stream = stream 44 self.showAll = verbosity > 1 45 self.dots = verbosity == 1 46 self.descriptions = descriptions 47 self._newline = True 48 self.durations = durations
Construct a TextTestResult. Subclasses should accept **kwargs to ensure compatibility as the interface changes.
57 def startTest(self, test): 58 super(TextTestResult, self).startTest(test) 59 if self.showAll: 60 self.stream.write(self.getDescription(test)) 61 self.stream.write(" ... ") 62 self.stream.flush() 63 self._newline = False
Called when the given test is about to be run
78 def addSubTest(self, test, subtest, err): 79 if err is not None: 80 if self.showAll: 81 if issubclass(err[0], subtest.failureException): 82 self._write_status(subtest, "FAIL") 83 else: 84 self._write_status(subtest, "ERROR") 85 elif self.dots: 86 if issubclass(err[0], subtest.failureException): 87 self.stream.write('F') 88 else: 89 self.stream.write('E') 90 self.stream.flush() 91 super(TextTestResult, self).addSubTest(test, subtest, err)
Called at the end of a subtest. 'err' is None if the subtest ended successfully, otherwise it's a tuple of values as returned by sys.exc_info().
93 def addSuccess(self, test): 94 super(TextTestResult, self).addSuccess(test) 95 if self.showAll: 96 self._write_status(test, "ok") 97 elif self.dots: 98 self.stream.write('.') 99 self.stream.flush()
Called when a test has completed successfully
101 def addError(self, test, err): 102 super(TextTestResult, self).addError(test, err) 103 if self.showAll: 104 self._write_status(test, "ERROR") 105 elif self.dots: 106 self.stream.write('E') 107 self.stream.flush()
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
109 def addFailure(self, test, err): 110 super(TextTestResult, self).addFailure(test, err) 111 if self.showAll: 112 self._write_status(test, "FAIL") 113 elif self.dots: 114 self.stream.write('F') 115 self.stream.flush()
Called when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().
117 def addSkip(self, test, reason): 118 super(TextTestResult, self).addSkip(test, reason) 119 if self.showAll: 120 self._write_status(test, "skipped {0!r}".format(reason)) 121 elif self.dots: 122 self.stream.write("s") 123 self.stream.flush()
Called when a test is skipped.
125 def addExpectedFailure(self, test, err): 126 super(TextTestResult, self).addExpectedFailure(test, err) 127 if self.showAll: 128 self.stream.writeln("expected failure") 129 self.stream.flush() 130 elif self.dots: 131 self.stream.write("x") 132 self.stream.flush()
Called when an expected failure/error occurred.
134 def addUnexpectedSuccess(self, test): 135 super(TextTestResult, self).addUnexpectedSuccess(test) 136 if self.showAll: 137 self.stream.writeln("unexpected success") 138 self.stream.flush() 139 elif self.dots: 140 self.stream.write("u") 141 self.stream.flush()
Called when a test was expected to fail, but succeed.
143 def printErrors(self): 144 if self.dots or self.showAll: 145 self.stream.writeln() 146 self.stream.flush() 147 self.printErrorList('ERROR', self.errors) 148 self.printErrorList('FAIL', self.failures) 149 unexpectedSuccesses = getattr(self, 'unexpectedSuccesses', ()) 150 if unexpectedSuccesses: 151 self.stream.writeln(self.separator1) 152 for test in unexpectedSuccesses: 153 self.stream.writeln(f"UNEXPECTED SUCCESS: {self.getDescription(test)}") 154 self.stream.flush()
Called by TestRunner after test run
58def removeHandler(method=None): 59 if method is not None: 60 @wraps(method) 61 def inner(*args, **kwargs): 62 initial = signal.getsignal(signal.SIGINT) 63 removeHandler() 64 try: 65 return method(*args, **kwargs) 66 finally: 67 signal.signal(signal.SIGINT, initial) 68 return inner 69 70 global _interrupt_handler 71 if _interrupt_handler is not None: 72 signal.signal(signal.SIGINT, _interrupt_handler.original_handler)
123def addModuleCleanup(function, /, *args, **kwargs): 124 """Same as addCleanup, except the cleanup items are called even if 125 setUpModule fails (unlike tearDownModule).""" 126 _module_cleanups.append((function, args, kwargs))
Same as addCleanup, except the cleanup items are called even if setUpModule fails (unlike tearDownModule).
133def doModuleCleanups(): 134 """Execute all module cleanup functions. Normally called for you after 135 tearDownModule.""" 136 exceptions = [] 137 while _module_cleanups: 138 function, args, kwargs = _module_cleanups.pop() 139 try: 140 function(*args, **kwargs) 141 except Exception as exc: 142 exceptions.append(exc) 143 if exceptions: 144 # Swallows all but first exception. If a multi-exception handler 145 # gets written we should use that here instead. 146 raise exceptions[0]
Execute all module cleanup functions. Normally called for you after tearDownModule.
128def enterModuleContext(cm): 129 """Same as enterContext, but module-wide.""" 130 return _enter_context(cm, addModuleCleanup)
Same as enterContext, but module-wide.
455def getTestCaseNames(testCaseClass, prefix, sortUsing=util.three_way_cmp, testNamePatterns=None): 456 import warnings 457 warnings.warn( 458 "unittest.getTestCaseNames() is deprecated and will be removed in Python 3.13. " 459 "Please use unittest.TestLoader.getTestCaseNames() instead.", 460 DeprecationWarning, stacklevel=2 461 ) 462 return _makeLoader(prefix, sortUsing, testNamePatterns=testNamePatterns).getTestCaseNames(testCaseClass)
464def makeSuite(testCaseClass, prefix='test', sortUsing=util.three_way_cmp, 465 suiteClass=suite.TestSuite): 466 import warnings 467 warnings.warn( 468 "unittest.makeSuite() is deprecated and will be removed in Python 3.13. " 469 "Please use unittest.TestLoader.loadTestsFromTestCase() instead.", 470 DeprecationWarning, stacklevel=2 471 ) 472 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase( 473 testCaseClass)
475def findTestCases(module, prefix='test', sortUsing=util.three_way_cmp, 476 suiteClass=suite.TestSuite): 477 import warnings 478 warnings.warn( 479 "unittest.findTestCases() is deprecated and will be removed in Python 3.13. " 480 "Please use unittest.TestLoader.loadTestsFromModule() instead.", 481 DeprecationWarning, stacklevel=2 482 ) 483 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(\ 484 module)