blob: 366fe8703c32679e5f646dbd6277d715a46e5437 [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
15
Benjamin Petersonbed7d042009-07-19 21:01:52 +000016
17class SkipTest(Exception):
18 """
19 Raise this exception in a test to skip it.
20
21 Usually you can use TestResult.skip() or one of the skipping decorators
22 instead of raising this directly.
23 """
24 pass
25
26class _ExpectedFailure(Exception):
27 """
28 Raise this when a test is expected to fail.
29
30 This is an implementation detail.
31 """
32
33 def __init__(self, exc_info):
34 super(_ExpectedFailure, self).__init__()
35 self.exc_info = exc_info
36
37class _UnexpectedSuccess(Exception):
38 """
39 The test was supposed to fail, but it didn't!
40 """
41 pass
42
43def _id(obj):
44 return obj
45
46def skip(reason):
47 """
48 Unconditionally skip a test.
49 """
50 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000051 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
52 @functools.wraps(test_item)
53 def skip_wrapper(*args, **kwargs):
54 raise SkipTest(reason)
55 test_item = skip_wrapper
56
57 test_item.__unittest_skip__ = True
58 test_item.__unittest_skip_why__ = reason
59 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000060 return decorator
61
62def skipIf(condition, reason):
63 """
64 Skip a test if the condition is true.
65 """
66 if condition:
67 return skip(reason)
68 return _id
69
70def skipUnless(condition, reason):
71 """
72 Skip a test unless the condition is true.
73 """
74 if not condition:
75 return skip(reason)
76 return _id
77
78
79def expectedFailure(func):
80 @functools.wraps(func)
81 def wrapper(*args, **kwargs):
82 try:
83 func(*args, **kwargs)
84 except Exception:
85 raise _ExpectedFailure(sys.exc_info())
86 raise _UnexpectedSuccess
87 return wrapper
88
89
90class _AssertRaisesContext(object):
91 """A context manager used to implement TestCase.assertRaises* methods."""
92
93 def __init__(self, expected, test_case, callable_obj=None,
94 expected_regexp=None):
95 self.expected = expected
96 self.failureException = test_case.failureException
97 if callable_obj is not None:
98 try:
99 self.obj_name = callable_obj.__name__
100 except AttributeError:
101 self.obj_name = str(callable_obj)
102 else:
103 self.obj_name = None
Georg Brandl89fad142010-03-14 10:23:39 +0000104 self.expected_regexp = expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000105
106 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000107 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000108
109 def __exit__(self, exc_type, exc_value, tb):
110 if exc_type is None:
111 try:
112 exc_name = self.expected.__name__
113 except AttributeError:
114 exc_name = str(self.expected)
115 if self.obj_name:
116 raise self.failureException("{0} not raised by {1}"
117 .format(exc_name, self.obj_name))
118 else:
119 raise self.failureException("{0} not raised"
120 .format(exc_name))
121 if not issubclass(exc_type, self.expected):
122 # let unexpected exceptions pass through
123 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000124 # store exception, without traceback, for later retrieval
125 self.exception = exc_value.with_traceback(None)
Georg Brandl89fad142010-03-14 10:23:39 +0000126 if self.expected_regexp is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000127 return True
128
Georg Brandl89fad142010-03-14 10:23:39 +0000129 expected_regexp = self.expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000130 if isinstance(expected_regexp, (bytes, str)):
131 expected_regexp = re.compile(expected_regexp)
132 if not expected_regexp.search(str(exc_value)):
133 raise self.failureException('"%s" does not match "%s"' %
134 (expected_regexp.pattern, str(exc_value)))
135 return True
136
137
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000138class TestCase(object):
139 """A class whose instances are single test cases.
140
141 By default, the test code itself should be placed in a method named
142 'runTest'.
143
144 If the fixture may be used for many test cases, create as
145 many test methods as are needed. When instantiating such a TestCase
146 subclass, specify in the constructor arguments the name of the test method
147 that the instance is to execute.
148
149 Test authors should subclass TestCase for their own tests. Construction
150 and deconstruction of the test's environment ('fixture') can be
151 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
152
153 If it is necessary to override the __init__ method, the base class
154 __init__ method must always be called. It is important that subclasses
155 should not change the signature of their __init__ method, since instances
156 of the classes are instantiated automatically by parts of the framework
157 in order to be run.
158 """
159
160 # This attribute determines which exception will be raised when
161 # the instance's assertion methods fail; test methods raising this
162 # exception will be deemed to have 'failed' rather than 'errored'
163
164 failureException = AssertionError
165
166 # This attribute determines whether long messages (including repr of
167 # objects used in assert methods) will be printed on failure in *addition*
168 # to any explicit message passed.
169
170 longMessage = False
171
Benjamin Peterson847a4112010-03-14 15:04:17 +0000172 # Attribute used by TestSuite for classSetUp
173
174 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000175
176 def __init__(self, methodName='runTest'):
177 """Create an instance of the class that will use the named test
178 method when executed. Raises a ValueError if the instance does
179 not have a method with the specified name.
180 """
181 self._testMethodName = methodName
182 self._resultForDoCleanups = None
183 try:
184 testMethod = getattr(self, methodName)
185 except AttributeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000186 raise ValueError("no such test method in %s: %s" %
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000187 (self.__class__, methodName))
188 self._testMethodDoc = testMethod.__doc__
189 self._cleanups = []
190
191 # Map types to custom assertEqual functions that will compare
192 # instances of said type in more detail to generate a more useful
193 # error message.
194 self._type_equality_funcs = {}
195 self.addTypeEqualityFunc(dict, self.assertDictEqual)
196 self.addTypeEqualityFunc(list, self.assertListEqual)
197 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
198 self.addTypeEqualityFunc(set, self.assertSetEqual)
199 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foord02834952010-02-08 23:10:39 +0000200 self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000201
202 def addTypeEqualityFunc(self, typeobj, function):
203 """Add a type specific assertEqual style function to compare a type.
204
205 This method is for use by TestCase subclasses that need to register
206 their own type equality functions to provide nicer error messages.
207
208 Args:
209 typeobj: The data type to call this function on when both values
210 are of the same type in assertEqual().
211 function: The callable taking two arguments and an optional
212 msg= argument that raises self.failureException with a
213 useful error message when the two arguments are not equal.
214 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000215 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000216
217 def addCleanup(self, function, *args, **kwargs):
218 """Add a function, with arguments, to be called when the test is
219 completed. Functions added are called on a LIFO basis and are
220 called after tearDown on test failure or success.
221
222 Cleanup items are called even if setUp fails (unlike tearDown)."""
223 self._cleanups.append((function, args, kwargs))
224
225 def setUp(self):
226 "Hook method for setting up the test fixture before exercising it."
227 pass
228
229 def tearDown(self):
230 "Hook method for deconstructing the test fixture after testing it."
231 pass
232
Benjamin Peterson847a4112010-03-14 15:04:17 +0000233 @classmethod
234 def setUpClass(cls):
235 "Hook method for setting up class fixture before running tests in the class."
236
237 @classmethod
238 def tearDownClass(cls):
239 "Hook method for deconstructing the class fixture after running all tests in the class."
240
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000241 def countTestCases(self):
242 return 1
243
244 def defaultTestResult(self):
245 return result.TestResult()
246
247 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000248 """Returns a one-line description of the test, or None if no
249 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000250
Michael Foord34c94622010-02-10 15:51:42 +0000251 The default implementation of this method returns the first line of
252 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000253 """
Michael Foord34c94622010-02-10 15:51:42 +0000254 doc = self._testMethodDoc
255 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000256
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000257
258 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000259 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000260
261 def __eq__(self, other):
262 if type(self) is not type(other):
263 return NotImplemented
264
265 return self._testMethodName == other._testMethodName
266
267 def __ne__(self, other):
268 return not self == other
269
270 def __hash__(self):
271 return hash((type(self), self._testMethodName))
272
273 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000274 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000275
276 def __repr__(self):
277 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000278 (strclass(self.__class__), self._testMethodName)
279
280 def _addSkip(self, result, reason):
281 addSkip = getattr(result, 'addSkip', None)
282 if addSkip is not None:
283 addSkip(self, reason)
284 else:
285 warnings.warn("TestResult has no addSkip method, skips not reported",
286 RuntimeWarning, 2)
287 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000288
289 def run(self, result=None):
290 orig_result = result
291 if result is None:
292 result = self.defaultTestResult()
293 startTestRun = getattr(result, 'startTestRun', None)
294 if startTestRun is not None:
295 startTestRun()
296
297 self._resultForDoCleanups = result
298 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000299
300 testMethod = getattr(self, self._testMethodName)
301 if (getattr(self.__class__, "__unittest_skip__", False) or
302 getattr(testMethod, "__unittest_skip__", False)):
303 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000304 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000305 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
306 or getattr(testMethod, '__unittest_skip_why__', ''))
307 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000308 finally:
309 result.stopTest(self)
310 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000311 try:
312 success = False
313 try:
314 self.setUp()
315 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000316 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000317 except Exception:
318 result.addError(self, sys.exc_info())
319 else:
320 try:
321 testMethod()
322 except self.failureException:
323 result.addFailure(self, sys.exc_info())
324 except _ExpectedFailure as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000325 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
326 if addExpectedFailure is not None:
327 addExpectedFailure(self, e.exc_info)
328 else:
329 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
330 RuntimeWarning)
331 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000332 except _UnexpectedSuccess:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000333 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
334 if addUnexpectedSuccess is not None:
335 addUnexpectedSuccess(self)
336 else:
337 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
338 RuntimeWarning)
339 result.addFailure(self, sys.exc_info())
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000340 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000341 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000342 except Exception:
343 result.addError(self, sys.exc_info())
344 else:
345 success = True
346
347 try:
348 self.tearDown()
349 except Exception:
350 result.addError(self, sys.exc_info())
351 success = False
352
353 cleanUpSuccess = self.doCleanups()
354 success = success and cleanUpSuccess
355 if success:
356 result.addSuccess(self)
357 finally:
358 result.stopTest(self)
359 if orig_result is None:
360 stopTestRun = getattr(result, 'stopTestRun', None)
361 if stopTestRun is not None:
362 stopTestRun()
363
364 def doCleanups(self):
365 """Execute all cleanup functions. Normally called for you after
366 tearDown."""
367 result = self._resultForDoCleanups
368 ok = True
369 while self._cleanups:
370 function, args, kwargs = self._cleanups.pop(-1)
371 try:
372 function(*args, **kwargs)
373 except Exception:
374 ok = False
375 result.addError(self, sys.exc_info())
376 return ok
377
378 def __call__(self, *args, **kwds):
379 return self.run(*args, **kwds)
380
381 def debug(self):
382 """Run the test without collecting errors in a TestResult"""
383 self.setUp()
384 getattr(self, self._testMethodName)()
385 self.tearDown()
386
387 def skipTest(self, reason):
388 """Skip this test."""
389 raise SkipTest(reason)
390
391 def fail(self, msg=None):
392 """Fail immediately, with the given message."""
393 raise self.failureException(msg)
394
395 def assertFalse(self, expr, msg=None):
396 "Fail the test if the expression is true."
397 if expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000398 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000399 raise self.failureException(msg)
400
401 def assertTrue(self, expr, msg=None):
402 """Fail the test unless the expression is true."""
403 if not expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000404 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000405 raise self.failureException(msg)
406
407 def _formatMessage(self, msg, standardMsg):
408 """Honour the longMessage attribute when generating failure messages.
409 If longMessage is False this means:
410 * Use only an explicit message if it is provided
411 * Otherwise use the standard message for the assert
412
413 If longMessage is True:
414 * Use the standard message
415 * If an explicit message is provided, plus ' : ' and the explicit message
416 """
417 if not self.longMessage:
418 return msg or standardMsg
419 if msg is None:
420 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000421 try:
422 # don't switch to '{}' formatting in Python 2.X
423 # it changes the way unicode input is handled
424 return '%s : %s' % (standardMsg, msg)
425 except UnicodeDecodeError:
426 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000427
428
429 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
430 """Fail unless an exception of class excClass is thrown
431 by callableObj when invoked with arguments args and keyword
432 arguments kwargs. If a different type of exception is
433 thrown, it will not be caught, and the test case will be
434 deemed to have suffered an error, exactly as for an
435 unexpected exception.
436
437 If called with callableObj omitted or None, will return a
438 context object used like this::
439
Michael Foord1c42b122010-02-05 22:58:21 +0000440 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000441 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000442
443 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000444 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000445 exception after the assertion::
446
447 with self.assertRaises(SomeException) as cm:
448 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000449 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000450 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000451 """
452 context = _AssertRaisesContext(excClass, self, callableObj)
453 if callableObj is None:
454 return context
455 with context:
456 callableObj(*args, **kwargs)
457
458 def _getAssertEqualityFunc(self, first, second):
459 """Get a detailed comparison function for the types of the two args.
460
461 Returns: A callable accepting (first, second, msg=None) that will
462 raise a failure exception if first != second with a useful human
463 readable error message for those types.
464 """
465 #
466 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
467 # and vice versa. I opted for the conservative approach in case
468 # subclasses are not intended to be compared in detail to their super
469 # class instances using a type equality func. This means testing
470 # subtypes won't automagically use the detailed comparison. Callers
471 # should use their type specific assertSpamEqual method to compare
472 # subclasses if the detailed comparison is desired and appropriate.
473 # See the discussion in http://bugs.python.org/issue2578.
474 #
475 if type(first) is type(second):
476 asserter = self._type_equality_funcs.get(type(first))
477 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000478 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000479
480 return self._baseAssertEqual
481
482 def _baseAssertEqual(self, first, second, msg=None):
483 """The default assertEqual implementation, not type specific."""
484 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000485 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000486 msg = self._formatMessage(msg, standardMsg)
487 raise self.failureException(msg)
488
489 def assertEqual(self, first, second, msg=None):
490 """Fail if the two objects are unequal as determined by the '=='
491 operator.
492 """
493 assertion_func = self._getAssertEqualityFunc(first, second)
494 assertion_func(first, second, msg=msg)
495
496 def assertNotEqual(self, first, second, msg=None):
497 """Fail if the two objects are equal as determined by the '=='
498 operator.
499 """
500 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000501 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
502 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000503 raise self.failureException(msg)
504
Benjamin Petersonb48af542010-04-11 20:43:16 +0000505 def assertAlmostEqual(self, first, second, *, places=None, msg=None,
506 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000507 """Fail if the two objects are unequal as determined by their
508 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000509 (default 7) and comparing to zero, or by comparing that the
510 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000511
512 Note that decimal places (from zero) are usually not the same
513 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000514
515 If the two objects compare equal then they will automatically
516 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000517 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000518 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000519 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000520 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000521 if delta is not None and places is not None:
522 raise TypeError("specify delta or places not both")
523
524 if delta is not None:
525 if abs(first - second) <= delta:
526 return
527
528 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
529 safe_repr(second),
530 safe_repr(delta))
531 else:
532 if places is None:
533 places = 7
534
535 if round(abs(second-first), places) == 0:
536 return
537
Benjamin Peterson847a4112010-03-14 15:04:17 +0000538 standardMsg = '%s != %s within %r places' % (safe_repr(first),
539 safe_repr(second),
540 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000541 msg = self._formatMessage(msg, standardMsg)
542 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000543
Benjamin Petersonb48af542010-04-11 20:43:16 +0000544 def assertNotAlmostEqual(self, first, second, *, places=None, msg=None,
545 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000546 """Fail if the two objects are equal as determined by their
547 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000548 (default 7) and comparing to zero, or by comparing that the
549 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000550
551 Note that decimal places (from zero) are usually not the same
552 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000553
554 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000555 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000556 if delta is not None and places is not None:
557 raise TypeError("specify delta or places not both")
558 if delta is not None:
559 if not (first == second) and abs(first - second) > delta:
560 return
561 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
562 safe_repr(second),
563 safe_repr(delta))
564 else:
565 if places is None:
566 places = 7
567 if not (first == second) and round(abs(second-first), places) != 0:
568 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000569 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000570 safe_repr(second),
571 places)
572
573 msg = self._formatMessage(msg, standardMsg)
574 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000575
576 # Synonyms for assertion methods
577
578 # The plurals are undocumented. Keep them that way to discourage use.
579 # Do not add more. Do not remove.
580 # Going through a deprecation cycle on these would annoy many people.
581 assertEquals = assertEqual
582 assertNotEquals = assertNotEqual
583 assertAlmostEquals = assertAlmostEqual
584 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord0e31b992010-02-10 15:52:56 +0000585 assert_ = assertTrue
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000586
587 # These fail* assertion method names are pending deprecation and will
588 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
589 def _deprecate(original_func):
590 def deprecated_func(*args, **kwargs):
591 warnings.warn(
592 'Please use {0} instead.'.format(original_func.__name__),
593 DeprecationWarning, 2)
594 return original_func(*args, **kwargs)
595 return deprecated_func
596
597 failUnlessEqual = _deprecate(assertEqual)
598 failIfEqual = _deprecate(assertNotEqual)
599 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
600 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
601 failUnless = _deprecate(assertTrue)
602 failUnlessRaises = _deprecate(assertRaises)
603 failIf = _deprecate(assertFalse)
604
605 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
606 """An equality assertion for ordered sequences (like lists and tuples).
607
R. David Murrayad13f222010-01-29 22:17:58 +0000608 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000609 which can be indexed, has a length, and has an equality operator.
610
611 Args:
612 seq1: The first sequence to compare.
613 seq2: The second sequence to compare.
614 seq_type: The expected datatype of the sequences, or None if no
615 datatype should be enforced.
616 msg: Optional message to use on failure instead of a list of
617 differences.
618 """
619 if seq_type != None:
620 seq_type_name = seq_type.__name__
621 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000622 raise self.failureException('First sequence is not a %s: %s'
623 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000624 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000625 raise self.failureException('Second sequence is not a %s: %s'
626 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000627 else:
628 seq_type_name = "sequence"
629
630 differing = None
631 try:
632 len1 = len(seq1)
633 except (TypeError, NotImplementedError):
634 differing = 'First %s has no length. Non-sequence?' % (
635 seq_type_name)
636
637 if differing is None:
638 try:
639 len2 = len(seq2)
640 except (TypeError, NotImplementedError):
641 differing = 'Second %s has no length. Non-sequence?' % (
642 seq_type_name)
643
644 if differing is None:
645 if seq1 == seq2:
646 return
647
Benjamin Peterson847a4112010-03-14 15:04:17 +0000648 seq1_repr = safe_repr(seq1)
649 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000650 if len(seq1_repr) > 30:
651 seq1_repr = seq1_repr[:30] + '...'
652 if len(seq2_repr) > 30:
653 seq2_repr = seq2_repr[:30] + '...'
654 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
655 differing = '%ss differ: %s != %s\n' % elements
656
657 for i in range(min(len1, len2)):
658 try:
659 item1 = seq1[i]
660 except (TypeError, IndexError, NotImplementedError):
661 differing += ('\nUnable to index element %d of first %s\n' %
662 (i, seq_type_name))
663 break
664
665 try:
666 item2 = seq2[i]
667 except (TypeError, IndexError, NotImplementedError):
668 differing += ('\nUnable to index element %d of second %s\n' %
669 (i, seq_type_name))
670 break
671
672 if item1 != item2:
673 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
674 (i, item1, item2))
675 break
676 else:
677 if (len1 == len2 and seq_type is None and
678 type(seq1) != type(seq2)):
679 # The sequences are the same, but have differing types.
680 return
681
682 if len1 > len2:
683 differing += ('\nFirst %s contains %d additional '
684 'elements.\n' % (seq_type_name, len1 - len2))
685 try:
686 differing += ('First extra element %d:\n%s\n' %
687 (len2, seq1[len2]))
688 except (TypeError, IndexError, NotImplementedError):
689 differing += ('Unable to index element %d '
690 'of first %s\n' % (len2, seq_type_name))
691 elif len1 < len2:
692 differing += ('\nSecond %s contains %d additional '
693 'elements.\n' % (seq_type_name, len2 - len1))
694 try:
695 differing += ('First extra element %d:\n%s\n' %
696 (len1, seq2[len1]))
697 except (TypeError, IndexError, NotImplementedError):
698 differing += ('Unable to index element %d '
699 'of second %s\n' % (len1, seq_type_name))
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000700 standardMsg = differing + '\n' + '\n'.join(
701 difflib.ndiff(pprint.pformat(seq1).splitlines(),
702 pprint.pformat(seq2).splitlines()))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000703 msg = self._formatMessage(msg, standardMsg)
704 self.fail(msg)
705
706 def assertListEqual(self, list1, list2, msg=None):
707 """A list-specific equality assertion.
708
709 Args:
710 list1: The first list to compare.
711 list2: The second list to compare.
712 msg: Optional message to use on failure instead of a list of
713 differences.
714
715 """
716 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
717
718 def assertTupleEqual(self, tuple1, tuple2, msg=None):
719 """A tuple-specific equality assertion.
720
721 Args:
722 tuple1: The first tuple to compare.
723 tuple2: The second tuple to compare.
724 msg: Optional message to use on failure instead of a list of
725 differences.
726 """
727 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
728
729 def assertSetEqual(self, set1, set2, msg=None):
730 """A set-specific equality assertion.
731
732 Args:
733 set1: The first set to compare.
734 set2: The second set to compare.
735 msg: Optional message to use on failure instead of a list of
736 differences.
737
Michael Foord91c9da32010-03-20 17:21:27 +0000738 assertSetEqual uses ducktyping to support different types of sets, and
739 is optimized for sets specifically (parameters must support a
740 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000741 """
742 try:
743 difference1 = set1.difference(set2)
744 except TypeError as e:
745 self.fail('invalid type when attempting set difference: %s' % e)
746 except AttributeError as e:
747 self.fail('first argument does not support set difference: %s' % e)
748
749 try:
750 difference2 = set2.difference(set1)
751 except TypeError as e:
752 self.fail('invalid type when attempting set difference: %s' % e)
753 except AttributeError as e:
754 self.fail('second argument does not support set difference: %s' % e)
755
756 if not (difference1 or difference2):
757 return
758
759 lines = []
760 if difference1:
761 lines.append('Items in the first set but not the second:')
762 for item in difference1:
763 lines.append(repr(item))
764 if difference2:
765 lines.append('Items in the second set but not the first:')
766 for item in difference2:
767 lines.append(repr(item))
768
769 standardMsg = '\n'.join(lines)
770 self.fail(self._formatMessage(msg, standardMsg))
771
772 def assertIn(self, member, container, msg=None):
773 """Just like self.assertTrue(a in b), but with a nicer default message."""
774 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000775 standardMsg = '%s not found in %s' % (safe_repr(member),
776 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000777 self.fail(self._formatMessage(msg, standardMsg))
778
779 def assertNotIn(self, member, container, msg=None):
780 """Just like self.assertTrue(a not in b), but with a nicer default message."""
781 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000782 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
783 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000784 self.fail(self._formatMessage(msg, standardMsg))
785
786 def assertIs(self, expr1, expr2, msg=None):
787 """Just like self.assertTrue(a is b), but with a nicer default message."""
788 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000789 standardMsg = '%s is not %s' % (safe_repr(expr1),
790 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000791 self.fail(self._formatMessage(msg, standardMsg))
792
793 def assertIsNot(self, expr1, expr2, msg=None):
794 """Just like self.assertTrue(a is not b), but with a nicer default message."""
795 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000796 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000797 self.fail(self._formatMessage(msg, standardMsg))
798
799 def assertDictEqual(self, d1, d2, msg=None):
800 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
801 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
802
803 if d1 != d2:
804 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
805 pprint.pformat(d1).splitlines(),
806 pprint.pformat(d2).splitlines())))
807 self.fail(self._formatMessage(msg, standardMsg))
808
809 def assertDictContainsSubset(self, expected, actual, msg=None):
810 """Checks whether actual is a superset of expected."""
811 missing = []
812 mismatched = []
813 for key, value in expected.items():
814 if key not in actual:
815 missing.append(key)
816 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000817 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000818 (safe_repr(key), safe_repr(value),
819 safe_repr(actual[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000820
821 if not (missing or mismatched):
822 return
823
824 standardMsg = ''
825 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000826 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
827 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000828 if mismatched:
829 if standardMsg:
830 standardMsg += '; '
831 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
832
833 self.fail(self._formatMessage(msg, standardMsg))
834
835 def assertSameElements(self, expected_seq, actual_seq, msg=None):
836 """An unordered sequence specific comparison.
837
838 Raises with an error message listing which elements of expected_seq
839 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000840
841 Duplicate elements are ignored when comparing *expected_seq* and
842 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
843 set(actual))`` but it works with sequences of unhashable objects as
844 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000845 """
Michael Foord91c9da32010-03-20 17:21:27 +0000846 warnings.warn('assertSameElements is deprecated',
847 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000848 try:
849 expected = set(expected_seq)
850 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000851 missing = sorted(expected.difference(actual))
852 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000853 except TypeError:
854 # Fall back to slower list-compare if any of the objects are
855 # not hashable.
856 expected = list(expected_seq)
857 actual = list(actual_seq)
858 try:
859 expected.sort()
860 actual.sort()
861 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000862 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000863 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000864 else:
865 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000866 errors = []
867 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000868 errors.append('Expected, but missing:\n %s' %
869 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000870 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000871 errors.append('Unexpected, but present:\n %s' %
872 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000873 if errors:
874 standardMsg = '\n'.join(errors)
875 self.fail(self._formatMessage(msg, standardMsg))
876
Michael Foord8442a602010-03-20 16:58:04 +0000877
878 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
879 """An unordered sequence / set specific comparison. It asserts that
880 expected_seq and actual_seq contain the same elements. It is
881 the equivalent of::
882
883 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
884
885 Raises with an error message listing which elements of expected_seq
886 are missing from actual_seq and vice versa if any.
887
888 Asserts that each element has the same count in both sequences.
889 Example:
890 - [0, 1, 1] and [1, 0, 1] compare equal.
891 - [0, 0, 1] and [0, 1] compare unequal.
892 """
893 try:
894 expected = sorted(expected_seq)
895 actual = sorted(actual_seq)
896 except TypeError:
897 # Unsortable items (example: set(), complex(), ...)
898 expected = list(expected_seq)
899 actual = list(actual_seq)
900 missing, unexpected = unorderable_list_difference(expected, actual)
901 else:
902 return self.assertSequenceEqual(expected, actual, msg=msg)
903
904 errors = []
905 if missing:
906 errors.append('Expected, but missing:\n %s' %
907 safe_repr(missing))
908 if unexpected:
909 errors.append('Unexpected, but present:\n %s' %
910 safe_repr(unexpected))
911 if errors:
912 standardMsg = '\n'.join(errors)
913 self.fail(self._formatMessage(msg, standardMsg))
914
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000915 def assertMultiLineEqual(self, first, second, msg=None):
916 """Assert that two multi-line strings are equal."""
917 self.assert_(isinstance(first, str), (
918 'First argument is not a string'))
919 self.assert_(isinstance(second, str), (
920 'Second argument is not a string'))
921
922 if first != second:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000923 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
924 second.splitlines(True)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000925 self.fail(self._formatMessage(msg, standardMsg))
926
927 def assertLess(self, a, b, msg=None):
928 """Just like self.assertTrue(a < b), but with a nicer default message."""
929 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000930 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000931 self.fail(self._formatMessage(msg, standardMsg))
932
933 def assertLessEqual(self, a, b, msg=None):
934 """Just like self.assertTrue(a <= b), but with a nicer default message."""
935 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000936 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000937 self.fail(self._formatMessage(msg, standardMsg))
938
939 def assertGreater(self, a, b, msg=None):
940 """Just like self.assertTrue(a > b), but with a nicer default message."""
941 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000942 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000943 self.fail(self._formatMessage(msg, standardMsg))
944
945 def assertGreaterEqual(self, a, b, msg=None):
946 """Just like self.assertTrue(a >= b), but with a nicer default message."""
947 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000948 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000949 self.fail(self._formatMessage(msg, standardMsg))
950
951 def assertIsNone(self, obj, msg=None):
952 """Same as self.assertTrue(obj is None), with a nicer default message."""
953 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000954 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000955 self.fail(self._formatMessage(msg, standardMsg))
956
957 def assertIsNotNone(self, obj, msg=None):
958 """Included for symmetry with assertIsNone."""
959 if obj is None:
960 standardMsg = 'unexpectedly None'
961 self.fail(self._formatMessage(msg, standardMsg))
962
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000963 def assertIsInstance(self, obj, cls, msg=None):
964 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
965 default message."""
966 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000967 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000968 self.fail(self._formatMessage(msg, standardMsg))
969
970 def assertNotIsInstance(self, obj, cls, msg=None):
971 """Included for symmetry with assertIsInstance."""
972 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000973 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000974 self.fail(self._formatMessage(msg, standardMsg))
975
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000976 def assertRaisesRegexp(self, expected_exception, expected_regexp,
977 callable_obj=None, *args, **kwargs):
978 """Asserts that the message in a raised exception matches a regexp.
979
980 Args:
981 expected_exception: Exception class expected to be raised.
982 expected_regexp: Regexp (re pattern object or string) expected
983 to be found in error message.
984 callable_obj: Function to be called.
985 args: Extra args.
986 kwargs: Extra kwargs.
987 """
988 context = _AssertRaisesContext(expected_exception, self, callable_obj,
989 expected_regexp)
990 if callable_obj is None:
991 return context
992 with context:
993 callable_obj(*args, **kwargs)
994
Georg Brandl89fad142010-03-14 10:23:39 +0000995 def assertRegexpMatches(self, text, expected_regexp, msg=None):
996 if isinstance(expected_regexp, (str, bytes)):
997 expected_regexp = re.compile(expected_regexp)
998 if not expected_regexp.search(text):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000999 msg = msg or "Regexp didn't match"
Georg Brandl89fad142010-03-14 10:23:39 +00001000 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001001 raise self.failureException(msg)
1002
Benjamin Petersonb48af542010-04-11 20:43:16 +00001003 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
1004 if isinstance(unexpected_regexp, (str, bytes)):
1005 unexpected_regexp = re.compile(unexpected_regexp)
1006 match = unexpected_regexp.search(text)
1007 if match:
1008 msg = msg or "Regexp matched"
1009 msg = '%s: %r matches %r in %r' % (msg,
1010 text[match.start():match.end()],
1011 unexpected_regexp.pattern,
1012 text)
1013 raise self.failureException(msg)
1014
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001015
1016class FunctionTestCase(TestCase):
1017 """A test case that wraps a test function.
1018
1019 This is useful for slipping pre-existing test functions into the
1020 unittest framework. Optionally, set-up and tidy-up functions can be
1021 supplied. As with TestCase, the tidy-up ('tearDown') function will
1022 always be called if the set-up ('setUp') function ran successfully.
1023 """
1024
1025 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1026 super(FunctionTestCase, self).__init__()
1027 self._setUpFunc = setUp
1028 self._tearDownFunc = tearDown
1029 self._testFunc = testFunc
1030 self._description = description
1031
1032 def setUp(self):
1033 if self._setUpFunc is not None:
1034 self._setUpFunc()
1035
1036 def tearDown(self):
1037 if self._tearDownFunc is not None:
1038 self._tearDownFunc()
1039
1040 def runTest(self):
1041 self._testFunc()
1042
1043 def id(self):
1044 return self._testFunc.__name__
1045
1046 def __eq__(self, other):
1047 if not isinstance(other, self.__class__):
1048 return NotImplemented
1049
1050 return self._setUpFunc == other._setUpFunc and \
1051 self._tearDownFunc == other._tearDownFunc and \
1052 self._testFunc == other._testFunc and \
1053 self._description == other._description
1054
1055 def __ne__(self, other):
1056 return not self == other
1057
1058 def __hash__(self):
1059 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1060 self._testFunc, self._description))
1061
1062 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001063 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001064 self._testFunc.__name__)
1065
1066 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001067 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001068 self._testFunc)
1069
1070 def shortDescription(self):
1071 if self._description is not None:
1072 return self._description
1073 doc = self._testFunc.__doc__
1074 return doc and doc.split("\n")[0].strip() or None