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