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

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 collections
4 import sys 3 import sys
5 import functools 4 import functools
6 import difflib 5 import difflib
6 import logging
7 import pprint 7 import pprint
8 import re 8 import re
9 import types
10 import warnings 9 import warnings
10 import collections
11 import contextlib
12 import traceback
11 13
12 from . import result 14 from . import result
13 from .util import ( 15 from .util import (strclass, safe_repr, _count_diff_all_purpose,
14 strclass, safe_repr, unorderable_list_difference, 16 _count_diff_hashable, _common_shorten_repr)
15 _count_diff_all_purpose, _count_diff_hashable
16 )
17
18 17
19 __unittest = True 18 __unittest = True
20 19
21 20
22 DIFF_OMITTED = ('\nDiff is %s characters long. ' 21 DIFF_OMITTED = ('\nDiff is %s characters long. '
23 'Set self.maxDiff to None to see it.') 22 'Set self.maxDiff to None to see it.')
24 23
25 class SkipTest(Exception): 24 class SkipTest(Exception):
26 """ 25 """
27 Raise this exception in a test to skip it. 26 Raise this exception in a test to skip it.
28 27
29 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
30 instead of raising this directly. 29 instead of raising this directly.
31 """ 30 """
32 pass 31
33 32 class _ShouldStop(Exception):
34 class _ExpectedFailure(Exception): 33 """
35 """ 34 The test should stop.
36 Raise this when a test is expected to fail. 35 """
37
38 This is an implementation detail.
39 """
40
41 def __init__(self, exc_info):
42 super(_ExpectedFailure, self).__init__()
43 self.exc_info = exc_info
44 36
45 class _UnexpectedSuccess(Exception): 37 class _UnexpectedSuccess(Exception):
46 """ 38 """
47 The test was supposed to fail, but it didn't! 39 The test was supposed to fail, but it didn't!
48 """ 40 """
49 pass 41
42
43 class _Outcome(object):
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
49 self.skipped = []
50 self.expectedFailure = None
51 self.errors = []
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
81
50 82
51 def _id(obj): 83 def _id(obj):
52 return obj 84 return obj
53 85
54 def skip(reason): 86 def skip(reason):
55 """ 87 """
56 Unconditionally skip a test. 88 Unconditionally skip a test.
57 """ 89 """
58 def decorator(test_item): 90 def decorator(test_item):
59 if not isinstance(test_item, (type, types.ClassType)): 91 if not isinstance(test_item, type):
60 @functools.wraps(test_item) 92 @functools.wraps(test_item)
61 def skip_wrapper(*args, **kwargs): 93 def skip_wrapper(*args, **kwargs):
62 raise SkipTest(reason) 94 raise SkipTest(reason)
63 test_item = skip_wrapper 95 test_item = skip_wrapper
64 96
65 test_item.__unittest_skip__ = True 97 test_item.__unittest_skip__ = True
66 test_item.__unittest_skip_why__ = reason 98 test_item.__unittest_skip_why__ = reason
67 return test_item 99 return test_item
68 return decorator 100 return decorator
69 101
70 def skipIf(condition, reason): 102 def skipIf(condition, reason):
71 """ 103 """
72 Skip a test if the condition is true. 104 Skip a test if the condition is true.
73 """ 105 """
74 if condition: 106 if condition:
75 return skip(reason) 107 return skip(reason)
76 return _id 108 return _id
77 109
78 def skipUnless(condition, reason): 110 def skipUnless(condition, reason):
79 """ 111 """
80 Skip a test unless the condition is true. 112 Skip a test unless the condition is true.
81 """ 113 """
82 if not condition: 114 if not condition:
83 return skip(reason) 115 return skip(reason)
84 return _id 116 return _id
85 117
86 118 def expectedFailure(test_item):
87 def expectedFailure(func): 119 test_item.__unittest_expecting_failure__ = True
88 @functools.wraps(func) 120 return test_item
89 def wrapper(*args, **kwargs): 121
122 def _is_subtype(expected, basetype):
123 if isinstance(expected, tuple):
124 return all(_is_subtype(e, basetype) for e in expected)
125 return isinstance(expected, type) and issubclass(expected, basetype)
126
127 class _BaseTestCaseContext:
128
129 def __init__(self, test_case):
130 self.test_case = test_case
131
132 def _raiseFailure(self, standardMsg):
133 msg = self.test_case._formatMessage(self.msg, standardMsg)
134 raise self.test_case.failureException(msg)
135
136 class _AssertRaisesBaseContext(_BaseTestCaseContext):
137
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
151 context manager, so check for a 'msg' kwarg and return self.
152 If args is not empty, call a callable passing positional and keyword
153 arguments.
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:
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)
168 return self
169
170 callable_obj, *args = args
90 try: 171 try:
91 func(*args, **kwargs) 172 self.obj_name = callable_obj.__name__
92 except Exception: 173 except AttributeError:
93 raise _ExpectedFailure(sys.exc_info()) 174 self.obj_name = str(callable_obj)
94 raise _UnexpectedSuccess 175 with self:
95 return wrapper 176 callable_obj(*args, **kwargs)
96 177
97 def _ensure_is_exception_type(e): 178
98 if isinstance(e, types.ClassType): 179 class _AssertRaisesContext(_AssertRaisesBaseContext):
99 return
ezio.melotti 2014/06/29 11:24:12 If this is to support exceptions that are not deri
100 if not isinstance(e, type) or not issubclass(e, BaseException):
101 raise TypeError('assertRaises arg 1 must be an exception type '
102 'or tuple of exception types')
103
104
105 class _AssertRaisesContext(object):
106 """A context manager used to implement TestCase.assertRaises* methods.""" 180 """A context manager used to implement TestCase.assertRaises* methods."""
107 181
108 def __init__(self, expected, test_case, expected_regexp=None): 182 _base_type = BaseException
109 self.expected = expected 183 _base_type_str = 'an exception type or tuple of exception types'
110
111 if type(expected) is tuple:
Claudiu.Popa 2014/06/14 17:01:42 You could use isinstance here.
112 for e in expected:
113 _ensure_is_exception_type(e)
114 else:
115 _ensure_is_exception_type(expected)
116
117 self.failureException = test_case.failureException
118 self.expected_regexp = expected_regexp
119 184
120 def __enter__(self): 185 def __enter__(self):
121 return self 186 return self
122 187
123 def __exit__(self, exc_type, exc_value, tb): 188 def __exit__(self, exc_type, exc_value, tb):
124 if exc_type is None: 189 if exc_type is None:
125 try: 190 try:
126 exc_name = self.expected.__name__ 191 exc_name = self.expected.__name__
127 except AttributeError: 192 except AttributeError:
128 exc_name = str(self.expected) 193 exc_name = str(self.expected)
129 raise self.failureException( 194 if self.obj_name:
130 "{0} not raised".format(exc_name)) 195 self._raiseFailure("{} not raised by {}".format(exc_name,
196 self.obj_name))
197 else:
198 self._raiseFailure("{} not raised".format(exc_name))
199 else:
200 traceback.clear_frames(tb)
131 if not issubclass(exc_type, self.expected): 201 if not issubclass(exc_type, self.expected):
132 # let unexpected exceptions pass through 202 # let unexpected exceptions pass through
133 return False 203 return False
134 self.exception = exc_value # store for later retrieval 204 # store exception, without traceback, for later retrieval
135 if self.expected_regexp is None: 205 self.exception = exc_value.with_traceback(None)
206 if self.expected_regex is None:
136 return True 207 return True
137 208
138 expected_regexp = self.expected_regexp 209 expected_regex = self.expected_regex
139 if isinstance(expected_regexp, basestring): 210 if not expected_regex.search(str(exc_value)):
140 expected_regexp = re.compile(expected_regexp) 211 self._raiseFailure('"{}" does not match "{}"'.format(
141 if not expected_regexp.search(str(exc_value)): 212 expected_regex.pattern, str(exc_value)))
142 raise self.failureException('"%s" does not match "%s"' %
143 (expected_regexp.pattern, str(exc_value)))
144 return True 213 return True
214
215
216 class _AssertWarnsContext(_AssertRaisesBaseContext):
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'
221
222 def __enter__(self):
223 # The __warningregistry__'s need to be in a pristine state for tests
224 # to work properly.
225 for v in sys.modules.values():
226 if getattr(v, '__warningregistry__', None):
227 v.__warningregistry__ = {}
228 self.warnings_manager = warnings.catch_warnings(record=True)
229 self.warnings = self.warnings_manager.__enter__()
230 warnings.simplefilter("always", self.expected)
231 return self
232
233 def __exit__(self, exc_type, exc_value, tb):
234 self.warnings_manager.__exit__(exc_type, exc_value, tb)
235 if exc_type is not None:
236 # let unexpected exceptions pass through
237 return
238 try:
239 exc_name = self.expected.__name__
240 except AttributeError:
241 exc_name = str(self.expected)
242 first_matching = None
243 for m in self.warnings:
244 w = m.message
245 if not isinstance(w, self.expected):
246 continue
247 if first_matching is None:
248 first_matching = w
249 if (self.expected_regex is not None and
250 not self.expected_regex.search(str(w))):
251 continue
252 # store warning for later retrieval
253 self.warning = w
254 self.filename = m.filename
255 self.lineno = m.lineno
256 return
257 # Now we simply try to choose a helpful failure message
258 if first_matching is not None:
259 self._raiseFailure('"{}" does not match "{}"'.format(
260 self.expected_regex.pattern, str(first_matching)))
261 if self.obj_name:
262 self._raiseFailure("{} not triggered by {}".format(exc_name,
263 self.obj_name))
264 else:
265 self._raiseFailure("{} not triggered".format(exc_name))
266
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))
145 334
146 335
147 class TestCase(object): 336 class TestCase(object):
148 """A class whose instances are single test cases. 337 """A class whose instances are single test cases.
149 338
150 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
151 'runTest'. 340 'runTest'.
152 341
153 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
154 many test methods as are needed. When instantiating such a TestCase 343 many test methods as are needed. When instantiating such a TestCase
155 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
156 that the instance is to execute. 345 that the instance is to execute.
157 346
158 Test authors should subclass TestCase for their own tests. Construction 347 Test authors should subclass TestCase for their own tests. Construction
159 and deconstruction of the test's environment ('fixture') can be 348 and deconstruction of the test's environment ('fixture') can be
160 implemented by overriding the 'setUp' and 'tearDown' methods respectively. 349 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
161 350
162 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
163 __init__ method must always be called. It is important that subclasses 352 __init__ method must always be called. It is important that subclasses
164 should not change the signature of their __init__ method, since instances 353 should not change the signature of their __init__ method, since instances
165 of the classes are instantiated automatically by parts of the framework 354 of the classes are instantiated automatically by parts of the framework
166 in order to be run. 355 in order to be run.
167 """ 356
168 357 When subclassing TestCase, you can set these attributes:
169 # This attribute determines which exception will be raised when 358 * failureException: determines which exception will be raised when
170 # the instance's assertion methods fail; test methods raising this 359 the instance's assertion methods fail; test methods raising this
171 # 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 """
172 368
173 failureException = AssertionError 369 failureException = AssertionError
174 370
175 # This attribute determines whether long messages (including repr of 371 longMessage = True
176 # objects used in assert methods) will be printed on failure in *addition*
177 # to any explicit message passed.
178
179 longMessage = False
180
181 # This attribute sets the maximum length of a diff in failure messages
182 # by assert methods using difflib. It is looked up as an instance attribute
183 # so can be configured by individual tests if required.
184 372
185 maxDiff = 80*8 373 maxDiff = 80*8
186 374
187 # If a string is longer than _diffThreshold, use normal comparison instead 375 # If a string is longer than _diffThreshold, use normal comparison instead
188 # of difflib. See #11763. 376 # of difflib. See #11763.
189 _diffThreshold = 2**16 377 _diffThreshold = 2**16
190 378
191 # Attribute used by TestSuite for classSetUp 379 # Attribute used by TestSuite for classSetUp
192 380
193 _classSetupFailed = False 381 _classSetupFailed = False
194 382
195 def __init__(self, methodName='runTest'): 383 def __init__(self, methodName='runTest'):
196 """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
197 method when executed. Raises a ValueError if the instance does 385 method when executed. Raises a ValueError if the instance does
198 not have a method with the specified name. 386 not have a method with the specified name.
199 """ 387 """
200 self._testMethodName = methodName 388 self._testMethodName = methodName
201 self._resultForDoCleanups = None 389 self._outcome = None
390 self._testMethodDoc = 'No test'
202 try: 391 try:
203 testMethod = getattr(self, methodName) 392 testMethod = getattr(self, methodName)
204 except AttributeError: 393 except AttributeError:
205 raise ValueError("no such test method in %s: %s" % 394 if methodName != 'runTest':
206 (self.__class__, methodName)) 395 # we allow instantiation with no explicit method name
207 self._testMethodDoc = testMethod.__doc__ 396 # but not an *incorrect* or missing method name
397 raise ValueError("no such test method in %s: %s" %
398 (self.__class__, methodName))
399 else:
400 self._testMethodDoc = testMethod.__doc__
208 self._cleanups = [] 401 self._cleanups = []
402 self._subtest = None
209 403
210 # Map types to custom assertEqual functions that will compare 404 # Map types to custom assertEqual functions that will compare
211 # 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
212 # error message. 406 # error message.
213 self._type_equality_funcs = {} 407 self._type_equality_funcs = {}
214 self.addTypeEqualityFunc(dict, 'assertDictEqual') 408 self.addTypeEqualityFunc(dict, 'assertDictEqual')
215 self.addTypeEqualityFunc(list, 'assertListEqual') 409 self.addTypeEqualityFunc(list, 'assertListEqual')
216 self.addTypeEqualityFunc(tuple, 'assertTupleEqual') 410 self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
217 self.addTypeEqualityFunc(set, 'assertSetEqual') 411 self.addTypeEqualityFunc(set, 'assertSetEqual')
218 self.addTypeEqualityFunc(frozenset, 'assertSetEqual') 412 self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
219 try: 413 self.addTypeEqualityFunc(str, 'assertMultiLineEqual')
220 self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
221 except NameError:
222 # No unicode support in this build
223 pass
224 414
225 def addTypeEqualityFunc(self, typeobj, function): 415 def addTypeEqualityFunc(self, typeobj, function):
226 """Add a type specific assertEqual style function to compare a type. 416 """Add a type specific assertEqual style function to compare a type.
227 417
228 This method is for use by TestCase subclasses that need to register 418 This method is for use by TestCase subclasses that need to register
229 their own type equality functions to provide nicer error messages. 419 their own type equality functions to provide nicer error messages.
230 420
231 Args: 421 Args:
232 typeobj: The data type to call this function on when both values 422 typeobj: The data type to call this function on when both values
233 are of the same type in assertEqual(). 423 are of the same type in assertEqual().
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 470
281 def id(self): 471 def id(self):
282 return "%s.%s" % (strclass(self.__class__), self._testMethodName) 472 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
283 473
284 def __eq__(self, other): 474 def __eq__(self, other):
285 if type(self) is not type(other): 475 if type(self) is not type(other):
286 return NotImplemented 476 return NotImplemented
287 477
288 return self._testMethodName == other._testMethodName 478 return self._testMethodName == other._testMethodName
289 479
290 def __ne__(self, other):
291 return not self == other
292
293 def __hash__(self): 480 def __hash__(self):
294 return hash((type(self), self._testMethodName)) 481 return hash((type(self), self._testMethodName))
295 482
296 def __str__(self): 483 def __str__(self):
297 return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) 484 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
298 485
299 def __repr__(self): 486 def __repr__(self):
300 return "<%s testMethod=%s>" % \ 487 return "<%s testMethod=%s>" % \
301 (strclass(self.__class__), self._testMethodName) 488 (strclass(self.__class__), self._testMethodName)
302 489
303 def _addSkip(self, result, reason): 490 def _addSkip(self, result, test_case, reason):
304 addSkip = getattr(result, 'addSkip', None) 491 addSkip = getattr(result, 'addSkip', None)
305 if addSkip is not None: 492 if addSkip is not None:
306 addSkip(self, reason) 493 addSkip(test_case, reason)
307 else: 494 else:
308 warnings.warn("TestResult has no addSkip method, skips not reported" , 495 warnings.warn("TestResult has no addSkip method, skips not reported" ,
309 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)
310 result.addSuccess(self) 546 result.addSuccess(self)
547 else:
548 addExpectedFailure(self, exc_info)
549
550 def _addUnexpectedSuccess(self, result):
551 try:
552 addUnexpectedSuccess = result.addUnexpectedSuccess
553 except AttributeError:
554 warnings.warn("TestResult has no addUnexpectedSuccess method, report ing as failure",
555 RuntimeWarning)
556 # We need to pass an actual exception and traceback to addFailure,
557 # otherwise the legacy result can choke.
558 try:
559 raise _UnexpectedSuccess from None
560 except _UnexpectedSuccess:
561 result.addFailure(self, sys.exc_info())
562 else:
563 addUnexpectedSuccess(self)
311 564
312 def run(self, result=None): 565 def run(self, result=None):
313 orig_result = result 566 orig_result = result
314 if result is None: 567 if result is None:
315 result = self.defaultTestResult() 568 result = self.defaultTestResult()
316 startTestRun = getattr(result, 'startTestRun', None) 569 startTestRun = getattr(result, 'startTestRun', None)
317 if startTestRun is not None: 570 if startTestRun is not None:
318 startTestRun() 571 startTestRun()
319 572
320 self._resultForDoCleanups = result
321 result.startTest(self) 573 result.startTest(self)
322 574
323 testMethod = getattr(self, self._testMethodName) 575 testMethod = getattr(self, self._testMethodName)
324 if (getattr(self.__class__, "__unittest_skip__", False) or 576 if (getattr(self.__class__, "__unittest_skip__", False) or
325 getattr(testMethod, "__unittest_skip__", False)): 577 getattr(testMethod, "__unittest_skip__", False)):
326 # If the class or method was skipped. 578 # If the class or method was skipped.
327 try: 579 try:
328 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') 580 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
329 or getattr(testMethod, '__unittest_skip_why__', '')) 581 or getattr(testMethod, '__unittest_skip_why__', ''))
330 self._addSkip(result, skip_why) 582 self._addSkip(result, self, skip_why)
331 finally: 583 finally:
332 result.stopTest(self) 584 result.stopTest(self)
333 return 585 return
586 expecting_failure = getattr(testMethod,
587 "__unittest_expecting_failure__", False)
588 outcome = _Outcome(result)
334 try: 589 try:
335 success = False 590 self._outcome = outcome
336 try: 591
592 with outcome.testPartExecutor(self):
337 self.setUp() 593 self.setUp()
338 except SkipTest as e: 594 if outcome.success:
339 self._addSkip(result, str(e)) 595 outcome.expecting_failure = expecting_failure
340 except KeyboardInterrupt: 596 with outcome.testPartExecutor(self, isTest=True):
341 raise
342 except:
343 result.addError(self, sys.exc_info())
344 else:
345 try:
346 testMethod() 597 testMethod()
347 except KeyboardInterrupt: 598 outcome.expecting_failure = False
348 raise 599 with outcome.testPartExecutor(self):
349 except self.failureException: 600 self.tearDown()
350 result.addFailure(self, sys.exc_info()) 601
351 except _ExpectedFailure as e: 602 self.doCleanups()
352 addExpectedFailure = getattr(result, 'addExpectedFailure', N one) 603 for test, reason in outcome.skipped:
353 if addExpectedFailure is not None: 604 self._addSkip(result, test, reason)
354 addExpectedFailure(self, e.exc_info) 605 self._feedErrorsToResult(result, outcome.errors)
606 if outcome.success:
607 if expecting_failure:
608 if outcome.expectedFailure:
609 self._addExpectedFailure(result, outcome.expectedFailure )
355 else: 610 else:
356 warnings.warn("TestResult has no addExpectedFailure meth od, reporting as passes", 611 self._addUnexpectedSuccess(result)
357 RuntimeWarning)
358 result.addSuccess(self)
359 except _UnexpectedSuccess:
360 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess ', None)
361 if addUnexpectedSuccess is not None:
362 addUnexpectedSuccess(self)
363 else:
364 warnings.warn("TestResult has no addUnexpectedSuccess me thod, reporting as failures",
365 RuntimeWarning)
366 result.addFailure(self, sys.exc_info())
367 except SkipTest as e:
368 self._addSkip(result, str(e))
369 except:
370 result.addError(self, sys.exc_info())
371 else: 612 else:
372 success = True 613 result.addSuccess(self)
373 614 return result
374 try:
375 self.tearDown()
376 except KeyboardInterrupt:
377 raise
378 except:
379 result.addError(self, sys.exc_info())
380 success = False
381
382 cleanUpSuccess = self.doCleanups()
383 success = success and cleanUpSuccess
384 if success:
385 result.addSuccess(self)
386 finally: 615 finally:
387 result.stopTest(self) 616 result.stopTest(self)
388 if orig_result is None: 617 if orig_result is None:
389 stopTestRun = getattr(result, 'stopTestRun', None) 618 stopTestRun = getattr(result, 'stopTestRun', None)
390 if stopTestRun is not None: 619 if stopTestRun is not None:
391 stopTestRun() 620 stopTestRun()
392 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
393 def doCleanups(self): 631 def doCleanups(self):
394 """Execute all cleanup functions. Normally called for you after 632 """Execute all cleanup functions. Normally called for you after
395 tearDown.""" 633 tearDown."""
396 result = self._resultForDoCleanups 634 outcome = self._outcome or _Outcome()
397 ok = True
398 while self._cleanups: 635 while self._cleanups:
399 function, args, kwargs = self._cleanups.pop(-1) 636 function, args, kwargs = self._cleanups.pop()
400 try: 637 with outcome.testPartExecutor(self):
401 function(*args, **kwargs) 638 function(*args, **kwargs)
402 except KeyboardInterrupt: 639
403 raise 640 # return this for backwards compatibility
404 except: 641 # even though we no longer us it internally
405 ok = False 642 return outcome.success
406 result.addError(self, sys.exc_info())
407 return ok
408 643
409 def __call__(self, *args, **kwds): 644 def __call__(self, *args, **kwds):
410 return self.run(*args, **kwds) 645 return self.run(*args, **kwds)
411 646
412 def debug(self): 647 def debug(self):
413 """Run the test without collecting errors in a TestResult""" 648 """Run the test without collecting errors in a TestResult"""
414 self.setUp() 649 self.setUp()
415 getattr(self, self._testMethodName)() 650 getattr(self, self._testMethodName)()
416 self.tearDown() 651 self.tearDown()
417 while self._cleanups: 652 while self._cleanups:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 return msg or standardMsg 687 return msg or standardMsg
453 if msg is None: 688 if msg is None:
454 return standardMsg 689 return standardMsg
455 try: 690 try:
456 # don't switch to '{}' formatting in Python 2.X 691 # don't switch to '{}' formatting in Python 2.X
457 # it changes the way unicode input is handled 692 # it changes the way unicode input is handled
458 return '%s : %s' % (standardMsg, msg) 693 return '%s : %s' % (standardMsg, msg)
459 except UnicodeDecodeError: 694 except UnicodeDecodeError:
460 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) 695 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
461 696
462 697 def assertRaises(self, expected_exception, *args, **kwargs):
463 def assertRaises(self, excClass, callableObj=None, *args, **kwargs): 698 """Fail unless an exception of class expected_exception is raised
464 """Fail unless an exception of class excClass is thrown 699 by the callable when invoked with specified positional and
465 by callableObj when invoked with arguments args and keyword 700 keyword arguments. If a different type of exception is
466 arguments kwargs. If a different type of exception is 701 raised, it will not be caught, and the test case will be
467 thrown, it will not be caught, and the test case will be
468 deemed to have suffered an error, exactly as for an 702 deemed to have suffered an error, exactly as for an
469 unexpected exception. 703 unexpected exception.
470 704
471 If called with callableObj omitted or None, will return a 705 If called with the callable and arguments omitted, will return a
472 context object used like this:: 706 context object used like this::
473 707
474 with self.assertRaises(SomeException): 708 with self.assertRaises(SomeException):
475 do_something() 709 do_something()
710
711 An optional keyword argument 'msg' can be provided when assertRaises
712 is used as a context object.
476 713
477 The context manager keeps a reference to the exception as 714 The context manager keeps a reference to the exception as
478 the 'exception' attribute. This allows you to inspect the 715 the 'exception' attribute. This allows you to inspect the
479 exception after the assertion:: 716 exception after the assertion::
480 717
481 with self.assertRaises(SomeException) as cm: 718 with self.assertRaises(SomeException) as cm:
482 do_something() 719 do_something()
483 the_exception = cm.exception 720 the_exception = cm.exception
484 self.assertEqual(the_exception.error_code, 3) 721 self.assertEqual(the_exception.error_code, 3)
485 """ 722 """
486 context = _AssertRaisesContext(excClass, self) 723 context = _AssertRaisesContext(expected_exception, self)
487 if callableObj is None: 724 return context.handle('assertRaises', args, kwargs)
488 return context 725
489 with context: 726 def assertWarns(self, expected_warning, *args, **kwargs):
490 callableObj(*args, **kwargs) 727 """Fail unless a warning of class warnClass is triggered
728 by the callable when invoked with specified positional and
729 keyword arguments. If a different type of warning is
730 triggered, it will not be handled: depending on the other
731 warning filtering rules in effect, it might be silenced, printed
732 out, or raised as an exception.
733
734 If called with the callable and arguments omitted, will return a
735 context object used like this::
736
737 with self.assertWarns(SomeWarning):
738 do_something()
739
740 An optional keyword argument 'msg' can be provided when assertWarns
741 is used as a context object.
742
743 The context manager keeps a reference to the first matching
744 warning as the 'warning' attribute; similarly, the 'filename'
745 and 'lineno' attributes give you information about the line
746 of Python code from which the warning was triggered.
747 This allows you to inspect the warning after the assertion::
748
749 with self.assertWarns(SomeWarning) as cm:
750 do_something()
751 the_warning = cm.warning
752 self.assertEqual(the_warning.some_attribute, 147)
753 """
754 context = _AssertWarnsContext(expected_warning, self)
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)
491 778
492 def _getAssertEqualityFunc(self, first, second): 779 def _getAssertEqualityFunc(self, first, second):
493 """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.
494 781
495 Returns: A callable accepting (first, second, msg=None) that will 782 Returns: A callable accepting (first, second, msg=None) that will
496 raise a failure exception if first != second with a useful human 783 raise a failure exception if first != second with a useful human
497 readable error message for those types. 784 readable error message for those types.
498 """ 785 """
499 # 786 #
500 # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) 787 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
501 # and vice versa. I opted for the conservative approach in case 788 # and vice versa. I opted for the conservative approach in case
502 # subclasses are not intended to be compared in detail to their super 789 # subclasses are not intended to be compared in detail to their super
503 # class instances using a type equality func. This means testing 790 # class instances using a type equality func. This means testing
504 # subtypes won't automagically use the detailed comparison. Callers 791 # subtypes won't automagically use the detailed comparison. Callers
505 # should use their type specific assertSpamEqual method to compare 792 # should use their type specific assertSpamEqual method to compare
506 # subclasses if the detailed comparison is desired and appropriate. 793 # subclasses if the detailed comparison is desired and appropriate.
507 # See the discussion in http://bugs.python.org/issue2578. 794 # See the discussion in http://bugs.python.org/issue2578.
508 # 795 #
509 if type(first) is type(second): 796 if type(first) is type(second):
510 asserter = self._type_equality_funcs.get(type(first)) 797 asserter = self._type_equality_funcs.get(type(first))
511 if asserter is not None: 798 if asserter is not None:
512 if isinstance(asserter, basestring): 799 if isinstance(asserter, str):
513 asserter = getattr(self, asserter) 800 asserter = getattr(self, asserter)
514 return asserter 801 return asserter
515 802
516 return self._baseAssertEqual 803 return self._baseAssertEqual
517 804
518 def _baseAssertEqual(self, first, second, msg=None): 805 def _baseAssertEqual(self, first, second, msg=None):
519 """The default assertEqual implementation, not type specific.""" 806 """The default assertEqual implementation, not type specific."""
520 if not first == second: 807 if not first == second:
521 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second)) 808 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
522 msg = self._formatMessage(msg, standardMsg) 809 msg = self._formatMessage(msg, standardMsg)
523 raise self.failureException(msg) 810 raise self.failureException(msg)
524 811
525 def assertEqual(self, first, second, msg=None): 812 def assertEqual(self, first, second, msg=None):
526 """Fail if the two objects are unequal as determined by the '==' 813 """Fail if the two objects are unequal as determined by the '=='
527 operator. 814 operator.
528 """ 815 """
529 assertion_func = self._getAssertEqualityFunc(first, second) 816 assertion_func = self._getAssertEqualityFunc(first, second)
530 assertion_func(first, second, msg=msg) 817 assertion_func(first, second, msg=msg)
531 818
532 def assertNotEqual(self, first, second, msg=None): 819 def assertNotEqual(self, first, second, msg=None):
533 """Fail if the two objects are equal as determined by the '==' 820 """Fail if the two objects are equal as determined by the '!='
534 operator. 821 operator.
535 """ 822 """
536 if not first != second: 823 if not first != second:
537 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), 824 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
538 safe_repr(second))) 825 safe_repr(second)))
539 raise self.failureException(msg) 826 raise self.failureException(msg)
540 827
541 828 def assertAlmostEqual(self, first, second, places=None, msg=None,
542 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None ): 829 delta=None):
543 """Fail if the two objects are unequal as determined by their 830 """Fail if the two objects are unequal as determined by their
544 difference rounded to the given number of decimal places 831 difference rounded to the given number of decimal places
545 (default 7) and comparing to zero, or by comparing that the 832 (default 7) and comparing to zero, or by comparing that the
546 between the two objects is more than the given delta. 833 between the two objects is more than the given delta.
547 834
548 Note that decimal places (from zero) are usually not the same 835 Note that decimal places (from zero) are usually not the same
549 as significant digits (measured from the most signficant digit). 836 as significant digits (measured from the most signficant digit).
550 837
551 If the two objects compare equal then they will automatically 838 If the two objects compare equal then they will automatically
552 compare almost equal. 839 compare almost equal.
(...skipping 17 matching lines...) Expand all
570 857
571 if round(abs(second-first), places) == 0: 858 if round(abs(second-first), places) == 0:
572 return 859 return
573 860
574 standardMsg = '%s != %s within %r places' % (safe_repr(first), 861 standardMsg = '%s != %s within %r places' % (safe_repr(first),
575 safe_repr(second), 862 safe_repr(second),
576 places) 863 places)
577 msg = self._formatMessage(msg, standardMsg) 864 msg = self._formatMessage(msg, standardMsg)
578 raise self.failureException(msg) 865 raise self.failureException(msg)
579 866
580 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=N one): 867 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
868 delta=None):
581 """Fail if the two objects are equal as determined by their 869 """Fail if the two objects are equal as determined by their
582 difference rounded to the given number of decimal places 870 difference rounded to the given number of decimal places
583 (default 7) and comparing to zero, or by comparing that the 871 (default 7) and comparing to zero, or by comparing that the
584 between the two objects is less than the given delta. 872 between the two objects is less than the given delta.
585 873
586 Note that decimal places (from zero) are usually not the same 874 Note that decimal places (from zero) are usually not the same
587 as significant digits (measured from the most signficant digit). 875 as significant digits (measured from the most signficant digit).
588 876
589 Objects that are equal automatically fail. 877 Objects that are equal automatically fail.
590 """ 878 """
(...skipping 10 matching lines...) Expand all
601 places = 7 889 places = 7
602 if not (first == second) and round(abs(second-first), places) != 0: 890 if not (first == second) and round(abs(second-first), places) != 0:
603 return 891 return
604 standardMsg = '%s == %s within %r places' % (safe_repr(first), 892 standardMsg = '%s == %s within %r places' % (safe_repr(first),
605 safe_repr(second), 893 safe_repr(second),
606 places) 894 places)
607 895
608 msg = self._formatMessage(msg, standardMsg) 896 msg = self._formatMessage(msg, standardMsg)
609 raise self.failureException(msg) 897 raise self.failureException(msg)
610 898
611 # Synonyms for assertion methods
612
613 # The plurals are undocumented. Keep them that way to discourage use.
614 # Do not add more. Do not remove.
615 # Going through a deprecation cycle on these would annoy many people.
616 assertEquals = assertEqual
617 assertNotEquals = assertNotEqual
618 assertAlmostEquals = assertAlmostEqual
619 assertNotAlmostEquals = assertNotAlmostEqual
620 assert_ = assertTrue
621
622 # These fail* assertion method names are pending deprecation and will
623 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
624 def _deprecate(original_func):
625 def deprecated_func(*args, **kwargs):
626 warnings.warn(
627 'Please use {0} instead.'.format(original_func.__name__),
628 PendingDeprecationWarning, 2)
629 return original_func(*args, **kwargs)
630 return deprecated_func
631
632 failUnlessEqual = _deprecate(assertEqual)
633 failIfEqual = _deprecate(assertNotEqual)
634 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
635 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
636 failUnless = _deprecate(assertTrue)
637 failUnlessRaises = _deprecate(assertRaises)
638 failIf = _deprecate(assertFalse)
639 899
640 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): 900 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
641 """An equality assertion for ordered sequences (like lists and tuples). 901 """An equality assertion for ordered sequences (like lists and tuples).
642 902
643 For the purposes of this function, a valid ordered sequence type is one 903 For the purposes of this function, a valid ordered sequence type is one
644 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.
645 905
646 Args: 906 Args:
647 seq1: The first sequence to compare. 907 seq1: The first sequence to compare.
648 seq2: The second sequence to compare. 908 seq2: The second sequence to compare.
(...skipping 24 matching lines...) Expand all
673 try: 933 try:
674 len2 = len(seq2) 934 len2 = len(seq2)
675 except (TypeError, NotImplementedError): 935 except (TypeError, NotImplementedError):
676 differing = 'Second %s has no length. Non-sequence?' % ( 936 differing = 'Second %s has no length. Non-sequence?' % (
677 seq_type_name) 937 seq_type_name)
678 938
679 if differing is None: 939 if differing is None:
680 if seq1 == seq2: 940 if seq1 == seq2:
681 return 941 return
682 942
683 seq1_repr = safe_repr(seq1) 943 differing = '%ss differ: %s != %s\n' % (
684 seq2_repr = safe_repr(seq2) 944 (seq_type_name.capitalize(),) +
685 if len(seq1_repr) > 30: 945 _common_shorten_repr(seq1, seq2))
686 seq1_repr = seq1_repr[:30] + '...' 946
687 if len(seq2_repr) > 30: 947 for i in range(min(len1, len2)):
688 seq2_repr = seq2_repr[:30] + '...'
689 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
690 differing = '%ss differ: %s != %s\n' % elements
691
692 for i in xrange(min(len1, len2)):
693 try: 948 try:
694 item1 = seq1[i] 949 item1 = seq1[i]
695 except (TypeError, IndexError, NotImplementedError): 950 except (TypeError, IndexError, NotImplementedError):
696 differing += ('\nUnable to index element %d of first %s\n' % 951 differing += ('\nUnable to index element %d of first %s\n' %
697 (i, seq_type_name)) 952 (i, seq_type_name))
698 break 953 break
699 954
700 try: 955 try:
701 item2 = seq2[i] 956 item2 = seq2[i]
702 except (TypeError, IndexError, NotImplementedError): 957 except (TypeError, IndexError, NotImplementedError):
(...skipping 26 matching lines...) Expand all
729 try: 984 try:
730 differing += ('First extra element %d:\n%s\n' % 985 differing += ('First extra element %d:\n%s\n' %
731 (len1, seq2[len1])) 986 (len1, seq2[len1]))
732 except (TypeError, IndexError, NotImplementedError): 987 except (TypeError, IndexError, NotImplementedError):
733 differing += ('Unable to index element %d ' 988 differing += ('Unable to index element %d '
734 'of second %s\n' % (len1, seq_type_name)) 989 'of second %s\n' % (len1, seq_type_name))
735 standardMsg = differing 990 standardMsg = differing
736 diffMsg = '\n' + '\n'.join( 991 diffMsg = '\n' + '\n'.join(
737 difflib.ndiff(pprint.pformat(seq1).splitlines(), 992 difflib.ndiff(pprint.pformat(seq1).splitlines(),
738 pprint.pformat(seq2).splitlines())) 993 pprint.pformat(seq2).splitlines()))
994
739 standardMsg = self._truncateMessage(standardMsg, diffMsg) 995 standardMsg = self._truncateMessage(standardMsg, diffMsg)
740 msg = self._formatMessage(msg, standardMsg) 996 msg = self._formatMessage(msg, standardMsg)
741 self.fail(msg) 997 self.fail(msg)
742 998
743 def _truncateMessage(self, message, diff): 999 def _truncateMessage(self, message, diff):
744 max_diff = self.maxDiff 1000 max_diff = self.maxDiff
745 if max_diff is None or len(diff) <= max_diff: 1001 if max_diff is None or len(diff) <= max_diff:
746 return message + diff 1002 return message + diff
747 return message + (DIFF_OMITTED % len(diff)) 1003 return message + (DIFF_OMITTED % len(diff))
748 1004
(...skipping 28 matching lines...) Expand all
777 set2: The second set to compare. 1033 set2: The second set to compare.
778 msg: Optional message to use on failure instead of a list of 1034 msg: Optional message to use on failure instead of a list of
779 differences. 1035 differences.
780 1036
781 assertSetEqual uses ducktyping to support different types of sets, and 1037 assertSetEqual uses ducktyping to support different types of sets, and
782 is optimized for sets specifically (parameters must support a 1038 is optimized for sets specifically (parameters must support a
783 difference method). 1039 difference method).
784 """ 1040 """
785 try: 1041 try:
786 difference1 = set1.difference(set2) 1042 difference1 = set1.difference(set2)
787 except TypeError, e: 1043 except TypeError as e:
788 self.fail('invalid type when attempting set difference: %s' % e) 1044 self.fail('invalid type when attempting set difference: %s' % e)
789 except AttributeError, e: 1045 except AttributeError as e:
790 self.fail('first argument does not support set difference: %s' % e) 1046 self.fail('first argument does not support set difference: %s' % e)
791 1047
792 try: 1048 try:
793 difference2 = set2.difference(set1) 1049 difference2 = set2.difference(set1)
794 except TypeError, e: 1050 except TypeError as e:
795 self.fail('invalid type when attempting set difference: %s' % e) 1051 self.fail('invalid type when attempting set difference: %s' % e)
796 except AttributeError, e: 1052 except AttributeError as e:
797 self.fail('second argument does not support set difference: %s' % e) 1053 self.fail('second argument does not support set difference: %s' % e)
798 1054
799 if not (difference1 or difference2): 1055 if not (difference1 or difference2):
800 return 1056 return
801 1057
802 lines = [] 1058 lines = []
803 if difference1: 1059 if difference1:
804 lines.append('Items in the first set but not the second:') 1060 lines.append('Items in the first set but not the second:')
805 for item in difference1: 1061 for item in difference1:
806 lines.append(repr(item)) 1062 lines.append(repr(item))
(...skipping 30 matching lines...) Expand all
837 """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."""
838 if expr1 is expr2: 1094 if expr1 is expr2:
839 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) 1095 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
840 self.fail(self._formatMessage(msg, standardMsg)) 1096 self.fail(self._formatMessage(msg, standardMsg))
841 1097
842 def assertDictEqual(self, d1, d2, msg=None): 1098 def assertDictEqual(self, d1, d2, msg=None):
843 self.assertIsInstance(d1, dict, 'First argument is not a dictionary') 1099 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
844 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') 1100 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
845 1101
846 if d1 != d2: 1102 if d1 != d2:
847 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True) ) 1103 standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
848 diff = ('\n' + '\n'.join(difflib.ndiff( 1104 diff = ('\n' + '\n'.join(difflib.ndiff(
849 pprint.pformat(d1).splitlines(), 1105 pprint.pformat(d1).splitlines(),
850 pprint.pformat(d2).splitlines()))) 1106 pprint.pformat(d2).splitlines())))
851 standardMsg = self._truncateMessage(standardMsg, diff) 1107 standardMsg = self._truncateMessage(standardMsg, diff)
852 self.fail(self._formatMessage(msg, standardMsg)) 1108 self.fail(self._formatMessage(msg, standardMsg))
853 1109
854 def assertDictContainsSubset(self, expected, actual, msg=None): 1110 def assertDictContainsSubset(self, subset, dictionary, msg=None):
855 """Checks whether actual is a superset of expected.""" 1111 """Checks whether dictionary is a superset of subset."""
1112 warnings.warn('assertDictContainsSubset is deprecated',
1113 DeprecationWarning)
856 missing = [] 1114 missing = []
857 mismatched = [] 1115 mismatched = []
858 for key, value in expected.iteritems(): 1116 for key, value in subset.items():
859 if key not in actual: 1117 if key not in dictionary:
860 missing.append(key) 1118 missing.append(key)
861 elif value != actual[key]: 1119 elif value != dictionary[key]:
862 mismatched.append('%s, expected: %s, actual: %s' % 1120 mismatched.append('%s, expected: %s, actual: %s' %
863 (safe_repr(key), safe_repr(value), 1121 (safe_repr(key), safe_repr(value),
864 safe_repr(actual[key]))) 1122 safe_repr(dictionary[key])))
865 1123
866 if not (missing or mismatched): 1124 if not (missing or mismatched):
867 return 1125 return
868 1126
869 standardMsg = '' 1127 standardMsg = ''
870 if missing: 1128 if missing:
871 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in 1129 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
872 missing) 1130 missing)
873 if mismatched: 1131 if mismatched:
874 if standardMsg: 1132 if standardMsg:
875 standardMsg += '; ' 1133 standardMsg += '; '
876 standardMsg += 'Mismatched values: %s' % ','.join(mismatched) 1134 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
877 1135
878 self.fail(self._formatMessage(msg, standardMsg)) 1136 self.fail(self._formatMessage(msg, standardMsg))
879 1137
880 def assertItemsEqual(self, expected_seq, actual_seq, msg=None): 1138
881 """An unordered sequence specific comparison. It asserts that 1139 def assertCountEqual(self, first, second, msg=None):
882 actual_seq and expected_seq have the same element counts. 1140 """An unordered sequence comparison asserting that the same elements,
883 Equivalent to:: 1141 regardless of order. If the same element occurs more than once,
884 1142 it verifies that the elements occur the same number of times.
885 self.assertEqual(Counter(iter(actual_seq)), 1143
886 Counter(iter(expected_seq))) 1144 self.assertEqual(Counter(list(first)),
887 1145 Counter(list(second)))
888 Asserts that each element has the same count in both sequences. 1146
889 Example: 1147 Example:
890 - [0, 1, 1] and [1, 0, 1] compare equal. 1148 - [0, 1, 1] and [1, 0, 1] compare equal.
891 - [0, 0, 1] and [0, 1] compare unequal. 1149 - [0, 0, 1] and [0, 1] compare unequal.
892 """ 1150
893 first_seq, second_seq = list(expected_seq), list(actual_seq) 1151 """
894 with warnings.catch_warnings(): 1152 first_seq, second_seq = list(first), list(second)
895 if sys.py3kwarning: 1153 try:
896 # Silence Py3k warning raised during the sorting 1154 first = collections.Counter(first_seq)
897 for _msg in ["(code|dict|type) inequality comparisons", 1155 second = collections.Counter(second_seq)
898 "builtin_function_or_method order comparisons", 1156 except TypeError:
899 "comparing unequal types"]: 1157 # Handle case with unhashable elements
900 warnings.filterwarnings("ignore", _msg, DeprecationWarning) 1158 differences = _count_diff_all_purpose(first_seq, second_seq)
901 try: 1159 else:
902 first = collections.Counter(first_seq) 1160 if first == second:
903 second = collections.Counter(second_seq) 1161 return
904 except TypeError: 1162 differences = _count_diff_hashable(first_seq, second_seq)
905 # Handle case with unhashable elements
906 differences = _count_diff_all_purpose(first_seq, second_seq)
907 else:
908 if first == second:
909 return
910 differences = _count_diff_hashable(first_seq, second_seq)
911 1163
912 if differences: 1164 if differences:
913 standardMsg = 'Element counts were not equal:\n' 1165 standardMsg = 'Element counts were not equal:\n'
914 lines = ['First has %d, Second has %d: %r' % diff for diff in diffe rences] 1166 lines = ['First has %d, Second has %d: %r' % diff for diff in diffe rences]
915 diffMsg = '\n'.join(lines) 1167 diffMsg = '\n'.join(lines)
916 standardMsg = self._truncateMessage(standardMsg, diffMsg) 1168 standardMsg = self._truncateMessage(standardMsg, diffMsg)
917 msg = self._formatMessage(msg, standardMsg) 1169 msg = self._formatMessage(msg, standardMsg)
918 self.fail(msg) 1170 self.fail(msg)
919 1171
920 def assertMultiLineEqual(self, first, second, msg=None): 1172 def assertMultiLineEqual(self, first, second, msg=None):
921 """Assert that two multi-line strings are equal.""" 1173 """Assert that two multi-line strings are equal."""
922 self.assertIsInstance(first, basestring, 1174 self.assertIsInstance(first, str, 'First argument is not a string')
923 'First argument is not a string') 1175 self.assertIsInstance(second, str, 'Second argument is not a string')
924 self.assertIsInstance(second, basestring,
925 'Second argument is not a string')
926 1176
927 if first != second: 1177 if first != second:
928 # don't use difflib if the strings are too long 1178 # don't use difflib if the strings are too long
929 if (len(first) > self._diffThreshold or 1179 if (len(first) > self._diffThreshold or
930 len(second) > self._diffThreshold): 1180 len(second) > self._diffThreshold):
931 self._baseAssertEqual(first, second, msg) 1181 self._baseAssertEqual(first, second, msg)
932 firstlines = first.splitlines(True) 1182 firstlines = first.splitlines(keepends=True)
933 secondlines = second.splitlines(True) 1183 secondlines = second.splitlines(keepends=True)
934 if len(firstlines) == 1 and first.strip('\r\n') == first: 1184 if len(firstlines) == 1 and first.strip('\r\n') == first:
935 firstlines = [first + '\n'] 1185 firstlines = [first + '\n']
936 secondlines = [second + '\n'] 1186 secondlines = [second + '\n']
937 standardMsg = '%s != %s' % (safe_repr(first, True), 1187 standardMsg = '%s != %s' % _common_shorten_repr(first, second)
938 safe_repr(second, True))
939 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) 1188 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
940 standardMsg = self._truncateMessage(standardMsg, diff) 1189 standardMsg = self._truncateMessage(standardMsg, diff)
941 self.fail(self._formatMessage(msg, standardMsg)) 1190 self.fail(self._formatMessage(msg, standardMsg))
942 1191
943 def assertLess(self, a, b, msg=None): 1192 def assertLess(self, a, b, msg=None):
944 """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."" "
945 if not a < b: 1194 if not a < b:
946 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))
947 self.fail(self._formatMessage(msg, standardMsg)) 1196 self.fail(self._formatMessage(msg, standardMsg))
948 1197
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 if not isinstance(obj, cls): 1231 if not isinstance(obj, cls):
983 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)
984 self.fail(self._formatMessage(msg, standardMsg)) 1233 self.fail(self._formatMessage(msg, standardMsg))
985 1234
986 def assertNotIsInstance(self, obj, cls, msg=None): 1235 def assertNotIsInstance(self, obj, cls, msg=None):
987 """Included for symmetry with assertIsInstance.""" 1236 """Included for symmetry with assertIsInstance."""
988 if isinstance(obj, cls): 1237 if isinstance(obj, cls):
989 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) 1238 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
990 self.fail(self._formatMessage(msg, standardMsg)) 1239 self.fail(self._formatMessage(msg, standardMsg))
991 1240
992 def assertRaisesRegexp(self, expected_exception, expected_regexp, 1241 def assertRaisesRegex(self, expected_exception, expected_regex,
993 callable_obj=None, *args, **kwargs): 1242 *args, **kwargs):
994 """Asserts that the message in a raised exception matches a regexp. 1243 """Asserts that the message in a raised exception matches a regex.
995 1244
996 Args: 1245 Args:
997 expected_exception: Exception class expected to be raised. 1246 expected_exception: Exception class expected to be raised.
998 expected_regexp: Regexp (re pattern object or string) expected 1247 expected_regex: Regex (re pattern object or string) expected
999 to be found in error message. 1248 to be found in error message.
1000 callable_obj: Function to be called. 1249 args: Function to be called and extra positional args.
1001 args: Extra args.
1002 kwargs: Extra kwargs. 1250 kwargs: Extra kwargs.
1003 """ 1251 msg: Optional message used in case of failure. Can only be used
1004 context = _AssertRaisesContext(expected_exception, self, expected_regexp ) 1252 when assertRaisesRegex is used as a context manager.
1005 if callable_obj is None: 1253 """
1006 return context 1254 context = _AssertRaisesContext(expected_exception, self, expected_regex)
1007 with context: 1255 return context.handle('assertRaisesRegex', args, kwargs)
1008 callable_obj(*args, **kwargs) 1256
1009 1257 def assertWarnsRegex(self, expected_warning, expected_regex,
1010 def assertRegexpMatches(self, text, expected_regexp, msg=None): 1258 *args, **kwargs):
1259 """Asserts that the message in a triggered warning matches a regexp.
1260 Basic functioning is similar to assertWarns() with the addition
1261 that only warnings whose messages also match the regular expression
1262 are considered successful matches.
1263
1264 Args:
1265 expected_warning: Warning class expected to be triggered.
1266 expected_regex: Regex (re pattern object or string) expected
1267 to be found in error message.
1268 args: Function to be called and extra positional args.
1269 kwargs: Extra kwargs.
1270 msg: Optional message used in case of failure. Can only be used
1271 when assertWarnsRegex is used as a context manager.
1272 """
1273 context = _AssertWarnsContext(expected_warning, self, expected_regex)
1274 return context.handle('assertWarnsRegex', args, kwargs)
1275
1276 def assertRegex(self, text, expected_regex, msg=None):
1011 """Fail the test unless the text matches the regular expression.""" 1277 """Fail the test unless the text matches the regular expression."""
1012 if isinstance(expected_regexp, basestring): 1278 if isinstance(expected_regex, (str, bytes)):
1013 expected_regexp = re.compile(expected_regexp) 1279 assert expected_regex, "expected_regex must not be empty."
1014 if not expected_regexp.search(text): 1280 expected_regex = re.compile(expected_regex)
1015 msg = msg or "Regexp didn't match" 1281 if not expected_regex.search(text):
1016 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text ) 1282 msg = msg or "Regex didn't match"
1283 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
1017 raise self.failureException(msg) 1284 raise self.failureException(msg)
1018 1285
1019 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None): 1286 def assertNotRegex(self, text, unexpected_regex, msg=None):
1020 """Fail the test if the text matches the regular expression.""" 1287 """Fail the test if the text matches the regular expression."""
1021 if isinstance(unexpected_regexp, basestring): 1288 if isinstance(unexpected_regex, (str, bytes)):
1022 unexpected_regexp = re.compile(unexpected_regexp) 1289 unexpected_regex = re.compile(unexpected_regex)
1023 match = unexpected_regexp.search(text) 1290 match = unexpected_regex.search(text)
1024 if match: 1291 if match:
1025 msg = msg or "Regexp matched" 1292 msg = msg or "Regex matched"
1026 msg = '%s: %r matches %r in %r' % (msg, 1293 msg = '%s: %r matches %r in %r' % (msg,
1027 text[match.start():match.end()], 1294 text[match.start():match.end()],
1028 unexpected_regexp.pattern, 1295 unexpected_regex.pattern,
1029 text) 1296 text)
1030 raise self.failureException(msg) 1297 raise self.failureException(msg)
1298
1299
1300 def _deprecate(original_func):
1301 def deprecated_func(*args, **kwargs):
1302 warnings.warn(
1303 'Please use {0} instead.'.format(original_func.__name__),
1304 DeprecationWarning, 2)
1305 return original_func(*args, **kwargs)
1306 return deprecated_func
1307
1308 # see #9424
1309 failUnlessEqual = assertEquals = _deprecate(assertEqual)
1310 failIfEqual = assertNotEquals = _deprecate(assertNotEqual)
1311 failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual)
1312 failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual)
1313 failUnless = assert_ = _deprecate(assertTrue)
1314 failUnlessRaises = _deprecate(assertRaises)
1315 failIf = _deprecate(assertFalse)
1316 assertRaisesRegexp = _deprecate(assertRaisesRegex)
1317 assertRegexpMatches = _deprecate(assertRegex)
1318
1031 1319
1032 1320
1033 class FunctionTestCase(TestCase): 1321 class FunctionTestCase(TestCase):
1034 """A test case that wraps a test function. 1322 """A test case that wraps a test function.
1035 1323
1036 This is useful for slipping pre-existing test functions into the 1324 This is useful for slipping pre-existing test functions into the
1037 unittest framework. Optionally, set-up and tidy-up functions can be 1325 unittest framework. Optionally, set-up and tidy-up functions can be
1038 supplied. As with TestCase, the tidy-up ('tearDown') function will 1326 supplied. As with TestCase, the tidy-up ('tearDown') function will
1039 always be called if the set-up ('setUp') function ran successfully. 1327 always be called if the set-up ('setUp') function ran successfully.
1040 """ 1328 """
(...skipping 21 matching lines...) Expand all
1062 1350
1063 def __eq__(self, other): 1351 def __eq__(self, other):
1064 if not isinstance(other, self.__class__): 1352 if not isinstance(other, self.__class__):
1065 return NotImplemented 1353 return NotImplemented
1066 1354
1067 return self._setUpFunc == other._setUpFunc and \ 1355 return self._setUpFunc == other._setUpFunc and \
1068 self._tearDownFunc == other._tearDownFunc and \ 1356 self._tearDownFunc == other._tearDownFunc and \
1069 self._testFunc == other._testFunc and \ 1357 self._testFunc == other._testFunc and \
1070 self._description == other._description 1358 self._description == other._description
1071 1359
1072 def __ne__(self, other):
1073 return not self == other
1074
1075 def __hash__(self): 1360 def __hash__(self):
1076 return hash((type(self), self._setUpFunc, self._tearDownFunc, 1361 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1077 self._testFunc, self._description)) 1362 self._testFunc, self._description))
1078 1363
1079 def __str__(self): 1364 def __str__(self):
1080 return "%s (%s)" % (strclass(self.__class__), 1365 return "%s (%s)" % (strclass(self.__class__),
1081 self._testFunc.__name__) 1366 self._testFunc.__name__)
1082 1367
1083 def __repr__(self): 1368 def __repr__(self):
1084 return "<%s tec=%s>" % (strclass(self.__class__), 1369 return "<%s tec=%s>" % (strclass(self.__class__),
1085 self._testFunc) 1370 self._testFunc)
1086 1371
1087 def shortDescription(self): 1372 def shortDescription(self):
1088 if self._description is not None: 1373 if self._description is not None:
1089 return self._description 1374 return self._description
1090 doc = self._testFunc.__doc__ 1375 doc = self._testFunc.__doc__
1091 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+