blob: 5831a76e030f34faf05d4f334d6431a7383ab835 [file] [log] [blame]
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001"""Test case implementation"""
2
3import sys
4import functools
5import difflib
6import pprint
7import re
8import warnings
9
Benjamin Peterson847a4112010-03-14 15:04:17 +000010from . import result
11from .util import (strclass, safe_repr, sorted_list_difference,
12 unorderable_list_difference)
Benjamin Petersonbed7d042009-07-19 21:01:52 +000013
Benjamin Petersondccc1fc2010-03-22 00:15:53 +000014__unittest = True
Benjamin Petersonbed7d042009-07-19 21:01:52 +000015
Michael Foord9dad32e2010-06-05 13:49:56 +000016
17DIFF_OMITTED = ('\nDiff is %s characters long. '
18 'Set self.maxDiff to None to see it.')
19
Benjamin Petersonbed7d042009-07-19 21:01:52 +000020class SkipTest(Exception):
21 """
22 Raise this exception in a test to skip it.
23
24 Usually you can use TestResult.skip() or one of the skipping decorators
25 instead of raising this directly.
26 """
27 pass
28
29class _ExpectedFailure(Exception):
30 """
31 Raise this when a test is expected to fail.
32
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
40class _UnexpectedSuccess(Exception):
41 """
42 The test was supposed to fail, but it didn't!
43 """
44 pass
45
46def _id(obj):
47 return obj
48
49def skip(reason):
50 """
51 Unconditionally skip a test.
52 """
53 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000054 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
55 @functools.wraps(test_item)
56 def skip_wrapper(*args, **kwargs):
57 raise SkipTest(reason)
58 test_item = skip_wrapper
59
60 test_item.__unittest_skip__ = True
61 test_item.__unittest_skip_why__ = reason
62 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000063 return decorator
64
65def skipIf(condition, reason):
66 """
67 Skip a test if the condition is true.
68 """
69 if condition:
70 return skip(reason)
71 return _id
72
73def skipUnless(condition, reason):
74 """
75 Skip a test unless the condition is true.
76 """
77 if not condition:
78 return skip(reason)
79 return _id
80
81
82def expectedFailure(func):
83 @functools.wraps(func)
84 def wrapper(*args, **kwargs):
85 try:
86 func(*args, **kwargs)
87 except Exception:
88 raise _ExpectedFailure(sys.exc_info())
89 raise _UnexpectedSuccess
90 return wrapper
91
92
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +000093class _AssertRaisesBaseContext(object):
Benjamin Petersonbed7d042009-07-19 21:01:52 +000094
95 def __init__(self, expected, test_case, callable_obj=None,
96 expected_regexp=None):
97 self.expected = expected
98 self.failureException = test_case.failureException
99 if callable_obj is not None:
100 try:
101 self.obj_name = callable_obj.__name__
102 except AttributeError:
103 self.obj_name = str(callable_obj)
104 else:
105 self.obj_name = None
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000106 if isinstance(expected_regexp, (bytes, str)):
107 expected_regexp = re.compile(expected_regexp)
Georg Brandl89fad142010-03-14 10:23:39 +0000108 self.expected_regexp = expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000109
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000110
111class _AssertRaisesContext(_AssertRaisesBaseContext):
112 """A context manager used to implement TestCase.assertRaises* methods."""
113
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000114 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000115 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000116
117 def __exit__(self, exc_type, exc_value, tb):
118 if exc_type is None:
119 try:
120 exc_name = self.expected.__name__
121 except AttributeError:
122 exc_name = str(self.expected)
123 if self.obj_name:
124 raise self.failureException("{0} not raised by {1}"
125 .format(exc_name, self.obj_name))
126 else:
127 raise self.failureException("{0} not raised"
128 .format(exc_name))
129 if not issubclass(exc_type, self.expected):
130 # let unexpected exceptions pass through
131 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000132 # store exception, without traceback, for later retrieval
133 self.exception = exc_value.with_traceback(None)
Georg Brandl89fad142010-03-14 10:23:39 +0000134 if self.expected_regexp is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000135 return True
136
Georg Brandl89fad142010-03-14 10:23:39 +0000137 expected_regexp = self.expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000138 if not expected_regexp.search(str(exc_value)):
139 raise self.failureException('"%s" does not match "%s"' %
140 (expected_regexp.pattern, str(exc_value)))
141 return True
142
143
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000144class _AssertWarnsContext(_AssertRaisesBaseContext):
145 """A context manager used to implement TestCase.assertWarns* methods."""
146
147 def __enter__(self):
148 # The __warningregistry__'s need to be in a pristine state for tests
149 # to work properly.
150 for v in sys.modules.values():
151 if getattr(v, '__warningregistry__', None):
152 v.__warningregistry__ = {}
153 self.warnings_manager = warnings.catch_warnings(record=True)
154 self.warnings = self.warnings_manager.__enter__()
155 warnings.simplefilter("always", self.expected)
156 return self
157
158 def __exit__(self, exc_type, exc_value, tb):
159 self.warnings_manager.__exit__(exc_type, exc_value, tb)
160 if exc_type is not None:
161 # let unexpected exceptions pass through
162 return
163 try:
164 exc_name = self.expected.__name__
165 except AttributeError:
166 exc_name = str(self.expected)
167 first_matching = None
168 for m in self.warnings:
169 w = m.message
170 if not isinstance(w, self.expected):
171 continue
172 if first_matching is None:
173 first_matching = w
174 if (self.expected_regexp is not None and
175 not self.expected_regexp.search(str(w))):
176 continue
177 # store warning for later retrieval
178 self.warning = w
179 self.filename = m.filename
180 self.lineno = m.lineno
181 return
182 # Now we simply try to choose a helpful failure message
183 if first_matching is not None:
184 raise self.failureException('"%s" does not match "%s"' %
185 (self.expected_regexp.pattern, str(first_matching)))
186 if self.obj_name:
187 raise self.failureException("{0} not triggered by {1}"
188 .format(exc_name, self.obj_name))
189 else:
190 raise self.failureException("{0} not triggered"
191 .format(exc_name))
192
193
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000194class TestCase(object):
195 """A class whose instances are single test cases.
196
197 By default, the test code itself should be placed in a method named
198 'runTest'.
199
200 If the fixture may be used for many test cases, create as
201 many test methods as are needed. When instantiating such a TestCase
202 subclass, specify in the constructor arguments the name of the test method
203 that the instance is to execute.
204
205 Test authors should subclass TestCase for their own tests. Construction
206 and deconstruction of the test's environment ('fixture') can be
207 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
208
209 If it is necessary to override the __init__ method, the base class
210 __init__ method must always be called. It is important that subclasses
211 should not change the signature of their __init__ method, since instances
212 of the classes are instantiated automatically by parts of the framework
213 in order to be run.
214 """
215
216 # This attribute determines which exception will be raised when
217 # the instance's assertion methods fail; test methods raising this
218 # exception will be deemed to have 'failed' rather than 'errored'
219
220 failureException = AssertionError
221
222 # This attribute determines whether long messages (including repr of
223 # objects used in assert methods) will be printed on failure in *addition*
224 # to any explicit message passed.
225
226 longMessage = False
227
Michael Foordc41d1412010-06-10 16:17:07 +0000228 # This attribute sets the maximum length of a diff in failure messages
Michael Foord085dfd32010-06-05 12:17:02 +0000229 # by assert methods using difflib. It is looked up as an instance attribute
230 # so can be configured by individual tests if required.
Michael Foordd50a6b92010-06-05 23:59:34 +0000231
Michael Foord085dfd32010-06-05 12:17:02 +0000232 maxDiff = 80*8
233
Benjamin Peterson847a4112010-03-14 15:04:17 +0000234 # Attribute used by TestSuite for classSetUp
235
236 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000237
238 def __init__(self, methodName='runTest'):
239 """Create an instance of the class that will use the named test
240 method when executed. Raises a ValueError if the instance does
241 not have a method with the specified name.
242 """
243 self._testMethodName = methodName
244 self._resultForDoCleanups = None
245 try:
246 testMethod = getattr(self, methodName)
247 except AttributeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000248 raise ValueError("no such test method in %s: %s" %
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000249 (self.__class__, methodName))
250 self._testMethodDoc = testMethod.__doc__
251 self._cleanups = []
252
253 # Map types to custom assertEqual functions that will compare
254 # instances of said type in more detail to generate a more useful
255 # error message.
256 self._type_equality_funcs = {}
257 self.addTypeEqualityFunc(dict, self.assertDictEqual)
258 self.addTypeEqualityFunc(list, self.assertListEqual)
259 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
260 self.addTypeEqualityFunc(set, self.assertSetEqual)
261 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foord02834952010-02-08 23:10:39 +0000262 self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000263
264 def addTypeEqualityFunc(self, typeobj, function):
265 """Add a type specific assertEqual style function to compare a type.
266
267 This method is for use by TestCase subclasses that need to register
268 their own type equality functions to provide nicer error messages.
269
270 Args:
271 typeobj: The data type to call this function on when both values
272 are of the same type in assertEqual().
273 function: The callable taking two arguments and an optional
274 msg= argument that raises self.failureException with a
275 useful error message when the two arguments are not equal.
276 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000277 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000278
279 def addCleanup(self, function, *args, **kwargs):
280 """Add a function, with arguments, to be called when the test is
281 completed. Functions added are called on a LIFO basis and are
282 called after tearDown on test failure or success.
283
284 Cleanup items are called even if setUp fails (unlike tearDown)."""
285 self._cleanups.append((function, args, kwargs))
286
287 def setUp(self):
288 "Hook method for setting up the test fixture before exercising it."
289 pass
290
291 def tearDown(self):
292 "Hook method for deconstructing the test fixture after testing it."
293 pass
294
Benjamin Peterson847a4112010-03-14 15:04:17 +0000295 @classmethod
296 def setUpClass(cls):
297 "Hook method for setting up class fixture before running tests in the class."
298
299 @classmethod
300 def tearDownClass(cls):
301 "Hook method for deconstructing the class fixture after running all tests in the class."
302
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000303 def countTestCases(self):
304 return 1
305
306 def defaultTestResult(self):
307 return result.TestResult()
308
309 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000310 """Returns a one-line description of the test, or None if no
311 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000312
Michael Foord34c94622010-02-10 15:51:42 +0000313 The default implementation of this method returns the first line of
314 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000315 """
Michael Foord34c94622010-02-10 15:51:42 +0000316 doc = self._testMethodDoc
317 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000318
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000319
320 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000321 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000322
323 def __eq__(self, other):
324 if type(self) is not type(other):
325 return NotImplemented
326
327 return self._testMethodName == other._testMethodName
328
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000329 def __hash__(self):
330 return hash((type(self), self._testMethodName))
331
332 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000333 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000334
335 def __repr__(self):
336 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000337 (strclass(self.__class__), self._testMethodName)
338
339 def _addSkip(self, result, reason):
340 addSkip = getattr(result, 'addSkip', None)
341 if addSkip is not None:
342 addSkip(self, reason)
343 else:
344 warnings.warn("TestResult has no addSkip method, skips not reported",
345 RuntimeWarning, 2)
346 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000347
348 def run(self, result=None):
349 orig_result = result
350 if result is None:
351 result = self.defaultTestResult()
352 startTestRun = getattr(result, 'startTestRun', None)
353 if startTestRun is not None:
354 startTestRun()
355
356 self._resultForDoCleanups = result
357 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000358
359 testMethod = getattr(self, self._testMethodName)
360 if (getattr(self.__class__, "__unittest_skip__", False) or
361 getattr(testMethod, "__unittest_skip__", False)):
362 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000363 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000364 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
365 or getattr(testMethod, '__unittest_skip_why__', ''))
366 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000367 finally:
368 result.stopTest(self)
369 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000370 try:
371 success = False
372 try:
373 self.setUp()
374 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000375 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000376 except Exception:
377 result.addError(self, sys.exc_info())
378 else:
379 try:
380 testMethod()
381 except self.failureException:
382 result.addFailure(self, sys.exc_info())
383 except _ExpectedFailure as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000384 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
385 if addExpectedFailure is not None:
386 addExpectedFailure(self, e.exc_info)
387 else:
388 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
389 RuntimeWarning)
390 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000391 except _UnexpectedSuccess:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000392 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
393 if addUnexpectedSuccess is not None:
394 addUnexpectedSuccess(self)
395 else:
396 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
397 RuntimeWarning)
398 result.addFailure(self, sys.exc_info())
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000399 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000400 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000401 except Exception:
402 result.addError(self, sys.exc_info())
403 else:
404 success = True
405
406 try:
407 self.tearDown()
408 except Exception:
409 result.addError(self, sys.exc_info())
410 success = False
411
412 cleanUpSuccess = self.doCleanups()
413 success = success and cleanUpSuccess
414 if success:
415 result.addSuccess(self)
416 finally:
417 result.stopTest(self)
418 if orig_result is None:
419 stopTestRun = getattr(result, 'stopTestRun', None)
420 if stopTestRun is not None:
421 stopTestRun()
422
423 def doCleanups(self):
424 """Execute all cleanup functions. Normally called for you after
425 tearDown."""
426 result = self._resultForDoCleanups
427 ok = True
428 while self._cleanups:
429 function, args, kwargs = self._cleanups.pop(-1)
430 try:
431 function(*args, **kwargs)
432 except Exception:
433 ok = False
434 result.addError(self, sys.exc_info())
435 return ok
436
437 def __call__(self, *args, **kwds):
438 return self.run(*args, **kwds)
439
440 def debug(self):
441 """Run the test without collecting errors in a TestResult"""
442 self.setUp()
443 getattr(self, self._testMethodName)()
444 self.tearDown()
Michael Foordb8748742010-06-10 16:16:08 +0000445 while self._cleanups:
446 function, args, kwargs = self._cleanups.pop(-1)
447 function(*args, **kwargs)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000448
449 def skipTest(self, reason):
450 """Skip this test."""
451 raise SkipTest(reason)
452
453 def fail(self, msg=None):
454 """Fail immediately, with the given message."""
455 raise self.failureException(msg)
456
457 def assertFalse(self, expr, msg=None):
458 "Fail the test if the expression is true."
459 if expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000460 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000461 raise self.failureException(msg)
462
463 def assertTrue(self, expr, msg=None):
464 """Fail the test unless the expression is true."""
465 if not expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000466 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000467 raise self.failureException(msg)
468
469 def _formatMessage(self, msg, standardMsg):
470 """Honour the longMessage attribute when generating failure messages.
471 If longMessage is False this means:
472 * Use only an explicit message if it is provided
473 * Otherwise use the standard message for the assert
474
475 If longMessage is True:
476 * Use the standard message
477 * If an explicit message is provided, plus ' : ' and the explicit message
478 """
479 if not self.longMessage:
480 return msg or standardMsg
481 if msg is None:
482 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000483 try:
484 # don't switch to '{}' formatting in Python 2.X
485 # it changes the way unicode input is handled
486 return '%s : %s' % (standardMsg, msg)
487 except UnicodeDecodeError:
488 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000489
490
491 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
492 """Fail unless an exception of class excClass is thrown
493 by callableObj when invoked with arguments args and keyword
494 arguments kwargs. If a different type of exception is
495 thrown, it will not be caught, and the test case will be
496 deemed to have suffered an error, exactly as for an
497 unexpected exception.
498
499 If called with callableObj omitted or None, will return a
500 context object used like this::
501
Michael Foord1c42b122010-02-05 22:58:21 +0000502 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000503 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000504
505 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000506 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000507 exception after the assertion::
508
509 with self.assertRaises(SomeException) as cm:
510 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000511 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000512 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000513 """
514 context = _AssertRaisesContext(excClass, self, callableObj)
515 if callableObj is None:
516 return context
517 with context:
518 callableObj(*args, **kwargs)
519
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +0000520 def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
521 """Fail unless a warning of class warnClass is triggered
522 by callableObj when invoked with arguments args and keyword
523 arguments kwargs. If a different type of warning is
524 triggered, it will not be handled: depending on the other
525 warning filtering rules in effect, it might be silenced, printed
526 out, or raised as an exception.
527
528 If called with callableObj omitted or None, will return a
529 context object used like this::
530
531 with self.assertWarns(SomeWarning):
532 do_something()
533
534 The context manager keeps a reference to the first matching
535 warning as the 'warning' attribute; similarly, the 'filename'
536 and 'lineno' attributes give you information about the line
537 of Python code from which the warning was triggered.
538 This allows you to inspect the warning after the assertion::
539
540 with self.assertWarns(SomeWarning) as cm:
541 do_something()
542 the_warning = cm.warning
543 self.assertEqual(the_warning.some_attribute, 147)
544 """
545 context = _AssertWarnsContext(expected_warning, self, callable_obj)
546 if callable_obj is None:
547 return context
548 with context:
549 callable_obj(*args, **kwargs)
550
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000551 def _getAssertEqualityFunc(self, first, second):
552 """Get a detailed comparison function for the types of the two args.
553
554 Returns: A callable accepting (first, second, msg=None) that will
555 raise a failure exception if first != second with a useful human
556 readable error message for those types.
557 """
558 #
559 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
560 # and vice versa. I opted for the conservative approach in case
561 # subclasses are not intended to be compared in detail to their super
562 # class instances using a type equality func. This means testing
563 # subtypes won't automagically use the detailed comparison. Callers
564 # should use their type specific assertSpamEqual method to compare
565 # subclasses if the detailed comparison is desired and appropriate.
566 # See the discussion in http://bugs.python.org/issue2578.
567 #
568 if type(first) is type(second):
569 asserter = self._type_equality_funcs.get(type(first))
570 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000571 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000572
573 return self._baseAssertEqual
574
575 def _baseAssertEqual(self, first, second, msg=None):
576 """The default assertEqual implementation, not type specific."""
577 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000578 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000579 msg = self._formatMessage(msg, standardMsg)
580 raise self.failureException(msg)
581
582 def assertEqual(self, first, second, msg=None):
583 """Fail if the two objects are unequal as determined by the '=='
584 operator.
585 """
586 assertion_func = self._getAssertEqualityFunc(first, second)
587 assertion_func(first, second, msg=msg)
588
589 def assertNotEqual(self, first, second, msg=None):
590 """Fail if the two objects are equal as determined by the '=='
591 operator.
592 """
593 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000594 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
595 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000596 raise self.failureException(msg)
597
Michael Foord321d0592010-11-02 13:44:51 +0000598 def assertAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000599 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000600 """Fail if the two objects are unequal as determined by their
601 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000602 (default 7) and comparing to zero, or by comparing that the
603 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000604
605 Note that decimal places (from zero) are usually not the same
606 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000607
608 If the two objects compare equal then they will automatically
609 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000610 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000611 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000612 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000613 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000614 if delta is not None and places is not None:
615 raise TypeError("specify delta or places not both")
616
617 if delta is not None:
618 if abs(first - second) <= delta:
619 return
620
621 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
622 safe_repr(second),
623 safe_repr(delta))
624 else:
625 if places is None:
626 places = 7
627
628 if round(abs(second-first), places) == 0:
629 return
630
Benjamin Peterson847a4112010-03-14 15:04:17 +0000631 standardMsg = '%s != %s within %r places' % (safe_repr(first),
632 safe_repr(second),
633 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000634 msg = self._formatMessage(msg, standardMsg)
635 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000636
Michael Foord321d0592010-11-02 13:44:51 +0000637 def assertNotAlmostEqual(self, first, second, places=None, msg=None,
Benjamin Petersonb48af542010-04-11 20:43:16 +0000638 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000639 """Fail if the two objects are equal as determined by their
640 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000641 (default 7) and comparing to zero, or by comparing that the
642 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000643
644 Note that decimal places (from zero) are usually not the same
645 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000646
647 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000648 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000649 if delta is not None and places is not None:
650 raise TypeError("specify delta or places not both")
651 if delta is not None:
652 if not (first == second) and abs(first - second) > delta:
653 return
654 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
655 safe_repr(second),
656 safe_repr(delta))
657 else:
658 if places is None:
659 places = 7
660 if not (first == second) and round(abs(second-first), places) != 0:
661 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000662 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000663 safe_repr(second),
664 places)
665
666 msg = self._formatMessage(msg, standardMsg)
667 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000668
669 # Synonyms for assertion methods
670
671 # The plurals are undocumented. Keep them that way to discourage use.
672 # Do not add more. Do not remove.
673 # Going through a deprecation cycle on these would annoy many people.
674 assertEquals = assertEqual
675 assertNotEquals = assertNotEqual
676 assertAlmostEquals = assertAlmostEqual
677 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord0e31b992010-02-10 15:52:56 +0000678 assert_ = assertTrue
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000679
680 # These fail* assertion method names are pending deprecation and will
681 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
682 def _deprecate(original_func):
683 def deprecated_func(*args, **kwargs):
684 warnings.warn(
685 'Please use {0} instead.'.format(original_func.__name__),
686 DeprecationWarning, 2)
687 return original_func(*args, **kwargs)
688 return deprecated_func
689
690 failUnlessEqual = _deprecate(assertEqual)
691 failIfEqual = _deprecate(assertNotEqual)
692 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
693 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
694 failUnless = _deprecate(assertTrue)
695 failUnlessRaises = _deprecate(assertRaises)
696 failIf = _deprecate(assertFalse)
697
Michael Foord085dfd32010-06-05 12:17:02 +0000698 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000699 """An equality assertion for ordered sequences (like lists and tuples).
700
R. David Murrayad13f222010-01-29 22:17:58 +0000701 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000702 which can be indexed, has a length, and has an equality operator.
703
704 Args:
705 seq1: The first sequence to compare.
706 seq2: The second sequence to compare.
707 seq_type: The expected datatype of the sequences, or None if no
708 datatype should be enforced.
709 msg: Optional message to use on failure instead of a list of
710 differences.
711 """
712 if seq_type != None:
713 seq_type_name = seq_type.__name__
714 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000715 raise self.failureException('First sequence is not a %s: %s'
716 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000717 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000718 raise self.failureException('Second sequence is not a %s: %s'
719 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000720 else:
721 seq_type_name = "sequence"
722
723 differing = None
724 try:
725 len1 = len(seq1)
726 except (TypeError, NotImplementedError):
727 differing = 'First %s has no length. Non-sequence?' % (
728 seq_type_name)
729
730 if differing is None:
731 try:
732 len2 = len(seq2)
733 except (TypeError, NotImplementedError):
734 differing = 'Second %s has no length. Non-sequence?' % (
735 seq_type_name)
736
737 if differing is None:
738 if seq1 == seq2:
739 return
740
Benjamin Peterson847a4112010-03-14 15:04:17 +0000741 seq1_repr = safe_repr(seq1)
742 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000743 if len(seq1_repr) > 30:
744 seq1_repr = seq1_repr[:30] + '...'
745 if len(seq2_repr) > 30:
746 seq2_repr = seq2_repr[:30] + '...'
747 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
748 differing = '%ss differ: %s != %s\n' % elements
749
750 for i in range(min(len1, len2)):
751 try:
752 item1 = seq1[i]
753 except (TypeError, IndexError, NotImplementedError):
754 differing += ('\nUnable to index element %d of first %s\n' %
755 (i, seq_type_name))
756 break
757
758 try:
759 item2 = seq2[i]
760 except (TypeError, IndexError, NotImplementedError):
761 differing += ('\nUnable to index element %d of second %s\n' %
762 (i, seq_type_name))
763 break
764
765 if item1 != item2:
766 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
767 (i, item1, item2))
768 break
769 else:
770 if (len1 == len2 and seq_type is None and
771 type(seq1) != type(seq2)):
772 # The sequences are the same, but have differing types.
773 return
774
775 if len1 > len2:
776 differing += ('\nFirst %s contains %d additional '
777 'elements.\n' % (seq_type_name, len1 - len2))
778 try:
779 differing += ('First extra element %d:\n%s\n' %
780 (len2, seq1[len2]))
781 except (TypeError, IndexError, NotImplementedError):
782 differing += ('Unable to index element %d '
783 'of first %s\n' % (len2, seq_type_name))
784 elif len1 < len2:
785 differing += ('\nSecond %s contains %d additional '
786 'elements.\n' % (seq_type_name, len2 - len1))
787 try:
788 differing += ('First extra element %d:\n%s\n' %
789 (len1, seq2[len1]))
790 except (TypeError, IndexError, NotImplementedError):
791 differing += ('Unable to index element %d '
792 'of second %s\n' % (len1, seq_type_name))
Michael Foord2034d9a2010-06-05 11:27:52 +0000793 standardMsg = differing
794 diffMsg = '\n' + '\n'.join(
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000795 difflib.ndiff(pprint.pformat(seq1).splitlines(),
796 pprint.pformat(seq2).splitlines()))
Michael Foord085dfd32010-06-05 12:17:02 +0000797
798 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000799 msg = self._formatMessage(msg, standardMsg)
800 self.fail(msg)
801
Michael Foord085dfd32010-06-05 12:17:02 +0000802 def _truncateMessage(self, message, diff):
803 max_diff = self.maxDiff
804 if max_diff is None or len(diff) <= max_diff:
805 return message + diff
Michael Foord9dad32e2010-06-05 13:49:56 +0000806 return message + (DIFF_OMITTED % len(diff))
Michael Foord085dfd32010-06-05 12:17:02 +0000807
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000808 def assertListEqual(self, list1, list2, msg=None):
809 """A list-specific equality assertion.
810
811 Args:
812 list1: The first list to compare.
813 list2: The second list to compare.
814 msg: Optional message to use on failure instead of a list of
815 differences.
816
817 """
818 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
819
820 def assertTupleEqual(self, tuple1, tuple2, msg=None):
821 """A tuple-specific equality assertion.
822
823 Args:
824 tuple1: The first tuple to compare.
825 tuple2: The second tuple to compare.
826 msg: Optional message to use on failure instead of a list of
827 differences.
828 """
829 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
830
831 def assertSetEqual(self, set1, set2, msg=None):
832 """A set-specific equality assertion.
833
834 Args:
835 set1: The first set to compare.
836 set2: The second set to compare.
837 msg: Optional message to use on failure instead of a list of
838 differences.
839
Michael Foord91c9da32010-03-20 17:21:27 +0000840 assertSetEqual uses ducktyping to support different types of sets, and
841 is optimized for sets specifically (parameters must support a
842 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000843 """
844 try:
845 difference1 = set1.difference(set2)
846 except TypeError as e:
847 self.fail('invalid type when attempting set difference: %s' % e)
848 except AttributeError as e:
849 self.fail('first argument does not support set difference: %s' % e)
850
851 try:
852 difference2 = set2.difference(set1)
853 except TypeError as e:
854 self.fail('invalid type when attempting set difference: %s' % e)
855 except AttributeError as e:
856 self.fail('second argument does not support set difference: %s' % e)
857
858 if not (difference1 or difference2):
859 return
860
861 lines = []
862 if difference1:
863 lines.append('Items in the first set but not the second:')
864 for item in difference1:
865 lines.append(repr(item))
866 if difference2:
867 lines.append('Items in the second set but not the first:')
868 for item in difference2:
869 lines.append(repr(item))
870
871 standardMsg = '\n'.join(lines)
872 self.fail(self._formatMessage(msg, standardMsg))
873
874 def assertIn(self, member, container, msg=None):
875 """Just like self.assertTrue(a in b), but with a nicer default message."""
876 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000877 standardMsg = '%s not found in %s' % (safe_repr(member),
878 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000879 self.fail(self._formatMessage(msg, standardMsg))
880
881 def assertNotIn(self, member, container, msg=None):
882 """Just like self.assertTrue(a not in b), but with a nicer default message."""
883 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000884 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
885 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000886 self.fail(self._formatMessage(msg, standardMsg))
887
888 def assertIs(self, expr1, expr2, msg=None):
889 """Just like self.assertTrue(a is b), but with a nicer default message."""
890 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000891 standardMsg = '%s is not %s' % (safe_repr(expr1),
892 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000893 self.fail(self._formatMessage(msg, standardMsg))
894
895 def assertIsNot(self, expr1, expr2, msg=None):
896 """Just like self.assertTrue(a is not b), but with a nicer default message."""
897 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000898 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000899 self.fail(self._formatMessage(msg, standardMsg))
900
901 def assertDictEqual(self, d1, d2, msg=None):
902 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
903 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
904
905 if d1 != d2:
Michael Foordcb11b252010-06-05 13:14:43 +0000906 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foord085dfd32010-06-05 12:17:02 +0000907 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000908 pprint.pformat(d1).splitlines(),
909 pprint.pformat(d2).splitlines())))
Michael Foordcb11b252010-06-05 13:14:43 +0000910 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000911 self.fail(self._formatMessage(msg, standardMsg))
912
913 def assertDictContainsSubset(self, expected, actual, msg=None):
914 """Checks whether actual is a superset of expected."""
915 missing = []
916 mismatched = []
917 for key, value in expected.items():
918 if key not in actual:
919 missing.append(key)
920 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000921 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000922 (safe_repr(key), safe_repr(value),
923 safe_repr(actual[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000924
925 if not (missing or mismatched):
926 return
927
928 standardMsg = ''
929 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000930 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
931 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000932 if mismatched:
933 if standardMsg:
934 standardMsg += '; '
935 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
936
937 self.fail(self._formatMessage(msg, standardMsg))
938
939 def assertSameElements(self, expected_seq, actual_seq, msg=None):
940 """An unordered sequence specific comparison.
941
942 Raises with an error message listing which elements of expected_seq
943 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000944
945 Duplicate elements are ignored when comparing *expected_seq* and
946 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
947 set(actual))`` but it works with sequences of unhashable objects as
948 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000949 """
Michael Foord91c9da32010-03-20 17:21:27 +0000950 warnings.warn('assertSameElements is deprecated',
951 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000952 try:
953 expected = set(expected_seq)
954 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000955 missing = sorted(expected.difference(actual))
956 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000957 except TypeError:
958 # Fall back to slower list-compare if any of the objects are
959 # not hashable.
960 expected = list(expected_seq)
961 actual = list(actual_seq)
962 try:
963 expected.sort()
964 actual.sort()
965 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000966 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000967 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000968 else:
969 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000970 errors = []
971 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000972 errors.append('Expected, but missing:\n %s' %
973 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000974 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000975 errors.append('Unexpected, but present:\n %s' %
976 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000977 if errors:
978 standardMsg = '\n'.join(errors)
979 self.fail(self._formatMessage(msg, standardMsg))
980
Michael Foord8442a602010-03-20 16:58:04 +0000981
982 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
983 """An unordered sequence / set specific comparison. It asserts that
984 expected_seq and actual_seq contain the same elements. It is
985 the equivalent of::
986
987 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
988
989 Raises with an error message listing which elements of expected_seq
990 are missing from actual_seq and vice versa if any.
991
992 Asserts that each element has the same count in both sequences.
993 Example:
994 - [0, 1, 1] and [1, 0, 1] compare equal.
995 - [0, 0, 1] and [0, 1] compare unequal.
996 """
997 try:
998 expected = sorted(expected_seq)
999 actual = sorted(actual_seq)
1000 except TypeError:
1001 # Unsortable items (example: set(), complex(), ...)
1002 expected = list(expected_seq)
1003 actual = list(actual_seq)
1004 missing, unexpected = unorderable_list_difference(expected, actual)
1005 else:
1006 return self.assertSequenceEqual(expected, actual, msg=msg)
1007
1008 errors = []
1009 if missing:
1010 errors.append('Expected, but missing:\n %s' %
1011 safe_repr(missing))
1012 if unexpected:
1013 errors.append('Unexpected, but present:\n %s' %
1014 safe_repr(unexpected))
1015 if errors:
1016 standardMsg = '\n'.join(errors)
1017 self.fail(self._formatMessage(msg, standardMsg))
1018
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001019 def assertMultiLineEqual(self, first, second, msg=None):
1020 """Assert that two multi-line strings are equal."""
1021 self.assert_(isinstance(first, str), (
1022 'First argument is not a string'))
1023 self.assert_(isinstance(second, str), (
1024 'Second argument is not a string'))
1025
1026 if first != second:
Michael Foordc653ce32010-07-10 13:52:22 +00001027 firstlines = first.splitlines(True)
1028 secondlines = second.splitlines(True)
1029 if len(firstlines) == 1 and first.strip('\r\n') == first:
1030 firstlines = [first + '\n']
1031 secondlines = [second + '\n']
1032 standardMsg = '%s != %s' % (safe_repr(first, True),
1033 safe_repr(second, True))
1034 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foordcb11b252010-06-05 13:14:43 +00001035 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001036 self.fail(self._formatMessage(msg, standardMsg))
1037
1038 def assertLess(self, a, b, msg=None):
1039 """Just like self.assertTrue(a < b), but with a nicer default message."""
1040 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001041 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001042 self.fail(self._formatMessage(msg, standardMsg))
1043
1044 def assertLessEqual(self, a, b, msg=None):
1045 """Just like self.assertTrue(a <= b), but with a nicer default message."""
1046 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001047 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001048 self.fail(self._formatMessage(msg, standardMsg))
1049
1050 def assertGreater(self, a, b, msg=None):
1051 """Just like self.assertTrue(a > b), but with a nicer default message."""
1052 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001053 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001054 self.fail(self._formatMessage(msg, standardMsg))
1055
1056 def assertGreaterEqual(self, a, b, msg=None):
1057 """Just like self.assertTrue(a >= b), but with a nicer default message."""
1058 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001059 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001060 self.fail(self._formatMessage(msg, standardMsg))
1061
1062 def assertIsNone(self, obj, msg=None):
1063 """Same as self.assertTrue(obj is None), with a nicer default message."""
1064 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +00001065 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001066 self.fail(self._formatMessage(msg, standardMsg))
1067
1068 def assertIsNotNone(self, obj, msg=None):
1069 """Included for symmetry with assertIsNone."""
1070 if obj is None:
1071 standardMsg = 'unexpectedly None'
1072 self.fail(self._formatMessage(msg, standardMsg))
1073
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001074 def assertIsInstance(self, obj, cls, msg=None):
1075 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
1076 default message."""
1077 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001078 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001079 self.fail(self._formatMessage(msg, standardMsg))
1080
1081 def assertNotIsInstance(self, obj, cls, msg=None):
1082 """Included for symmetry with assertIsInstance."""
1083 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001084 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +00001085 self.fail(self._formatMessage(msg, standardMsg))
1086
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001087 def assertRaisesRegexp(self, expected_exception, expected_regexp,
1088 callable_obj=None, *args, **kwargs):
1089 """Asserts that the message in a raised exception matches a regexp.
1090
1091 Args:
1092 expected_exception: Exception class expected to be raised.
1093 expected_regexp: Regexp (re pattern object or string) expected
1094 to be found in error message.
1095 callable_obj: Function to be called.
1096 args: Extra args.
1097 kwargs: Extra kwargs.
1098 """
1099 context = _AssertRaisesContext(expected_exception, self, callable_obj,
1100 expected_regexp)
1101 if callable_obj is None:
1102 return context
1103 with context:
1104 callable_obj(*args, **kwargs)
1105
Antoine Pitrou4bc12ef2010-09-06 19:25:46 +00001106 def assertWarnsRegexp(self, expected_warning, expected_regexp,
1107 callable_obj=None, *args, **kwargs):
1108 """Asserts that the message in a triggered warning matches a regexp.
1109 Basic functioning is similar to assertWarns() with the addition
1110 that only warnings whose messages also match the regular expression
1111 are considered successful matches.
1112
1113 Args:
1114 expected_warning: Warning class expected to be triggered.
1115 expected_regexp: Regexp (re pattern object or string) expected
1116 to be found in error message.
1117 callable_obj: Function to be called.
1118 args: Extra args.
1119 kwargs: Extra kwargs.
1120 """
1121 context = _AssertWarnsContext(expected_warning, self, callable_obj,
1122 expected_regexp)
1123 if callable_obj is None:
1124 return context
1125 with context:
1126 callable_obj(*args, **kwargs)
1127
Georg Brandl89fad142010-03-14 10:23:39 +00001128 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001129 """Fail the test unless the text matches the regular expression."""
Georg Brandl89fad142010-03-14 10:23:39 +00001130 if isinstance(expected_regexp, (str, bytes)):
1131 expected_regexp = re.compile(expected_regexp)
1132 if not expected_regexp.search(text):
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001133 msg = msg or "Regexp didn't match"
Georg Brandl89fad142010-03-14 10:23:39 +00001134 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001135 raise self.failureException(msg)
1136
Benjamin Petersonb48af542010-04-11 20:43:16 +00001137 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001138 """Fail the test if the text matches the regular expression."""
Benjamin Petersonb48af542010-04-11 20:43:16 +00001139 if isinstance(unexpected_regexp, (str, bytes)):
1140 unexpected_regexp = re.compile(unexpected_regexp)
1141 match = unexpected_regexp.search(text)
1142 if match:
1143 msg = msg or "Regexp matched"
1144 msg = '%s: %r matches %r in %r' % (msg,
1145 text[match.start():match.end()],
1146 unexpected_regexp.pattern,
1147 text)
1148 raise self.failureException(msg)
1149
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001150
1151class FunctionTestCase(TestCase):
1152 """A test case that wraps a test function.
1153
1154 This is useful for slipping pre-existing test functions into the
1155 unittest framework. Optionally, set-up and tidy-up functions can be
1156 supplied. As with TestCase, the tidy-up ('tearDown') function will
1157 always be called if the set-up ('setUp') function ran successfully.
1158 """
1159
1160 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1161 super(FunctionTestCase, self).__init__()
1162 self._setUpFunc = setUp
1163 self._tearDownFunc = tearDown
1164 self._testFunc = testFunc
1165 self._description = description
1166
1167 def setUp(self):
1168 if self._setUpFunc is not None:
1169 self._setUpFunc()
1170
1171 def tearDown(self):
1172 if self._tearDownFunc is not None:
1173 self._tearDownFunc()
1174
1175 def runTest(self):
1176 self._testFunc()
1177
1178 def id(self):
1179 return self._testFunc.__name__
1180
1181 def __eq__(self, other):
1182 if not isinstance(other, self.__class__):
1183 return NotImplemented
1184
1185 return self._setUpFunc == other._setUpFunc and \
1186 self._tearDownFunc == other._tearDownFunc and \
1187 self._testFunc == other._testFunc and \
1188 self._description == other._description
1189
1190 def __ne__(self, other):
1191 return not self == other
1192
1193 def __hash__(self):
1194 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1195 self._testFunc, self._description))
1196
1197 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001198 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001199 self._testFunc.__name__)
1200
1201 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001202 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001203 self._testFunc)
1204
1205 def shortDescription(self):
1206 if self._description is not None:
1207 return self._description
1208 doc = self._testFunc.__doc__
1209 return doc and doc.split("\n")[0].strip() or None