Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(40691)

Delta Between Two Patch Sets: Lib/unittest/case.py

Issue 15836: unittest assertRaises should verify excClass is actually a BaseException class
Left Patch Set: Created 7 years ago
Right Patch Set: Created 4 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_importlib/builtin/test_loader.py ('k') | Lib/unittest/test/test_case.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 """Test case implementation""" 1 """Test case implementation"""
2 2
3 import sys 3 import sys
4 import functools 4 import functools
5 import difflib 5 import difflib
6 import logging
6 import pprint 7 import pprint
7 import re 8 import re
8 import warnings 9 import warnings
9 import collections 10 import collections
11 import contextlib
12 import traceback
10 13
11 from . import result 14 from . import result
12 from .util import (strclass, safe_repr, _count_diff_all_purpose, 15 from .util import (strclass, safe_repr, _count_diff_all_purpose,
13 _count_diff_hashable) 16 _count_diff_hashable, _common_shorten_repr)
14 17
15 __unittest = True 18 __unittest = True
16 19
17 20
18 DIFF_OMITTED = ('\nDiff is %s characters long. ' 21 DIFF_OMITTED = ('\nDiff is %s characters long. '
19 'Set self.maxDiff to None to see it.') 22 'Set self.maxDiff to None to see it.')
20 23
21 class SkipTest(Exception): 24 class SkipTest(Exception):
22 """ 25 """
23 Raise this exception in a test to skip it. 26 Raise this exception in a test to skip it.
24 27
25 Usually you can use TestResult.skip() or one of the skipping decorators 28 Usually you can use TestCase.skipTest() or one of the skipping decorators
26 instead of raising this directly. 29 instead of raising this directly.
27 """ 30 """
28 31
29 class _ExpectedFailure(Exception): 32 class _ShouldStop(Exception):
30 """ 33 """
31 Raise this when a test is expected to fail. 34 The test should stop.
32 35 """
33 This is an implementation detail.
34 """
35
36 def __init__(self, exc_info):
37 super(_ExpectedFailure, self).__init__()
38 self.exc_info = exc_info
39 36
40 class _UnexpectedSuccess(Exception): 37 class _UnexpectedSuccess(Exception):
41 """ 38 """
42 The test was supposed to fail, but it didn't! 39 The test was supposed to fail, but it didn't!
43 """ 40 """
44 41
45 42
46 class _Outcome(object): 43 class _Outcome(object):
47 def __init__(self): 44 def __init__(self, result=None):
45 self.expecting_failure = False
46 self.result = result
47 self.result_supports_subtests = hasattr(result, "addSubTest")
48 self.success = True 48 self.success = True
49 self.skipped = None 49 self.skipped = []
50 self.unexpectedSuccess = None
51 self.expectedFailure = None 50 self.expectedFailure = None
52 self.errors = [] 51 self.errors = []
53 self.failures = [] 52
53 @contextlib.contextmanager
54 def testPartExecutor(self, test_case, isTest=False):
55 old_success = self.success
56 self.success = True
57 try:
58 yield
59 except KeyboardInterrupt:
60 raise
61 except SkipTest as e:
62 self.success = False
63 self.skipped.append((test_case, str(e)))
64 except _ShouldStop:
65 pass
66 except:
67 exc_info = sys.exc_info()
68 if self.expecting_failure:
69 self.expectedFailure = exc_info
70 else:
71 self.success = False
72 self.errors.append((test_case, exc_info))
73 # explicitly break a reference cycle:
74 # exc_info -> frame -> exc_info
75 exc_info = None
76 else:
77 if self.result_supports_subtests and self.success:
78 self.errors.append((test_case, None))
79 finally:
80 self.success = self.success and old_success
54 81
55 82
56 def _id(obj): 83 def _id(obj):
57 return obj 84 return obj
58 85
59 def skip(reason): 86 def skip(reason):
60 """ 87 """
61 Unconditionally skip a test. 88 Unconditionally skip a test.
62 """ 89 """
63 def decorator(test_item): 90 def decorator(test_item):
(...skipping 17 matching lines...) Expand all
81 return _id 108 return _id
82 109
83 def skipUnless(condition, reason): 110 def skipUnless(condition, reason):
84 """ 111 """
85 Skip a test unless the condition is true. 112 Skip a test unless the condition is true.
86 """ 113 """
87 if not condition: 114 if not condition:
88 return skip(reason) 115 return skip(reason)
89 return _id 116 return _id
90 117
91 118 def expectedFailure(test_item):
92 def expectedFailure(func): 119 test_item.__unittest_expecting_failure__ = True
93 @functools.wraps(func) 120 return test_item
94 def wrapper(*args, **kwargs): 121
95 try: 122 def _is_subtype(expected, basetype):
96 func(*args, **kwargs) 123 if isinstance(expected, tuple):
97 except Exception: 124 return all(_is_subtype(e, basetype) for e in expected)
98 raise _ExpectedFailure(sys.exc_info()) 125 return isinstance(expected, type) and issubclass(expected, basetype)
99 raise _UnexpectedSuccess 126
100 return wrapper 127 class _BaseTestCaseContext:
101 128
102 129 def __init__(self, test_case):
103 class _AssertRaisesBaseContext(object):
104
105 def __init__(self, expected, test_case, callable_obj=None,
106 expected_regex=None):
107 self.expected = expected
108 self.test_case = test_case 130 self.test_case = test_case
109 if callable_obj is not None:
110 try:
111 self.obj_name = callable_obj.__name__
112 except AttributeError:
113 self.obj_name = str(callable_obj)
114 else:
115 self.obj_name = None
116 if isinstance(expected_regex, (bytes, str)):
117 expected_regex = re.compile(expected_regex)
118 self.expected_regex = expected_regex
119 self.msg = None
120 131
121 def _raiseFailure(self, standardMsg): 132 def _raiseFailure(self, standardMsg):
122 msg = self.test_case._formatMessage(self.msg, standardMsg) 133 msg = self.test_case._formatMessage(self.msg, standardMsg)
123 raise self.test_case.failureException(msg) 134 raise self.test_case.failureException(msg)
124 135
125 def handle(self, name, callable_obj, args, kwargs): 136 class _AssertRaisesBaseContext(_BaseTestCaseContext):
126 """ 137
127 If callable_obj is None, assertRaises/Warns is being used as a 138 def __init__(self, expected, test_case, expected_regex=None):
139 _BaseTestCaseContext.__init__(self, test_case)
140 self.expected = expected
141 self.test_case = test_case
142 if expected_regex is not None:
143 expected_regex = re.compile(expected_regex)
144 self.expected_regex = expected_regex
145 self.obj_name = None
146 self.msg = None
147
148 def handle(self, name, args, kwargs):
149 """
150 If args is empty, assertRaises/Warns is being used as a
128 context manager, so check for a 'msg' kwarg and return self. 151 context manager, so check for a 'msg' kwarg and return self.
129 If callable_obj is not None, call it passing args and kwargs. 152 If args is not empty, call a callable passing positional and keyword
130 """ 153 arguments.
131 if callable_obj is None: 154 """
155 if not _is_subtype(self.expected, self._base_type):
Martin Panter 2015/05/19 12:37:58 Why is this check moved from __init__() to handle(
storchaka 2015/05/19 12:47:33 Only because the name parameter is passed to handl
Martin Panter 2015/05/19 13:27:57 Fair enough, that makes sense
156 raise TypeError('%s() arg 1 must be %s' %
157 (name, self._base_type_str))
158 if args and args[0] is None:
159 warnings.warn("callable is None",
160 DeprecationWarning, 3)
161 args = ()
162 if not args:
132 self.msg = kwargs.pop('msg', None) 163 self.msg = kwargs.pop('msg', None)
164 if kwargs:
165 warnings.warn('%r is an invalid keyword argument for '
166 'this function' % next(iter(kwargs)),
167 DeprecationWarning, 3)
133 return self 168 return self
169
170 callable_obj, *args = args
171 try:
172 self.obj_name = callable_obj.__name__
173 except AttributeError:
174 self.obj_name = str(callable_obj)
134 with self: 175 with self:
135 callable_obj(*args, **kwargs) 176 callable_obj(*args, **kwargs)
136 177
137 178
138
139 class _AssertRaisesContext(_AssertRaisesBaseContext): 179 class _AssertRaisesContext(_AssertRaisesBaseContext):
140 """A context manager used to implement TestCase.assertRaises* methods.""" 180 """A context manager used to implement TestCase.assertRaises* methods."""
181
182 _base_type = BaseException
183 _base_type_str = 'an exception type or tuple of exception types'
141 184
142 def __enter__(self): 185 def __enter__(self):
143 return self 186 return self
144 187
145 def __exit__(self, exc_type, exc_value, tb): 188 def __exit__(self, exc_type, exc_value, tb):
146 if exc_type is None: 189 if exc_type is None:
147 try: 190 try:
148 exc_name = self.expected.__name__ 191 exc_name = self.expected.__name__
149 except AttributeError: 192 except AttributeError:
150 exc_name = str(self.expected) 193 exc_name = str(self.expected)
151 if self.obj_name: 194 if self.obj_name:
152 self._raiseFailure("{} not raised by {}".format(exc_name, 195 self._raiseFailure("{} not raised by {}".format(exc_name,
153 self.obj_name)) 196 self.obj_name))
154 else: 197 else:
155 self._raiseFailure("{} not raised".format(exc_name)) 198 self._raiseFailure("{} not raised".format(exc_name))
199 else:
200 traceback.clear_frames(tb)
156 if not issubclass(exc_type, self.expected): 201 if not issubclass(exc_type, self.expected):
157 # let unexpected exceptions pass through 202 # let unexpected exceptions pass through
158 return False 203 return False
159 # store exception, without traceback, for later retrieval 204 # store exception, without traceback, for later retrieval
160 self.exception = exc_value.with_traceback(None) 205 self.exception = exc_value.with_traceback(None)
161 if self.expected_regex is None: 206 if self.expected_regex is None:
162 return True 207 return True
163 208
164 expected_regex = self.expected_regex 209 expected_regex = self.expected_regex
165 if not expected_regex.search(str(exc_value)): 210 if not expected_regex.search(str(exc_value)):
166 self._raiseFailure('"{}" does not match "{}"'.format( 211 self._raiseFailure('"{}" does not match "{}"'.format(
167 expected_regex.pattern, str(exc_value))) 212 expected_regex.pattern, str(exc_value)))
168 return True 213 return True
169 214
170 215
171 class _AssertWarnsContext(_AssertRaisesBaseContext): 216 class _AssertWarnsContext(_AssertRaisesBaseContext):
172 """A context manager used to implement TestCase.assertWarns* methods.""" 217 """A context manager used to implement TestCase.assertWarns* methods."""
218
219 _base_type = Warning
220 _base_type_str = 'a warning type or tuple of warning types'
173 221
174 def __enter__(self): 222 def __enter__(self):
175 # The __warningregistry__'s need to be in a pristine state for tests 223 # The __warningregistry__'s need to be in a pristine state for tests
176 # to work properly. 224 # to work properly.
177 for v in sys.modules.values(): 225 for v in sys.modules.values():
178 if getattr(v, '__warningregistry__', None): 226 if getattr(v, '__warningregistry__', None):
179 v.__warningregistry__ = {} 227 v.__warningregistry__ = {}
180 self.warnings_manager = warnings.catch_warnings(record=True) 228 self.warnings_manager = warnings.catch_warnings(record=True)
181 self.warnings = self.warnings_manager.__enter__() 229 self.warnings = self.warnings_manager.__enter__()
182 warnings.simplefilter("always", self.expected) 230 warnings.simplefilter("always", self.expected)
(...skipping 27 matching lines...) Expand all
210 if first_matching is not None: 258 if first_matching is not None:
211 self._raiseFailure('"{}" does not match "{}"'.format( 259 self._raiseFailure('"{}" does not match "{}"'.format(
212 self.expected_regex.pattern, str(first_matching))) 260 self.expected_regex.pattern, str(first_matching)))
213 if self.obj_name: 261 if self.obj_name:
214 self._raiseFailure("{} not triggered by {}".format(exc_name, 262 self._raiseFailure("{} not triggered by {}".format(exc_name,
215 self.obj_name)) 263 self.obj_name))
216 else: 264 else:
217 self._raiseFailure("{} not triggered".format(exc_name)) 265 self._raiseFailure("{} not triggered".format(exc_name))
218 266
219 267
268
269 _LoggingWatcher = collections.namedtuple("_LoggingWatcher",
270 ["records", "output"])
271
272
273 class _CapturingHandler(logging.Handler):
274 """
275 A logging handler capturing all (raw and formatted) logging output.
276 """
277
278 def __init__(self):
279 logging.Handler.__init__(self)
280 self.watcher = _LoggingWatcher([], [])
281
282 def flush(self):
283 pass
284
285 def emit(self, record):
286 self.watcher.records.append(record)
287 msg = self.format(record)
288 self.watcher.output.append(msg)
289
290
291
292 class _AssertLogsContext(_BaseTestCaseContext):
293 """A context manager used to implement TestCase.assertLogs()."""
294
295 LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s"
296
297 def __init__(self, test_case, logger_name, level):
298 _BaseTestCaseContext.__init__(self, test_case)
299 self.logger_name = logger_name
300 if level:
301 self.level = logging._nameToLevel.get(level, level)
302 else:
303 self.level = logging.INFO
304 self.msg = None
305
306 def __enter__(self):
307 if isinstance(self.logger_name, logging.Logger):
308 logger = self.logger = self.logger_name
309 else:
310 logger = self.logger = logging.getLogger(self.logger_name)
311 formatter = logging.Formatter(self.LOGGING_FORMAT)
312 handler = _CapturingHandler()
313 handler.setFormatter(formatter)
314 self.watcher = handler.watcher
315 self.old_handlers = logger.handlers[:]
316 self.old_level = logger.level
317 self.old_propagate = logger.propagate
318 logger.handlers = [handler]
319 logger.setLevel(self.level)
320 logger.propagate = False
321 return handler.watcher
322
323 def __exit__(self, exc_type, exc_value, tb):
324 self.logger.handlers = self.old_handlers
325 self.logger.propagate = self.old_propagate
326 self.logger.setLevel(self.old_level)
327 if exc_type is not None:
328 # let unexpected exceptions pass through
329 return False
330 if len(self.watcher.records) == 0:
331 self._raiseFailure(
332 "no logs of level {} or higher triggered on {}"
333 .format(logging.getLevelName(self.level), self.logger.name))
334
335
220 class TestCase(object): 336 class TestCase(object):
221 """A class whose instances are single test cases. 337 """A class whose instances are single test cases.
222 338
223 By default, the test code itself should be placed in a method named 339 By default, the test code itself should be placed in a method named
224 'runTest'. 340 'runTest'.
225 341
226 If the fixture may be used for many test cases, create as 342 If the fixture may be used for many test cases, create as
227 many test methods as are needed. When instantiating such a TestCase 343 many test methods as are needed. When instantiating such a TestCase
228 subclass, specify in the constructor arguments the name of the test method 344 subclass, specify in the constructor arguments the name of the test method
229 that the instance is to execute. 345 that the instance is to execute.
230 346
231 Test authors should subclass TestCase for their own tests. Construction 347 Test authors should subclass TestCase for their own tests. Construction
232 and deconstruction of the test's environment ('fixture') can be 348 and deconstruction of the test's environment ('fixture') can be
233 implemented by overriding the 'setUp' and 'tearDown' methods respectively. 349 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
234 350
235 If it is necessary to override the __init__ method, the base class 351 If it is necessary to override the __init__ method, the base class
236 __init__ method must always be called. It is important that subclasses 352 __init__ method must always be called. It is important that subclasses
237 should not change the signature of their __init__ method, since instances 353 should not change the signature of their __init__ method, since instances
238 of the classes are instantiated automatically by parts of the framework 354 of the classes are instantiated automatically by parts of the framework
239 in order to be run. 355 in order to be run.
240 """ 356
241 357 When subclassing TestCase, you can set these attributes:
242 # This attribute determines which exception will be raised when 358 * failureException: determines which exception will be raised when
243 # the instance's assertion methods fail; test methods raising this 359 the instance's assertion methods fail; test methods raising this
244 # exception will be deemed to have 'failed' rather than 'errored' 360 exception will be deemed to have 'failed' rather than 'errored'.
361 * longMessage: determines whether long messages (including repr of
362 objects used in assert methods) will be printed on failure in *addition*
363 to any explicit message passed.
364 * maxDiff: sets the maximum length of a diff in failure messages
365 by assert methods using difflib. It is looked up as an instance
366 attribute so can be configured by individual tests if required.
367 """
245 368
246 failureException = AssertionError 369 failureException = AssertionError
247 370
248 # This attribute determines whether long messages (including repr of
249 # objects used in assert methods) will be printed on failure in *addition*
250 # to any explicit message passed.
251
252 longMessage = True 371 longMessage = True
253
254 # This attribute sets the maximum length of a diff in failure messages
255 # by assert methods using difflib. It is looked up as an instance attribute
256 # so can be configured by individual tests if required.
257 372
258 maxDiff = 80*8 373 maxDiff = 80*8
259 374
260 # If a string is longer than _diffThreshold, use normal comparison instead 375 # If a string is longer than _diffThreshold, use normal comparison instead
261 # of difflib. See #11763. 376 # of difflib. See #11763.
262 _diffThreshold = 2**16 377 _diffThreshold = 2**16
263 378
264 # Attribute used by TestSuite for classSetUp 379 # Attribute used by TestSuite for classSetUp
265 380
266 _classSetupFailed = False 381 _classSetupFailed = False
267 382
268 def __init__(self, methodName='runTest'): 383 def __init__(self, methodName='runTest'):
269 """Create an instance of the class that will use the named test 384 """Create an instance of the class that will use the named test
270 method when executed. Raises a ValueError if the instance does 385 method when executed. Raises a ValueError if the instance does
271 not have a method with the specified name. 386 not have a method with the specified name.
272 """ 387 """
273 self._testMethodName = methodName 388 self._testMethodName = methodName
274 self._outcomeForDoCleanups = None 389 self._outcome = None
275 self._testMethodDoc = 'No test' 390 self._testMethodDoc = 'No test'
276 try: 391 try:
277 testMethod = getattr(self, methodName) 392 testMethod = getattr(self, methodName)
278 except AttributeError: 393 except AttributeError:
279 if methodName != 'runTest': 394 if methodName != 'runTest':
280 # we allow instantiation with no explicit method name 395 # we allow instantiation with no explicit method name
281 # but not an *incorrect* or missing method name 396 # but not an *incorrect* or missing method name
282 raise ValueError("no such test method in %s: %s" % 397 raise ValueError("no such test method in %s: %s" %
283 (self.__class__, methodName)) 398 (self.__class__, methodName))
284 else: 399 else:
285 self._testMethodDoc = testMethod.__doc__ 400 self._testMethodDoc = testMethod.__doc__
286 self._cleanups = [] 401 self._cleanups = []
402 self._subtest = None
287 403
288 # Map types to custom assertEqual functions that will compare 404 # Map types to custom assertEqual functions that will compare
289 # instances of said type in more detail to generate a more useful 405 # instances of said type in more detail to generate a more useful
290 # error message. 406 # error message.
291 self._type_equality_funcs = {} 407 self._type_equality_funcs = {}
292 self.addTypeEqualityFunc(dict, 'assertDictEqual') 408 self.addTypeEqualityFunc(dict, 'assertDictEqual')
293 self.addTypeEqualityFunc(list, 'assertListEqual') 409 self.addTypeEqualityFunc(list, 'assertListEqual')
294 self.addTypeEqualityFunc(tuple, 'assertTupleEqual') 410 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
295 self.addTypeEqualityFunc(set, 'assertSetEqual') 411 self.addTypeEqualityFunc(set, 'assertSetEqual')
296 self.addTypeEqualityFunc(frozenset, 'assertSetEqual') 412 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 def __hash__(self): 480 def __hash__(self):
365 return hash((type(self), self._testMethodName)) 481 return hash((type(self), self._testMethodName))
366 482
367 def __str__(self): 483 def __str__(self):
368 return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) 484 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
369 485
370 def __repr__(self): 486 def __repr__(self):
371 return "<%s testMethod=%s>" % \ 487 return "<%s testMethod=%s>" % \
372 (strclass(self.__class__), self._testMethodName) 488 (strclass(self.__class__), self._testMethodName)
373 489
374 def _addSkip(self, result, reason): 490 def _addSkip(self, result, test_case, reason):
375 addSkip = getattr(result, 'addSkip', None) 491 addSkip = getattr(result, 'addSkip', None)
376 if addSkip is not None: 492 if addSkip is not None:
377 addSkip(self, reason) 493 addSkip(test_case, reason)
378 else: 494 else:
379 warnings.warn("TestResult has no addSkip method, skips not reported" , 495 warnings.warn("TestResult has no addSkip method, skips not reported" ,
380 RuntimeWarning, 2) 496 RuntimeWarning, 2)
497 result.addSuccess(test_case)
498
499 @contextlib.contextmanager
500 def subTest(self, msg=None, **params):
501 """Return a context manager that will return the enclosed block
502 of code in a subtest identified by the optional message and
503 keyword parameters. A failure in the subtest marks the test
504 case as failed but resumes execution at the end of the enclosed
505 block, allowing further test code to be executed.
506 """
507 if not self._outcome.result_supports_subtests:
508 yield
509 return
510 parent = self._subtest
511 if parent is None:
512 params_map = collections.ChainMap(params)
513 else:
514 params_map = parent.params.new_child(params)
515 self._subtest = _SubTest(self, msg, params_map)
516 try:
517 with self._outcome.testPartExecutor(self._subtest, isTest=True):
518 yield
519 if not self._outcome.success:
520 result = self._outcome.result
521 if result is not None and result.failfast:
522 raise _ShouldStop
523 elif self._outcome.expectedFailure:
524 # If the test is expecting a failure, we really want to
525 # stop now and register the expected failure.
526 raise _ShouldStop
527 finally:
528 self._subtest = parent
529
530 def _feedErrorsToResult(self, result, errors):
531 for test, exc_info in errors:
532 if isinstance(test, _SubTest):
533 result.addSubTest(test.test_case, test, exc_info)
534 elif exc_info is not None:
535 if issubclass(exc_info[0], self.failureException):
536 result.addFailure(test, exc_info)
537 else:
538 result.addError(test, exc_info)
539
540 def _addExpectedFailure(self, result, exc_info):
541 try:
542 addExpectedFailure = result.addExpectedFailure
543 except AttributeError:
544 warnings.warn("TestResult has no addExpectedFailure method, reportin g as passes",
545 RuntimeWarning)
381 result.addSuccess(self) 546 result.addSuccess(self)
382 547 else:
383 def _executeTestPart(self, function, outcome, isTest=False): 548 addExpectedFailure(self, exc_info)
549
550 def _addUnexpectedSuccess(self, result):
384 try: 551 try:
385 function() 552 addUnexpectedSuccess = result.addUnexpectedSuccess
386 except KeyboardInterrupt: 553 except AttributeError:
387 raise 554 warnings.warn("TestResult has no addUnexpectedSuccess method, report ing as failure",
388 except SkipTest as e: 555 RuntimeWarning)
389 outcome.success = False 556 # We need to pass an actual exception and traceback to addFailure,
390 outcome.skipped = str(e) 557 # otherwise the legacy result can choke.
391 except _UnexpectedSuccess: 558 try:
392 exc_info = sys.exc_info() 559 raise _UnexpectedSuccess from None
393 outcome.success = False 560 except _UnexpectedSuccess:
394 if isTest: 561 result.addFailure(self, sys.exc_info())
395 outcome.unexpectedSuccess = exc_info 562 else:
396 else: 563 addUnexpectedSuccess(self)
397 outcome.errors.append(exc_info)
398 except _ExpectedFailure:
399 outcome.success = False
400 exc_info = sys.exc_info()
401 if isTest:
402 outcome.expectedFailure = exc_info
403 else:
404 outcome.errors.append(exc_info)
405 except self.failureException:
406 outcome.success = False
407 outcome.failures.append(sys.exc_info())
408 exc_info = sys.exc_info()
409 except:
410 outcome.success = False
411 outcome.errors.append(sys.exc_info())
412 564
413 def run(self, result=None): 565 def run(self, result=None):
414 orig_result = result 566 orig_result = result
415 if result is None: 567 if result is None:
416 result = self.defaultTestResult() 568 result = self.defaultTestResult()
417 startTestRun = getattr(result, 'startTestRun', None) 569 startTestRun = getattr(result, 'startTestRun', None)
418 if startTestRun is not None: 570 if startTestRun is not None:
419 startTestRun() 571 startTestRun()
420 572
421 result.startTest(self) 573 result.startTest(self)
422 574
423 testMethod = getattr(self, self._testMethodName) 575 testMethod = getattr(self, self._testMethodName)
424 if (getattr(self.__class__, "__unittest_skip__", False) or 576 if (getattr(self.__class__, "__unittest_skip__", False) or
425 getattr(testMethod, "__unittest_skip__", False)): 577 getattr(testMethod, "__unittest_skip__", False)):
426 # If the class or method was skipped. 578 # If the class or method was skipped.
427 try: 579 try:
428 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 580 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
429 or getattr(testMethod, '__unittest_skip_why__', '')) 581 or getattr(testMethod, '__unittest_skip_why__', ''))
430 self._addSkip(result, skip_why) 582 self._addSkip(result, self, skip_why)
431 finally: 583 finally:
432 result.stopTest(self) 584 result.stopTest(self)
433 return 585 return
586 expecting_failure = getattr(testMethod,
587 "__unittest_expecting_failure__", False)
588 outcome = _Outcome(result)
434 try: 589 try:
435 outcome = _Outcome() 590 self._outcome = outcome
436 self._outcomeForDoCleanups = outcome 591
437 592 with outcome.testPartExecutor(self):
438 self._executeTestPart(self.setUp, outcome) 593 self.setUp()
439 if outcome.success: 594 if outcome.success:
440 self._executeTestPart(testMethod, outcome, isTest=True) 595 outcome.expecting_failure = expecting_failure
441 self._executeTestPart(self.tearDown, outcome) 596 with outcome.testPartExecutor(self, isTest=True):
597 testMethod()
598 outcome.expecting_failure = False
599 with outcome.testPartExecutor(self):
600 self.tearDown()
442 601
443 self.doCleanups() 602 self.doCleanups()
603 for test, reason in outcome.skipped:
604 self._addSkip(result, test, reason)
605 self._feedErrorsToResult(result, outcome.errors)
444 if outcome.success: 606 if outcome.success:
445 result.addSuccess(self) 607 if expecting_failure:
446 else: 608 if outcome.expectedFailure:
447 if outcome.skipped is not None: 609 self._addExpectedFailure(result, outcome.expectedFailure )
448 self._addSkip(result, outcome.skipped)
449 for exc_info in outcome.errors:
450 result.addError(self, exc_info)
451 for exc_info in outcome.failures:
452 result.addFailure(self, exc_info)
453 if outcome.unexpectedSuccess is not None:
454 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess ', None)
455 if addUnexpectedSuccess is not None:
456 addUnexpectedSuccess(self)
457 else: 610 else:
458 warnings.warn("TestResult has no addUnexpectedSuccess me thod, reporting as failures", 611 self._addUnexpectedSuccess(result)
459 RuntimeWarning) 612 else:
460 result.addFailure(self, outcome.unexpectedSuccess) 613 result.addSuccess(self)
461
462 if outcome.expectedFailure is not None:
463 addExpectedFailure = getattr(result, 'addExpectedFailure', N one)
464 if addExpectedFailure is not None:
465 addExpectedFailure(self, outcome.expectedFailure)
466 else:
467 warnings.warn("TestResult has no addExpectedFailure meth od, reporting as passes",
468 RuntimeWarning)
469 result.addSuccess(self)
470 return result 614 return result
471 finally: 615 finally:
472 result.stopTest(self) 616 result.stopTest(self)
473 if orig_result is None: 617 if orig_result is None:
474 stopTestRun = getattr(result, 'stopTestRun', None) 618 stopTestRun = getattr(result, 'stopTestRun', None)
475 if stopTestRun is not None: 619 if stopTestRun is not None:
476 stopTestRun() 620 stopTestRun()
477 621
622 # explicitly break reference cycles:
623 # outcome.errors -> frame -> outcome -> outcome.errors
624 # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFai lure
625 outcome.errors.clear()
626 outcome.expectedFailure = None
627
628 # clear the outcome, no more needed
629 self._outcome = None
630
478 def doCleanups(self): 631 def doCleanups(self):
479 """Execute all cleanup functions. Normally called for you after 632 """Execute all cleanup functions. Normally called for you after
480 tearDown.""" 633 tearDown."""
481 outcome = self._outcomeForDoCleanups or _Outcome() 634 outcome = self._outcome or _Outcome()
482 while self._cleanups: 635 while self._cleanups:
483 function, args, kwargs = self._cleanups.pop() 636 function, args, kwargs = self._cleanups.pop()
484 part = lambda: function(*args, **kwargs) 637 with outcome.testPartExecutor(self):
485 self._executeTestPart(part, outcome) 638 function(*args, **kwargs)
486 639
487 # return this for backwards compatibility 640 # return this for backwards compatibility
488 # even though we no longer us it internally 641 # even though we no longer us it internally
489 return outcome.success 642 return outcome.success
490 643
491 def __call__(self, *args, **kwds): 644 def __call__(self, *args, **kwds):
492 return self.run(*args, **kwds) 645 return self.run(*args, **kwds)
493 646
494 def debug(self): 647 def debug(self):
495 """Run the test without collecting errors in a TestResult""" 648 """Run the test without collecting errors in a TestResult"""
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 return msg or standardMsg 687 return msg or standardMsg
535 if msg is None: 688 if msg is None:
536 return standardMsg 689 return standardMsg
537 try: 690 try:
538 # don't switch to '{}' formatting in Python 2.X 691 # don't switch to '{}' formatting in Python 2.X
539 # it changes the way unicode input is handled 692 # it changes the way unicode input is handled
540 return '%s : %s' % (standardMsg, msg) 693 return '%s : %s' % (standardMsg, msg)
541 except UnicodeDecodeError: 694 except UnicodeDecodeError:
542 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) 695 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
543 696
544 def assertRaises(self, excClass, callableObj=None, *args, **kwargs): 697 def assertRaises(self, expected_exception, *args, **kwargs):
545 """Fail unless an exception of class excClass is thrown 698 """Fail unless an exception of class expected_exception is raised
546 by callableObj when invoked with arguments args and keyword 699 by the callable when invoked with specified positional and
547 arguments kwargs. If a different type of exception is 700 keyword arguments. If a different type of exception is
548 thrown, it will not be caught, and the test case will be 701 raised, it will not be caught, and the test case will be
549 deemed to have suffered an error, exactly as for an 702 deemed to have suffered an error, exactly as for an
550 unexpected exception. 703 unexpected exception.
551 704
552 If called with callableObj omitted or None, will return a 705 If called with the callable and arguments omitted, will return a
553 context object used like this:: 706 context object used like this::
554 707
555 with self.assertRaises(SomeException): 708 with self.assertRaises(SomeException):
556 do_something() 709 do_something()
557 710
558 An optional keyword argument 'msg' can be provided when assertRaises 711 An optional keyword argument 'msg' can be provided when assertRaises
559 is used as a context object. 712 is used as a context object.
560 713
561 The context manager keeps a reference to the exception as 714 The context manager keeps a reference to the exception as
562 the 'exception' attribute. This allows you to inspect the 715 the 'exception' attribute. This allows you to inspect the
563 exception after the assertion:: 716 exception after the assertion::
564 717
565 with self.assertRaises(SomeException) as cm: 718 with self.assertRaises(SomeException) as cm:
566 do_something() 719 do_something()
567 the_exception = cm.exception 720 the_exception = cm.exception
568 self.assertEqual(the_exception.error_code, 3) 721 self.assertEqual(the_exception.error_code, 3)
569 """ 722 """
570 def check_is_exception(e): 723 context = _AssertRaisesContext(expected_exception, self)
r.david.murray 2012/09/01 03:00:27 I prefer the style where a helper function like th
illicitonion 2012/09/01 03:35:38 Pushed up to private module level helper
571 if not type(e) is type or not issubclass(e, BaseException): 724 return context.handle('assertRaises', args, kwargs)
572 raise TypeError('assertRaises arg 1 must be an exception type ' 725
573 'or tuple of exception types') 726 def assertWarns(self, expected_warning, *args, **kwargs):
574
575 if type(excClass) is tuple:
r.david.murray 2012/09/01 03:00:27 These checks should be done inside the _AssertRais
illicitonion 2012/09/01 03:35:38 Done.
576 for e in excClass:
577 check_is_exception(e)
578 else:
579 check_is_exception(excClass)
580
581 context = _AssertRaisesContext(excClass, self, callableObj)
582 return context.handle('assertRaises', callableObj, args, kwargs)
583
584 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
585 """Fail unless a warning of class warnClass is triggered 727 """Fail unless a warning of class warnClass is triggered
586 by callable_obj when invoked with arguments args and keyword 728 by the callable when invoked with specified positional and
587 arguments kwargs. If a different type of warning is 729 keyword arguments. If a different type of warning is
588 triggered, it will not be handled: depending on the other 730 triggered, it will not be handled: depending on the other
589 warning filtering rules in effect, it might be silenced, printed 731 warning filtering rules in effect, it might be silenced, printed
590 out, or raised as an exception. 732 out, or raised as an exception.
591 733
592 If called with callable_obj omitted or None, will return a 734 If called with the callable and arguments omitted, will return a
593 context object used like this:: 735 context object used like this::
594 736
595 with self.assertWarns(SomeWarning): 737 with self.assertWarns(SomeWarning):
596 do_something() 738 do_something()
597 739
598 An optional keyword argument 'msg' can be provided when assertWarns 740 An optional keyword argument 'msg' can be provided when assertWarns
599 is used as a context object. 741 is used as a context object.
600 742
601 The context manager keeps a reference to the first matching 743 The context manager keeps a reference to the first matching
602 warning as the 'warning' attribute; similarly, the 'filename' 744 warning as the 'warning' attribute; similarly, the 'filename'
603 and 'lineno' attributes give you information about the line 745 and 'lineno' attributes give you information about the line
604 of Python code from which the warning was triggered. 746 of Python code from which the warning was triggered.
605 This allows you to inspect the warning after the assertion:: 747 This allows you to inspect the warning after the assertion::
606 748
607 with self.assertWarns(SomeWarning) as cm: 749 with self.assertWarns(SomeWarning) as cm:
608 do_something() 750 do_something()
609 the_warning = cm.warning 751 the_warning = cm.warning
610 self.assertEqual(the_warning.some_attribute, 147) 752 self.assertEqual(the_warning.some_attribute, 147)
611 """ 753 """
612 context = _AssertWarnsContext(expected_warning, self, callable_obj) 754 context = _AssertWarnsContext(expected_warning, self)
613 return context.handle('assertWarns', callable_obj, args, kwargs) 755 return context.handle('assertWarns', args, kwargs)
756
757 def assertLogs(self, logger=None, level=None):
758 """Fail unless a log message of level *level* or higher is emitted
759 on *logger_name* or its children. If omitted, *level* defaults to
760 INFO and *logger* defaults to the root logger.
761
762 This method must be used as a context manager, and will yield
763 a recording object with two attributes: `output` and `records`.
764 At the end of the context manager, the `output` attribute will
765 be a list of the matching formatted log messages and the
766 `records` attribute will be a list of the corresponding LogRecord
767 objects.
768
769 Example::
770
771 with self.assertLogs('foo', level='INFO') as cm:
772 logging.getLogger('foo').info('first message')
773 logging.getLogger('foo.bar').error('second message')
774 self.assertEqual(cm.output, ['INFO:foo:first message',
775 'ERROR:foo.bar:second message'])
776 """
777 return _AssertLogsContext(self, logger, level)
614 778
615 def _getAssertEqualityFunc(self, first, second): 779 def _getAssertEqualityFunc(self, first, second):
616 """Get a detailed comparison function for the types of the two args. 780 """Get a detailed comparison function for the types of the two args.
617 781
618 Returns: A callable accepting (first, second, msg=None) that will 782 Returns: A callable accepting (first, second, msg=None) that will
619 raise a failure exception if first != second with a useful human 783 raise a failure exception if first != second with a useful human
620 readable error message for those types. 784 readable error message for those types.
621 """ 785 """
622 # 786 #
623 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) 787 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
(...skipping 10 matching lines...) Expand all
634 if asserter is not None: 798 if asserter is not None:
635 if isinstance(asserter, str): 799 if isinstance(asserter, str):
636 asserter = getattr(self, asserter) 800 asserter = getattr(self, asserter)
637 return asserter 801 return asserter
638 802
639 return self._baseAssertEqual 803 return self._baseAssertEqual
640 804
641 def _baseAssertEqual(self, first, second, msg=None): 805 def _baseAssertEqual(self, first, second, msg=None):
642 """The default assertEqual implementation, not type specific.""" 806 """The default assertEqual implementation, not type specific."""
643 if not first == second: 807 if not first == second:
644 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second)) 808 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
645 msg = self._formatMessage(msg, standardMsg) 809 msg = self._formatMessage(msg, standardMsg)
646 raise self.failureException(msg) 810 raise self.failureException(msg)
647 811
648 def assertEqual(self, first, second, msg=None): 812 def assertEqual(self, first, second, msg=None):
649 """Fail if the two objects are unequal as determined by the '==' 813 """Fail if the two objects are unequal as determined by the '=='
650 operator. 814 operator.
651 """ 815 """
652 assertion_func = self._getAssertEqualityFunc(first, second) 816 assertion_func = self._getAssertEqualityFunc(first, second)
653 assertion_func(first, second, msg=msg) 817 assertion_func(first, second, msg=msg)
654 818
655 def assertNotEqual(self, first, second, msg=None): 819 def assertNotEqual(self, first, second, msg=None):
656 """Fail if the two objects are equal as determined by the '==' 820 """Fail if the two objects are equal as determined by the '!='
657 operator. 821 operator.
658 """ 822 """
659 if not first != second: 823 if not first != second:
660 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), 824 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
661 safe_repr(second))) 825 safe_repr(second)))
662 raise self.failureException(msg) 826 raise self.failureException(msg)
663 827
664 def assertAlmostEqual(self, first, second, places=None, msg=None, 828 def assertAlmostEqual(self, first, second, places=None, msg=None,
665 delta=None): 829 delta=None):
666 """Fail if the two objects are unequal as determined by their 830 """Fail if the two objects are unequal as determined by their
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 which can be indexed, has a length, and has an equality operator. 904 which can be indexed, has a length, and has an equality operator.
741 905
742 Args: 906 Args:
743 seq1: The first sequence to compare. 907 seq1: The first sequence to compare.
744 seq2: The second sequence to compare. 908 seq2: The second sequence to compare.
745 seq_type: The expected datatype of the sequences, or None if no 909 seq_type: The expected datatype of the sequences, or None if no
746 datatype should be enforced. 910 datatype should be enforced.
747 msg: Optional message to use on failure instead of a list of 911 msg: Optional message to use on failure instead of a list of
748 differences. 912 differences.
749 """ 913 """
750 if seq_type != None: 914 if seq_type is not None:
751 seq_type_name = seq_type.__name__ 915 seq_type_name = seq_type.__name__
752 if not isinstance(seq1, seq_type): 916 if not isinstance(seq1, seq_type):
753 raise self.failureException('First sequence is not a %s: %s' 917 raise self.failureException('First sequence is not a %s: %s'
754 % (seq_type_name, safe_repr(seq1))) 918 % (seq_type_name, safe_repr(seq1)))
755 if not isinstance(seq2, seq_type): 919 if not isinstance(seq2, seq_type):
756 raise self.failureException('Second sequence is not a %s: %s' 920 raise self.failureException('Second sequence is not a %s: %s'
757 % (seq_type_name, safe_repr(seq2))) 921 % (seq_type_name, safe_repr(seq2)))
758 else: 922 else:
759 seq_type_name = "sequence" 923 seq_type_name = "sequence"
760 924
761 differing = None 925 differing = None
762 try: 926 try:
763 len1 = len(seq1) 927 len1 = len(seq1)
764 except (TypeError, NotImplementedError): 928 except (TypeError, NotImplementedError):
765 differing = 'First %s has no length. Non-sequence?' % ( 929 differing = 'First %s has no length. Non-sequence?' % (
766 seq_type_name) 930 seq_type_name)
767 931
768 if differing is None: 932 if differing is None:
769 try: 933 try:
770 len2 = len(seq2) 934 len2 = len(seq2)
771 except (TypeError, NotImplementedError): 935 except (TypeError, NotImplementedError):
772 differing = 'Second %s has no length. Non-sequence?' % ( 936 differing = 'Second %s has no length. Non-sequence?' % (
773 seq_type_name) 937 seq_type_name)
774 938
775 if differing is None: 939 if differing is None:
776 if seq1 == seq2: 940 if seq1 == seq2:
777 return 941 return
778 942
779 seq1_repr = safe_repr(seq1) 943 differing = '%ss differ: %s != %s\n' % (
780 seq2_repr = safe_repr(seq2) 944 (seq_type_name.capitalize(),) +
781 if len(seq1_repr) > 30: 945 _common_shorten_repr(seq1, seq2))
782 seq1_repr = seq1_repr[:30] + '...'
783 if len(seq2_repr) > 30:
784 seq2_repr = seq2_repr[:30] + '...'
785 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
786 differing = '%ss differ: %s != %s\n' % elements
787 946
788 for i in range(min(len1, len2)): 947 for i in range(min(len1, len2)):
789 try: 948 try:
790 item1 = seq1[i] 949 item1 = seq1[i]
791 except (TypeError, IndexError, NotImplementedError): 950 except (TypeError, IndexError, NotImplementedError):
792 differing += ('\nUnable to index element %d of first %s\n' % 951 differing += ('\nUnable to index element %d of first %s\n' %
793 (i, seq_type_name)) 952 (i, seq_type_name))
794 break 953 break
795 954
796 try: 955 try:
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 """Just like self.assertTrue(a is not b), but with a nicer default messa ge.""" 1093 """Just like self.assertTrue(a is not b), but with a nicer default messa ge."""
935 if expr1 is expr2: 1094 if expr1 is expr2:
936 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) 1095 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
937 self.fail(self._formatMessage(msg, standardMsg)) 1096 self.fail(self._formatMessage(msg, standardMsg))
938 1097
939 def assertDictEqual(self, d1, d2, msg=None): 1098 def assertDictEqual(self, d1, d2, msg=None):
940 self.assertIsInstance(d1, dict, 'First argument is not a dictionary') 1099 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
941 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') 1100 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
942 1101
943 if d1 != d2: 1102 if d1 != d2:
944 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True) ) 1103 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
945 diff = ('\n' + '\n'.join(difflib.ndiff( 1104 diff = ('\n' + '\n'.join(difflib.ndiff(
946 pprint.pformat(d1).splitlines(), 1105 pprint.pformat(d1).splitlines(),
947 pprint.pformat(d2).splitlines()))) 1106 pprint.pformat(d2).splitlines())))
948 standardMsg = self._truncateMessage(standardMsg, diff) 1107 standardMsg = self._truncateMessage(standardMsg, diff)
949 self.fail(self._formatMessage(msg, standardMsg)) 1108 self.fail(self._formatMessage(msg, standardMsg))
950 1109
951 def assertDictContainsSubset(self, subset, dictionary, msg=None): 1110 def assertDictContainsSubset(self, subset, dictionary, msg=None):
952 """Checks whether dictionary is a superset of subset.""" 1111 """Checks whether dictionary is a superset of subset."""
953 warnings.warn('assertDictContainsSubset is deprecated', 1112 warnings.warn('assertDictContainsSubset is deprecated',
954 DeprecationWarning) 1113 DeprecationWarning)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 if first != second: 1177 if first != second:
1019 # don't use difflib if the strings are too long 1178 # don't use difflib if the strings are too long
1020 if (len(first) > self._diffThreshold or 1179 if (len(first) > self._diffThreshold or
1021 len(second) > self._diffThreshold): 1180 len(second) > self._diffThreshold):
1022 self._baseAssertEqual(first, second, msg) 1181 self._baseAssertEqual(first, second, msg)
1023 firstlines = first.splitlines(keepends=True) 1182 firstlines = first.splitlines(keepends=True)
1024 secondlines = second.splitlines(keepends=True) 1183 secondlines = second.splitlines(keepends=True)
1025 if len(firstlines) == 1 and first.strip('\r\n') == first: 1184 if len(firstlines) == 1 and first.strip('\r\n') == first:
1026 firstlines = [first + '\n'] 1185 firstlines = [first + '\n']
1027 secondlines = [second + '\n'] 1186 secondlines = [second + '\n']
1028 standardMsg = '%s != %s' % (safe_repr(first, True), 1187 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
1029 safe_repr(second, True))
1030 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) 1188 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
1031 standardMsg = self._truncateMessage(standardMsg, diff) 1189 standardMsg = self._truncateMessage(standardMsg, diff)
1032 self.fail(self._formatMessage(msg, standardMsg)) 1190 self.fail(self._formatMessage(msg, standardMsg))
1033 1191
1034 def assertLess(self, a, b, msg=None): 1192 def assertLess(self, a, b, msg=None):
1035 """Just like self.assertTrue(a < b), but with a nicer default message."" " 1193 """Just like self.assertTrue(a < b), but with a nicer default message."" "
1036 if not a < b: 1194 if not a < b:
1037 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) 1195 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
1038 self.fail(self._formatMessage(msg, standardMsg)) 1196 self.fail(self._formatMessage(msg, standardMsg))
1039 1197
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) 1232 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
1075 self.fail(self._formatMessage(msg, standardMsg)) 1233 self.fail(self._formatMessage(msg, standardMsg))
1076 1234
1077 def assertNotIsInstance(self, obj, cls, msg=None): 1235 def assertNotIsInstance(self, obj, cls, msg=None):
1078 """Included for symmetry with assertIsInstance.""" 1236 """Included for symmetry with assertIsInstance."""
1079 if isinstance(obj, cls): 1237 if isinstance(obj, cls):
1080 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) 1238 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
1081 self.fail(self._formatMessage(msg, standardMsg)) 1239 self.fail(self._formatMessage(msg, standardMsg))
1082 1240
1083 def assertRaisesRegex(self, expected_exception, expected_regex, 1241 def assertRaisesRegex(self, expected_exception, expected_regex,
1084 callable_obj=None, *args, **kwargs): 1242 *args, **kwargs):
1085 """Asserts that the message in a raised exception matches a regex. 1243 """Asserts that the message in a raised exception matches a regex.
1086 1244
1087 Args: 1245 Args:
1088 expected_exception: Exception class expected to be raised. 1246 expected_exception: Exception class expected to be raised.
1089 expected_regex: Regex (re pattern object or string) expected 1247 expected_regex: Regex (re pattern object or string) expected
1090 to be found in error message. 1248 to be found in error message.
1091 callable_obj: Function to be called. 1249 args: Function to be called and extra positional args.
1250 kwargs: Extra kwargs.
1092 msg: Optional message used in case of failure. Can only be used 1251 msg: Optional message used in case of failure. Can only be used
1093 when assertRaisesRegex is used as a context manager. 1252 when assertRaisesRegex is used as a context manager.
1094 args: Extra args. 1253 """
1095 kwargs: Extra kwargs. 1254 context = _AssertRaisesContext(expected_exception, self, expected_regex)
1096 """ 1255 return context.handle('assertRaisesRegex', args, kwargs)
1097 context = _AssertRaisesContext(expected_exception, self, callable_obj,
1098 expected_regex)
1099
1100 return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
1101 1256
1102 def assertWarnsRegex(self, expected_warning, expected_regex, 1257 def assertWarnsRegex(self, expected_warning, expected_regex,
1103 callable_obj=None, *args, **kwargs): 1258 *args, **kwargs):
1104 """Asserts that the message in a triggered warning matches a regexp. 1259 """Asserts that the message in a triggered warning matches a regexp.
1105 Basic functioning is similar to assertWarns() with the addition 1260 Basic functioning is similar to assertWarns() with the addition
1106 that only warnings whose messages also match the regular expression 1261 that only warnings whose messages also match the regular expression
1107 are considered successful matches. 1262 are considered successful matches.
1108 1263
1109 Args: 1264 Args:
1110 expected_warning: Warning class expected to be triggered. 1265 expected_warning: Warning class expected to be triggered.
1111 expected_regex: Regex (re pattern object or string) expected 1266 expected_regex: Regex (re pattern object or string) expected
1112 to be found in error message. 1267 to be found in error message.
1113 callable_obj: Function to be called. 1268 args: Function to be called and extra positional args.
1269 kwargs: Extra kwargs.
1114 msg: Optional message used in case of failure. Can only be used 1270 msg: Optional message used in case of failure. Can only be used
1115 when assertWarnsRegex is used as a context manager. 1271 when assertWarnsRegex is used as a context manager.
1116 args: Extra args. 1272 """
1117 kwargs: Extra kwargs. 1273 context = _AssertWarnsContext(expected_warning, self, expected_regex)
1118 """ 1274 return context.handle('assertWarnsRegex', args, kwargs)
1119 context = _AssertWarnsContext(expected_warning, self, callable_obj,
1120 expected_regex)
1121 return context.handle('assertWarnsRegex', callable_obj, args, kwargs)
1122 1275
1123 def assertRegex(self, text, expected_regex, msg=None): 1276 def assertRegex(self, text, expected_regex, msg=None):
1124 """Fail the test unless the text matches the regular expression.""" 1277 """Fail the test unless the text matches the regular expression."""
1125 if isinstance(expected_regex, (str, bytes)): 1278 if isinstance(expected_regex, (str, bytes)):
1126 assert expected_regex, "expected_regex must not be empty." 1279 assert expected_regex, "expected_regex must not be empty."
1127 expected_regex = re.compile(expected_regex) 1280 expected_regex = re.compile(expected_regex)
1128 if not expected_regex.search(text): 1281 if not expected_regex.search(text):
1129 msg = msg or "Regex didn't match" 1282 msg = msg or "Regex didn't match"
1130 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text) 1283 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
1131 raise self.failureException(msg) 1284 raise self.failureException(msg)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 1350
1198 def __eq__(self, other): 1351 def __eq__(self, other):
1199 if not isinstance(other, self.__class__): 1352 if not isinstance(other, self.__class__):
1200 return NotImplemented 1353 return NotImplemented
1201 1354
1202 return self._setUpFunc == other._setUpFunc and \ 1355 return self._setUpFunc == other._setUpFunc and \
1203 self._tearDownFunc == other._tearDownFunc and \ 1356 self._tearDownFunc == other._tearDownFunc and \
1204 self._testFunc == other._testFunc and \ 1357 self._testFunc == other._testFunc and \
1205 self._description == other._description 1358 self._description == other._description
1206 1359
1207 def __ne__(self, other):
1208 return not self == other
1209
1210 def __hash__(self): 1360 def __hash__(self):
1211 return hash((type(self), self._setUpFunc, self._tearDownFunc, 1361 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1212 self._testFunc, self._description)) 1362 self._testFunc, self._description))
1213 1363
1214 def __str__(self): 1364 def __str__(self):
1215 return "%s (%s)" % (strclass(self.__class__), 1365 return "%s (%s)" % (strclass(self.__class__),
1216 self._testFunc.__name__) 1366 self._testFunc.__name__)
1217 1367
1218 def __repr__(self): 1368 def __repr__(self):
1219 return "<%s tec=%s>" % (strclass(self.__class__), 1369 return "<%s tec=%s>" % (strclass(self.__class__),
1220 self._testFunc) 1370 self._testFunc)
1221 1371
1222 def shortDescription(self): 1372 def shortDescription(self):
1223 if self._description is not None: 1373 if self._description is not None:
1224 return self._description 1374 return self._description
1225 doc = self._testFunc.__doc__ 1375 doc = self._testFunc.__doc__
1226 return doc and doc.split("\n")[0].strip() or None 1376 return doc and doc.split("\n")[0].strip() or None
1377
1378
1379 class _SubTest(TestCase):
1380
1381 def __init__(self, test_case, message, params):
1382 super().__init__()
1383 self._message = message
1384 self.test_case = test_case
1385 self.params = params
1386 self.failureException = test_case.failureException
1387
1388 def runTest(self):
1389 raise NotImplementedError("subtests cannot be run directly")
1390
1391 def _subDescription(self):
1392 parts = []
1393 if self._message:
1394 parts.append("[{}]".format(self._message))
1395 if self.params:
1396 params_desc = ', '.join(
1397 "{}={!r}".format(k, v)
1398 for (k, v) in sorted(self.params.items()))
1399 parts.append("({})".format(params_desc))
1400 return " ".join(parts) or '(<subtest>)'
1401
1402 def id(self):
1403 return "{} {}".format(self.test_case.id(), self._subDescription())
1404
1405 def shortDescription(self):
1406 """Returns a one-line description of the subtest, or None if no
1407 description has been provided.
1408 """
1409 return self.test_case.shortDescription()
1410
1411 def __str__(self):
1412 return "{} {}".format(self.test_case, self._subDescription())
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+