blob: a072cf18979f756428bb150ad3261bdca51e2b37 [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
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000267 def __hash__(self):
268 return hash((type(self), self._testMethodName))
269
270 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000271 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000272
273 def __repr__(self):
274 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000275 (strclass(self.__class__), self._testMethodName)
276
277 def _addSkip(self, result, reason):
278 addSkip = getattr(result, 'addSkip', None)
279 if addSkip is not None:
280 addSkip(self, reason)
281 else:
282 warnings.warn("TestResult has no addSkip method, skips not reported",
283 RuntimeWarning, 2)
284 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000285
286 def run(self, result=None):
287 orig_result = result
288 if result is None:
289 result = self.defaultTestResult()
290 startTestRun = getattr(result, 'startTestRun', None)
291 if startTestRun is not None:
292 startTestRun()
293
294 self._resultForDoCleanups = result
295 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000296
297 testMethod = getattr(self, self._testMethodName)
298 if (getattr(self.__class__, "__unittest_skip__", False) or
299 getattr(testMethod, "__unittest_skip__", False)):
300 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000301 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000302 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
303 or getattr(testMethod, '__unittest_skip_why__', ''))
304 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000305 finally:
306 result.stopTest(self)
307 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000308 try:
309 success = False
310 try:
311 self.setUp()
312 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000313 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000314 except Exception:
315 result.addError(self, sys.exc_info())
316 else:
317 try:
318 testMethod()
319 except self.failureException:
320 result.addFailure(self, sys.exc_info())
321 except _ExpectedFailure as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000322 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
323 if addExpectedFailure is not None:
324 addExpectedFailure(self, e.exc_info)
325 else:
326 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
327 RuntimeWarning)
328 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000329 except _UnexpectedSuccess:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000330 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
331 if addUnexpectedSuccess is not None:
332 addUnexpectedSuccess(self)
333 else:
334 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
335 RuntimeWarning)
336 result.addFailure(self, sys.exc_info())
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000337 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000338 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000339 except Exception:
340 result.addError(self, sys.exc_info())
341 else:
342 success = True
343
344 try:
345 self.tearDown()
346 except Exception:
347 result.addError(self, sys.exc_info())
348 success = False
349
350 cleanUpSuccess = self.doCleanups()
351 success = success and cleanUpSuccess
352 if success:
353 result.addSuccess(self)
354 finally:
355 result.stopTest(self)
356 if orig_result is None:
357 stopTestRun = getattr(result, 'stopTestRun', None)
358 if stopTestRun is not None:
359 stopTestRun()
360
361 def doCleanups(self):
362 """Execute all cleanup functions. Normally called for you after
363 tearDown."""
364 result = self._resultForDoCleanups
365 ok = True
366 while self._cleanups:
367 function, args, kwargs = self._cleanups.pop(-1)
368 try:
369 function(*args, **kwargs)
370 except Exception:
371 ok = False
372 result.addError(self, sys.exc_info())
373 return ok
374
375 def __call__(self, *args, **kwds):
376 return self.run(*args, **kwds)
377
378 def debug(self):
379 """Run the test without collecting errors in a TestResult"""
380 self.setUp()
381 getattr(self, self._testMethodName)()
382 self.tearDown()
383
384 def skipTest(self, reason):
385 """Skip this test."""
386 raise SkipTest(reason)
387
388 def fail(self, msg=None):
389 """Fail immediately, with the given message."""
390 raise self.failureException(msg)
391
392 def assertFalse(self, expr, msg=None):
393 "Fail the test if the expression is true."
394 if expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000395 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000396 raise self.failureException(msg)
397
398 def assertTrue(self, expr, msg=None):
399 """Fail the test unless the expression is true."""
400 if not expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000401 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000402 raise self.failureException(msg)
403
404 def _formatMessage(self, msg, standardMsg):
405 """Honour the longMessage attribute when generating failure messages.
406 If longMessage is False this means:
407 * Use only an explicit message if it is provided
408 * Otherwise use the standard message for the assert
409
410 If longMessage is True:
411 * Use the standard message
412 * If an explicit message is provided, plus ' : ' and the explicit message
413 """
414 if not self.longMessage:
415 return msg or standardMsg
416 if msg is None:
417 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000418 try:
419 # don't switch to '{}' formatting in Python 2.X
420 # it changes the way unicode input is handled
421 return '%s : %s' % (standardMsg, msg)
422 except UnicodeDecodeError:
423 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000424
425
426 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
427 """Fail unless an exception of class excClass is thrown
428 by callableObj when invoked with arguments args and keyword
429 arguments kwargs. If a different type of exception is
430 thrown, it will not be caught, and the test case will be
431 deemed to have suffered an error, exactly as for an
432 unexpected exception.
433
434 If called with callableObj omitted or None, will return a
435 context object used like this::
436
Michael Foord1c42b122010-02-05 22:58:21 +0000437 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000438 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000439
440 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000441 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000442 exception after the assertion::
443
444 with self.assertRaises(SomeException) as cm:
445 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000446 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000447 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000448 """
449 context = _AssertRaisesContext(excClass, self, callableObj)
450 if callableObj is None:
451 return context
452 with context:
453 callableObj(*args, **kwargs)
454
455 def _getAssertEqualityFunc(self, first, second):
456 """Get a detailed comparison function for the types of the two args.
457
458 Returns: A callable accepting (first, second, msg=None) that will
459 raise a failure exception if first != second with a useful human
460 readable error message for those types.
461 """
462 #
463 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
464 # and vice versa. I opted for the conservative approach in case
465 # subclasses are not intended to be compared in detail to their super
466 # class instances using a type equality func. This means testing
467 # subtypes won't automagically use the detailed comparison. Callers
468 # should use their type specific assertSpamEqual method to compare
469 # subclasses if the detailed comparison is desired and appropriate.
470 # See the discussion in http://bugs.python.org/issue2578.
471 #
472 if type(first) is type(second):
473 asserter = self._type_equality_funcs.get(type(first))
474 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000475 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000476
477 return self._baseAssertEqual
478
479 def _baseAssertEqual(self, first, second, msg=None):
480 """The default assertEqual implementation, not type specific."""
481 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000482 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000483 msg = self._formatMessage(msg, standardMsg)
484 raise self.failureException(msg)
485
486 def assertEqual(self, first, second, msg=None):
487 """Fail if the two objects are unequal as determined by the '=='
488 operator.
489 """
490 assertion_func = self._getAssertEqualityFunc(first, second)
491 assertion_func(first, second, msg=msg)
492
493 def assertNotEqual(self, first, second, msg=None):
494 """Fail if the two objects are equal as determined by the '=='
495 operator.
496 """
497 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000498 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
499 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000500 raise self.failureException(msg)
501
Benjamin Petersonb48af542010-04-11 20:43:16 +0000502 def assertAlmostEqual(self, first, second, *, places=None, msg=None,
503 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000504 """Fail if the two objects are unequal as determined by their
505 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000506 (default 7) and comparing to zero, or by comparing that the
507 between the two objects is more than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000508
509 Note that decimal places (from zero) are usually not the same
510 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000511
512 If the two objects compare equal then they will automatically
513 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000514 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000515 if first == second:
Benjamin Petersonb48af542010-04-11 20:43:16 +0000516 # shortcut
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000517 return
Benjamin Petersonb48af542010-04-11 20:43:16 +0000518 if delta is not None and places is not None:
519 raise TypeError("specify delta or places not both")
520
521 if delta is not None:
522 if abs(first - second) <= delta:
523 return
524
525 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
526 safe_repr(second),
527 safe_repr(delta))
528 else:
529 if places is None:
530 places = 7
531
532 if round(abs(second-first), places) == 0:
533 return
534
Benjamin Peterson847a4112010-03-14 15:04:17 +0000535 standardMsg = '%s != %s within %r places' % (safe_repr(first),
536 safe_repr(second),
537 places)
Benjamin Petersonb48af542010-04-11 20:43:16 +0000538 msg = self._formatMessage(msg, standardMsg)
539 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000540
Benjamin Petersonb48af542010-04-11 20:43:16 +0000541 def assertNotAlmostEqual(self, first, second, *, places=None, msg=None,
542 delta=None):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000543 """Fail if the two objects are equal as determined by their
544 difference rounded to the given number of decimal places
Benjamin Petersonb48af542010-04-11 20:43:16 +0000545 (default 7) and comparing to zero, or by comparing that the
546 between the two objects is less than the given delta.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000547
548 Note that decimal places (from zero) are usually not the same
549 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000550
551 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000552 """
Benjamin Petersonb48af542010-04-11 20:43:16 +0000553 if delta is not None and places is not None:
554 raise TypeError("specify delta or places not both")
555 if delta is not None:
556 if not (first == second) and abs(first - second) > delta:
557 return
558 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
559 safe_repr(second),
560 safe_repr(delta))
561 else:
562 if places is None:
563 places = 7
564 if not (first == second) and round(abs(second-first), places) != 0:
565 return
Benjamin Peterson847a4112010-03-14 15:04:17 +0000566 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Benjamin Petersonb48af542010-04-11 20:43:16 +0000567 safe_repr(second),
568 places)
569
570 msg = self._formatMessage(msg, standardMsg)
571 raise self.failureException(msg)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000572
573 # Synonyms for assertion methods
574
575 # The plurals are undocumented. Keep them that way to discourage use.
576 # Do not add more. Do not remove.
577 # Going through a deprecation cycle on these would annoy many people.
578 assertEquals = assertEqual
579 assertNotEquals = assertNotEqual
580 assertAlmostEquals = assertAlmostEqual
581 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord0e31b992010-02-10 15:52:56 +0000582 assert_ = assertTrue
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000583
584 # These fail* assertion method names are pending deprecation and will
585 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
586 def _deprecate(original_func):
587 def deprecated_func(*args, **kwargs):
588 warnings.warn(
589 'Please use {0} instead.'.format(original_func.__name__),
590 DeprecationWarning, 2)
591 return original_func(*args, **kwargs)
592 return deprecated_func
593
594 failUnlessEqual = _deprecate(assertEqual)
595 failIfEqual = _deprecate(assertNotEqual)
596 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
597 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
598 failUnless = _deprecate(assertTrue)
599 failUnlessRaises = _deprecate(assertRaises)
600 failIf = _deprecate(assertFalse)
601
602 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
603 """An equality assertion for ordered sequences (like lists and tuples).
604
R. David Murrayad13f222010-01-29 22:17:58 +0000605 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000606 which can be indexed, has a length, and has an equality operator.
607
608 Args:
609 seq1: The first sequence to compare.
610 seq2: The second sequence to compare.
611 seq_type: The expected datatype of the sequences, or None if no
612 datatype should be enforced.
613 msg: Optional message to use on failure instead of a list of
614 differences.
615 """
616 if seq_type != None:
617 seq_type_name = seq_type.__name__
618 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000619 raise self.failureException('First sequence is not a %s: %s'
620 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000621 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000622 raise self.failureException('Second sequence is not a %s: %s'
623 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000624 else:
625 seq_type_name = "sequence"
626
627 differing = None
628 try:
629 len1 = len(seq1)
630 except (TypeError, NotImplementedError):
631 differing = 'First %s has no length. Non-sequence?' % (
632 seq_type_name)
633
634 if differing is None:
635 try:
636 len2 = len(seq2)
637 except (TypeError, NotImplementedError):
638 differing = 'Second %s has no length. Non-sequence?' % (
639 seq_type_name)
640
641 if differing is None:
642 if seq1 == seq2:
643 return
644
Benjamin Peterson847a4112010-03-14 15:04:17 +0000645 seq1_repr = safe_repr(seq1)
646 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000647 if len(seq1_repr) > 30:
648 seq1_repr = seq1_repr[:30] + '...'
649 if len(seq2_repr) > 30:
650 seq2_repr = seq2_repr[:30] + '...'
651 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
652 differing = '%ss differ: %s != %s\n' % elements
653
654 for i in range(min(len1, len2)):
655 try:
656 item1 = seq1[i]
657 except (TypeError, IndexError, NotImplementedError):
658 differing += ('\nUnable to index element %d of first %s\n' %
659 (i, seq_type_name))
660 break
661
662 try:
663 item2 = seq2[i]
664 except (TypeError, IndexError, NotImplementedError):
665 differing += ('\nUnable to index element %d of second %s\n' %
666 (i, seq_type_name))
667 break
668
669 if item1 != item2:
670 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
671 (i, item1, item2))
672 break
673 else:
674 if (len1 == len2 and seq_type is None and
675 type(seq1) != type(seq2)):
676 # The sequences are the same, but have differing types.
677 return
678
679 if len1 > len2:
680 differing += ('\nFirst %s contains %d additional '
681 'elements.\n' % (seq_type_name, len1 - len2))
682 try:
683 differing += ('First extra element %d:\n%s\n' %
684 (len2, seq1[len2]))
685 except (TypeError, IndexError, NotImplementedError):
686 differing += ('Unable to index element %d '
687 'of first %s\n' % (len2, seq_type_name))
688 elif len1 < len2:
689 differing += ('\nSecond %s contains %d additional '
690 'elements.\n' % (seq_type_name, len2 - len1))
691 try:
692 differing += ('First extra element %d:\n%s\n' %
693 (len1, seq2[len1]))
694 except (TypeError, IndexError, NotImplementedError):
695 differing += ('Unable to index element %d '
696 'of second %s\n' % (len1, seq_type_name))
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000697 standardMsg = differing + '\n' + '\n'.join(
698 difflib.ndiff(pprint.pformat(seq1).splitlines(),
699 pprint.pformat(seq2).splitlines()))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000700 msg = self._formatMessage(msg, standardMsg)
701 self.fail(msg)
702
703 def assertListEqual(self, list1, list2, msg=None):
704 """A list-specific equality assertion.
705
706 Args:
707 list1: The first list to compare.
708 list2: The second list to compare.
709 msg: Optional message to use on failure instead of a list of
710 differences.
711
712 """
713 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
714
715 def assertTupleEqual(self, tuple1, tuple2, msg=None):
716 """A tuple-specific equality assertion.
717
718 Args:
719 tuple1: The first tuple to compare.
720 tuple2: The second tuple to compare.
721 msg: Optional message to use on failure instead of a list of
722 differences.
723 """
724 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
725
726 def assertSetEqual(self, set1, set2, msg=None):
727 """A set-specific equality assertion.
728
729 Args:
730 set1: The first set to compare.
731 set2: The second set to compare.
732 msg: Optional message to use on failure instead of a list of
733 differences.
734
Michael Foord91c9da32010-03-20 17:21:27 +0000735 assertSetEqual uses ducktyping to support different types of sets, and
736 is optimized for sets specifically (parameters must support a
737 difference method).
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000738 """
739 try:
740 difference1 = set1.difference(set2)
741 except TypeError as e:
742 self.fail('invalid type when attempting set difference: %s' % e)
743 except AttributeError as e:
744 self.fail('first argument does not support set difference: %s' % e)
745
746 try:
747 difference2 = set2.difference(set1)
748 except TypeError as e:
749 self.fail('invalid type when attempting set difference: %s' % e)
750 except AttributeError as e:
751 self.fail('second argument does not support set difference: %s' % e)
752
753 if not (difference1 or difference2):
754 return
755
756 lines = []
757 if difference1:
758 lines.append('Items in the first set but not the second:')
759 for item in difference1:
760 lines.append(repr(item))
761 if difference2:
762 lines.append('Items in the second set but not the first:')
763 for item in difference2:
764 lines.append(repr(item))
765
766 standardMsg = '\n'.join(lines)
767 self.fail(self._formatMessage(msg, standardMsg))
768
769 def assertIn(self, member, container, msg=None):
770 """Just like self.assertTrue(a in b), but with a nicer default message."""
771 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000772 standardMsg = '%s not found in %s' % (safe_repr(member),
773 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000774 self.fail(self._formatMessage(msg, standardMsg))
775
776 def assertNotIn(self, member, container, msg=None):
777 """Just like self.assertTrue(a not in b), but with a nicer default message."""
778 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000779 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
780 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000781 self.fail(self._formatMessage(msg, standardMsg))
782
783 def assertIs(self, expr1, expr2, msg=None):
784 """Just like self.assertTrue(a is b), but with a nicer default message."""
785 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000786 standardMsg = '%s is not %s' % (safe_repr(expr1),
787 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000788 self.fail(self._formatMessage(msg, standardMsg))
789
790 def assertIsNot(self, expr1, expr2, msg=None):
791 """Just like self.assertTrue(a is not b), but with a nicer default message."""
792 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000793 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000794 self.fail(self._formatMessage(msg, standardMsg))
795
796 def assertDictEqual(self, d1, d2, msg=None):
797 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
798 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
799
800 if d1 != d2:
801 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
802 pprint.pformat(d1).splitlines(),
803 pprint.pformat(d2).splitlines())))
804 self.fail(self._formatMessage(msg, standardMsg))
805
806 def assertDictContainsSubset(self, expected, actual, msg=None):
807 """Checks whether actual is a superset of expected."""
808 missing = []
809 mismatched = []
810 for key, value in expected.items():
811 if key not in actual:
812 missing.append(key)
813 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000814 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000815 (safe_repr(key), safe_repr(value),
816 safe_repr(actual[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000817
818 if not (missing or mismatched):
819 return
820
821 standardMsg = ''
822 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000823 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
824 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000825 if mismatched:
826 if standardMsg:
827 standardMsg += '; '
828 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
829
830 self.fail(self._formatMessage(msg, standardMsg))
831
832 def assertSameElements(self, expected_seq, actual_seq, msg=None):
833 """An unordered sequence specific comparison.
834
835 Raises with an error message listing which elements of expected_seq
836 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000837
838 Duplicate elements are ignored when comparing *expected_seq* and
839 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
840 set(actual))`` but it works with sequences of unhashable objects as
841 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000842 """
Michael Foord91c9da32010-03-20 17:21:27 +0000843 warnings.warn('assertSameElements is deprecated',
844 DeprecationWarning)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000845 try:
846 expected = set(expected_seq)
847 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000848 missing = sorted(expected.difference(actual))
849 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000850 except TypeError:
851 # Fall back to slower list-compare if any of the objects are
852 # not hashable.
853 expected = list(expected_seq)
854 actual = list(actual_seq)
855 try:
856 expected.sort()
857 actual.sort()
858 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000859 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000860 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000861 else:
862 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000863 errors = []
864 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000865 errors.append('Expected, but missing:\n %s' %
866 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000867 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000868 errors.append('Unexpected, but present:\n %s' %
869 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000870 if errors:
871 standardMsg = '\n'.join(errors)
872 self.fail(self._formatMessage(msg, standardMsg))
873
Michael Foord8442a602010-03-20 16:58:04 +0000874
875 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
876 """An unordered sequence / set specific comparison. It asserts that
877 expected_seq and actual_seq contain the same elements. It is
878 the equivalent of::
879
880 self.assertEqual(sorted(expected_seq), sorted(actual_seq))
881
882 Raises with an error message listing which elements of expected_seq
883 are missing from actual_seq and vice versa if any.
884
885 Asserts that each element has the same count in both sequences.
886 Example:
887 - [0, 1, 1] and [1, 0, 1] compare equal.
888 - [0, 0, 1] and [0, 1] compare unequal.
889 """
890 try:
891 expected = sorted(expected_seq)
892 actual = sorted(actual_seq)
893 except TypeError:
894 # Unsortable items (example: set(), complex(), ...)
895 expected = list(expected_seq)
896 actual = list(actual_seq)
897 missing, unexpected = unorderable_list_difference(expected, actual)
898 else:
899 return self.assertSequenceEqual(expected, actual, msg=msg)
900
901 errors = []
902 if missing:
903 errors.append('Expected, but missing:\n %s' %
904 safe_repr(missing))
905 if unexpected:
906 errors.append('Unexpected, but present:\n %s' %
907 safe_repr(unexpected))
908 if errors:
909 standardMsg = '\n'.join(errors)
910 self.fail(self._formatMessage(msg, standardMsg))
911
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000912 def assertMultiLineEqual(self, first, second, msg=None):
913 """Assert that two multi-line strings are equal."""
914 self.assert_(isinstance(first, str), (
915 'First argument is not a string'))
916 self.assert_(isinstance(second, str), (
917 'Second argument is not a string'))
918
919 if first != second:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000920 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
921 second.splitlines(True)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000922 self.fail(self._formatMessage(msg, standardMsg))
923
924 def assertLess(self, a, b, msg=None):
925 """Just like self.assertTrue(a < b), but with a nicer default message."""
926 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000927 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000928 self.fail(self._formatMessage(msg, standardMsg))
929
930 def assertLessEqual(self, a, b, msg=None):
931 """Just like self.assertTrue(a <= b), but with a nicer default message."""
932 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000933 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000934 self.fail(self._formatMessage(msg, standardMsg))
935
936 def assertGreater(self, a, b, msg=None):
937 """Just like self.assertTrue(a > b), but with a nicer default message."""
938 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000939 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000940 self.fail(self._formatMessage(msg, standardMsg))
941
942 def assertGreaterEqual(self, a, b, msg=None):
943 """Just like self.assertTrue(a >= b), but with a nicer default message."""
944 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000945 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000946 self.fail(self._formatMessage(msg, standardMsg))
947
948 def assertIsNone(self, obj, msg=None):
949 """Same as self.assertTrue(obj is None), with a nicer default message."""
950 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000951 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000952 self.fail(self._formatMessage(msg, standardMsg))
953
954 def assertIsNotNone(self, obj, msg=None):
955 """Included for symmetry with assertIsNone."""
956 if obj is None:
957 standardMsg = 'unexpectedly None'
958 self.fail(self._formatMessage(msg, standardMsg))
959
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000960 def assertIsInstance(self, obj, cls, msg=None):
961 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
962 default message."""
963 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000964 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000965 self.fail(self._formatMessage(msg, standardMsg))
966
967 def assertNotIsInstance(self, obj, cls, msg=None):
968 """Included for symmetry with assertIsInstance."""
969 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000970 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000971 self.fail(self._formatMessage(msg, standardMsg))
972
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000973 def assertRaisesRegexp(self, expected_exception, expected_regexp,
974 callable_obj=None, *args, **kwargs):
975 """Asserts that the message in a raised exception matches a regexp.
976
977 Args:
978 expected_exception: Exception class expected to be raised.
979 expected_regexp: Regexp (re pattern object or string) expected
980 to be found in error message.
981 callable_obj: Function to be called.
982 args: Extra args.
983 kwargs: Extra kwargs.
984 """
985 context = _AssertRaisesContext(expected_exception, self, callable_obj,
986 expected_regexp)
987 if callable_obj is None:
988 return context
989 with context:
990 callable_obj(*args, **kwargs)
991
Georg Brandl89fad142010-03-14 10:23:39 +0000992 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +0000993 """Fail the test unless the text matches the regular expression."""
Georg Brandl89fad142010-03-14 10:23:39 +0000994 if isinstance(expected_regexp, (str, bytes)):
995 expected_regexp = re.compile(expected_regexp)
996 if not expected_regexp.search(text):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000997 msg = msg or "Regexp didn't match"
Georg Brandl89fad142010-03-14 10:23:39 +0000998 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000999 raise self.failureException(msg)
1000
Benjamin Petersonb48af542010-04-11 20:43:16 +00001001 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foorde3ef5f12010-05-08 16:46:14 +00001002 """Fail the test if the text matches the regular expression."""
Benjamin Petersonb48af542010-04-11 20:43:16 +00001003 if isinstance(unexpected_regexp, (str, bytes)):
1004 unexpected_regexp = re.compile(unexpected_regexp)
1005 match = unexpected_regexp.search(text)
1006 if match:
1007 msg = msg or "Regexp matched"
1008 msg = '%s: %r matches %r in %r' % (msg,
1009 text[match.start():match.end()],
1010 unexpected_regexp.pattern,
1011 text)
1012 raise self.failureException(msg)
1013
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001014
1015class FunctionTestCase(TestCase):
1016 """A test case that wraps a test function.
1017
1018 This is useful for slipping pre-existing test functions into the
1019 unittest framework. Optionally, set-up and tidy-up functions can be
1020 supplied. As with TestCase, the tidy-up ('tearDown') function will
1021 always be called if the set-up ('setUp') function ran successfully.
1022 """
1023
1024 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1025 super(FunctionTestCase, self).__init__()
1026 self._setUpFunc = setUp
1027 self._tearDownFunc = tearDown
1028 self._testFunc = testFunc
1029 self._description = description
1030
1031 def setUp(self):
1032 if self._setUpFunc is not None:
1033 self._setUpFunc()
1034
1035 def tearDown(self):
1036 if self._tearDownFunc is not None:
1037 self._tearDownFunc()
1038
1039 def runTest(self):
1040 self._testFunc()
1041
1042 def id(self):
1043 return self._testFunc.__name__
1044
1045 def __eq__(self, other):
1046 if not isinstance(other, self.__class__):
1047 return NotImplemented
1048
1049 return self._setUpFunc == other._setUpFunc and \
1050 self._tearDownFunc == other._tearDownFunc and \
1051 self._testFunc == other._testFunc and \
1052 self._description == other._description
1053
1054 def __ne__(self, other):
1055 return not self == other
1056
1057 def __hash__(self):
1058 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1059 self._testFunc, self._description))
1060
1061 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001062 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001063 self._testFunc.__name__)
1064
1065 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +00001066 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +00001067 self._testFunc)
1068
1069 def shortDescription(self):
1070 if self._description is not None:
1071 return self._description
1072 doc = self._testFunc.__doc__
1073 return doc and doc.split("\n")[0].strip() or None