blob: 890091597996a1a0adfea274f61723e711e0c650 [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
14
15class SkipTest(Exception):
16 """
17 Raise this exception in a test to skip it.
18
19 Usually you can use TestResult.skip() or one of the skipping decorators
20 instead of raising this directly.
21 """
22 pass
23
24class _ExpectedFailure(Exception):
25 """
26 Raise this when a test is expected to fail.
27
28 This is an implementation detail.
29 """
30
31 def __init__(self, exc_info):
32 super(_ExpectedFailure, self).__init__()
33 self.exc_info = exc_info
34
35class _UnexpectedSuccess(Exception):
36 """
37 The test was supposed to fail, but it didn't!
38 """
39 pass
40
41def _id(obj):
42 return obj
43
44def skip(reason):
45 """
46 Unconditionally skip a test.
47 """
48 def decorator(test_item):
Benjamin Peterson847a4112010-03-14 15:04:17 +000049 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
50 @functools.wraps(test_item)
51 def skip_wrapper(*args, **kwargs):
52 raise SkipTest(reason)
53 test_item = skip_wrapper
54
55 test_item.__unittest_skip__ = True
56 test_item.__unittest_skip_why__ = reason
57 return test_item
Benjamin Petersonbed7d042009-07-19 21:01:52 +000058 return decorator
59
60def skipIf(condition, reason):
61 """
62 Skip a test if the condition is true.
63 """
64 if condition:
65 return skip(reason)
66 return _id
67
68def skipUnless(condition, reason):
69 """
70 Skip a test unless the condition is true.
71 """
72 if not condition:
73 return skip(reason)
74 return _id
75
76
77def expectedFailure(func):
78 @functools.wraps(func)
79 def wrapper(*args, **kwargs):
80 try:
81 func(*args, **kwargs)
82 except Exception:
83 raise _ExpectedFailure(sys.exc_info())
84 raise _UnexpectedSuccess
85 return wrapper
86
87
88class _AssertRaisesContext(object):
89 """A context manager used to implement TestCase.assertRaises* methods."""
90
91 def __init__(self, expected, test_case, callable_obj=None,
92 expected_regexp=None):
93 self.expected = expected
94 self.failureException = test_case.failureException
95 if callable_obj is not None:
96 try:
97 self.obj_name = callable_obj.__name__
98 except AttributeError:
99 self.obj_name = str(callable_obj)
100 else:
101 self.obj_name = None
Georg Brandl89fad142010-03-14 10:23:39 +0000102 self.expected_regexp = expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000103
104 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000105 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000106
107 def __exit__(self, exc_type, exc_value, tb):
108 if exc_type is None:
109 try:
110 exc_name = self.expected.__name__
111 except AttributeError:
112 exc_name = str(self.expected)
113 if self.obj_name:
114 raise self.failureException("{0} not raised by {1}"
115 .format(exc_name, self.obj_name))
116 else:
117 raise self.failureException("{0} not raised"
118 .format(exc_name))
119 if not issubclass(exc_type, self.expected):
120 # let unexpected exceptions pass through
121 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000122 # store exception, without traceback, for later retrieval
123 self.exception = exc_value.with_traceback(None)
Georg Brandl89fad142010-03-14 10:23:39 +0000124 if self.expected_regexp is None:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000125 return True
126
Georg Brandl89fad142010-03-14 10:23:39 +0000127 expected_regexp = self.expected_regexp
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000128 if isinstance(expected_regexp, (bytes, str)):
129 expected_regexp = re.compile(expected_regexp)
130 if not expected_regexp.search(str(exc_value)):
131 raise self.failureException('"%s" does not match "%s"' %
132 (expected_regexp.pattern, str(exc_value)))
133 return True
134
135
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000136class TestCase(object):
137 """A class whose instances are single test cases.
138
139 By default, the test code itself should be placed in a method named
140 'runTest'.
141
142 If the fixture may be used for many test cases, create as
143 many test methods as are needed. When instantiating such a TestCase
144 subclass, specify in the constructor arguments the name of the test method
145 that the instance is to execute.
146
147 Test authors should subclass TestCase for their own tests. Construction
148 and deconstruction of the test's environment ('fixture') can be
149 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
150
151 If it is necessary to override the __init__ method, the base class
152 __init__ method must always be called. It is important that subclasses
153 should not change the signature of their __init__ method, since instances
154 of the classes are instantiated automatically by parts of the framework
155 in order to be run.
156 """
157
158 # This attribute determines which exception will be raised when
159 # the instance's assertion methods fail; test methods raising this
160 # exception will be deemed to have 'failed' rather than 'errored'
161
162 failureException = AssertionError
163
164 # This attribute determines whether long messages (including repr of
165 # objects used in assert methods) will be printed on failure in *addition*
166 # to any explicit message passed.
167
168 longMessage = False
169
Benjamin Peterson847a4112010-03-14 15:04:17 +0000170 # Attribute used by TestSuite for classSetUp
171
172 _classSetupFailed = False
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000173
174 def __init__(self, methodName='runTest'):
175 """Create an instance of the class that will use the named test
176 method when executed. Raises a ValueError if the instance does
177 not have a method with the specified name.
178 """
179 self._testMethodName = methodName
180 self._resultForDoCleanups = None
181 try:
182 testMethod = getattr(self, methodName)
183 except AttributeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000184 raise ValueError("no such test method in %s: %s" %
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000185 (self.__class__, methodName))
186 self._testMethodDoc = testMethod.__doc__
187 self._cleanups = []
188
189 # Map types to custom assertEqual functions that will compare
190 # instances of said type in more detail to generate a more useful
191 # error message.
192 self._type_equality_funcs = {}
193 self.addTypeEqualityFunc(dict, self.assertDictEqual)
194 self.addTypeEqualityFunc(list, self.assertListEqual)
195 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
196 self.addTypeEqualityFunc(set, self.assertSetEqual)
197 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foord02834952010-02-08 23:10:39 +0000198 self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000199
200 def addTypeEqualityFunc(self, typeobj, function):
201 """Add a type specific assertEqual style function to compare a type.
202
203 This method is for use by TestCase subclasses that need to register
204 their own type equality functions to provide nicer error messages.
205
206 Args:
207 typeobj: The data type to call this function on when both values
208 are of the same type in assertEqual().
209 function: The callable taking two arguments and an optional
210 msg= argument that raises self.failureException with a
211 useful error message when the two arguments are not equal.
212 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000213 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000214
215 def addCleanup(self, function, *args, **kwargs):
216 """Add a function, with arguments, to be called when the test is
217 completed. Functions added are called on a LIFO basis and are
218 called after tearDown on test failure or success.
219
220 Cleanup items are called even if setUp fails (unlike tearDown)."""
221 self._cleanups.append((function, args, kwargs))
222
223 def setUp(self):
224 "Hook method for setting up the test fixture before exercising it."
225 pass
226
227 def tearDown(self):
228 "Hook method for deconstructing the test fixture after testing it."
229 pass
230
Benjamin Peterson847a4112010-03-14 15:04:17 +0000231 @classmethod
232 def setUpClass(cls):
233 "Hook method for setting up class fixture before running tests in the class."
234
235 @classmethod
236 def tearDownClass(cls):
237 "Hook method for deconstructing the class fixture after running all tests in the class."
238
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000239 def countTestCases(self):
240 return 1
241
242 def defaultTestResult(self):
243 return result.TestResult()
244
245 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000246 """Returns a one-line description of the test, or None if no
247 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000248
Michael Foord34c94622010-02-10 15:51:42 +0000249 The default implementation of this method returns the first line of
250 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000251 """
Michael Foord34c94622010-02-10 15:51:42 +0000252 doc = self._testMethodDoc
253 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000254
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000255
256 def id(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000257 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000258
259 def __eq__(self, other):
260 if type(self) is not type(other):
261 return NotImplemented
262
263 return self._testMethodName == other._testMethodName
264
265 def __ne__(self, other):
266 return not self == other
267
268 def __hash__(self):
269 return hash((type(self), self._testMethodName))
270
271 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000272 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000273
274 def __repr__(self):
275 return "<%s testMethod=%s>" % \
Benjamin Peterson847a4112010-03-14 15:04:17 +0000276 (strclass(self.__class__), self._testMethodName)
277
278 def _addSkip(self, result, reason):
279 addSkip = getattr(result, 'addSkip', None)
280 if addSkip is not None:
281 addSkip(self, reason)
282 else:
283 warnings.warn("TestResult has no addSkip method, skips not reported",
284 RuntimeWarning, 2)
285 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000286
287 def run(self, result=None):
288 orig_result = result
289 if result is None:
290 result = self.defaultTestResult()
291 startTestRun = getattr(result, 'startTestRun', None)
292 if startTestRun is not None:
293 startTestRun()
294
295 self._resultForDoCleanups = result
296 result.startTest(self)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000297
298 testMethod = getattr(self, self._testMethodName)
299 if (getattr(self.__class__, "__unittest_skip__", False) or
300 getattr(testMethod, "__unittest_skip__", False)):
301 # If the class or method was skipped.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000302 try:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000303 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
304 or getattr(testMethod, '__unittest_skip_why__', ''))
305 self._addSkip(result, skip_why)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000306 finally:
307 result.stopTest(self)
308 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000309 try:
310 success = False
311 try:
312 self.setUp()
313 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000314 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000315 except Exception:
316 result.addError(self, sys.exc_info())
317 else:
318 try:
319 testMethod()
320 except self.failureException:
321 result.addFailure(self, sys.exc_info())
322 except _ExpectedFailure as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000323 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
324 if addExpectedFailure is not None:
325 addExpectedFailure(self, e.exc_info)
326 else:
327 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
328 RuntimeWarning)
329 result.addSuccess(self)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000330 except _UnexpectedSuccess:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000331 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
332 if addUnexpectedSuccess is not None:
333 addUnexpectedSuccess(self)
334 else:
335 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
336 RuntimeWarning)
337 result.addFailure(self, sys.exc_info())
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000338 except SkipTest as e:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000339 self._addSkip(result, str(e))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000340 except Exception:
341 result.addError(self, sys.exc_info())
342 else:
343 success = True
344
345 try:
346 self.tearDown()
347 except Exception:
348 result.addError(self, sys.exc_info())
349 success = False
350
351 cleanUpSuccess = self.doCleanups()
352 success = success and cleanUpSuccess
353 if success:
354 result.addSuccess(self)
355 finally:
356 result.stopTest(self)
357 if orig_result is None:
358 stopTestRun = getattr(result, 'stopTestRun', None)
359 if stopTestRun is not None:
360 stopTestRun()
361
362 def doCleanups(self):
363 """Execute all cleanup functions. Normally called for you after
364 tearDown."""
365 result = self._resultForDoCleanups
366 ok = True
367 while self._cleanups:
368 function, args, kwargs = self._cleanups.pop(-1)
369 try:
370 function(*args, **kwargs)
371 except Exception:
372 ok = False
373 result.addError(self, sys.exc_info())
374 return ok
375
376 def __call__(self, *args, **kwds):
377 return self.run(*args, **kwds)
378
379 def debug(self):
380 """Run the test without collecting errors in a TestResult"""
381 self.setUp()
382 getattr(self, self._testMethodName)()
383 self.tearDown()
384
385 def skipTest(self, reason):
386 """Skip this test."""
387 raise SkipTest(reason)
388
389 def fail(self, msg=None):
390 """Fail immediately, with the given message."""
391 raise self.failureException(msg)
392
393 def assertFalse(self, expr, msg=None):
394 "Fail the test if the expression is true."
395 if expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000396 msg = self._formatMessage(msg, "%s is not False" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000397 raise self.failureException(msg)
398
399 def assertTrue(self, expr, msg=None):
400 """Fail the test unless the expression is true."""
401 if not expr:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000402 msg = self._formatMessage(msg, "%s is not True" % safe_repr(expr))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000403 raise self.failureException(msg)
404
405 def _formatMessage(self, msg, standardMsg):
406 """Honour the longMessage attribute when generating failure messages.
407 If longMessage is False this means:
408 * Use only an explicit message if it is provided
409 * Otherwise use the standard message for the assert
410
411 If longMessage is True:
412 * Use the standard message
413 * If an explicit message is provided, plus ' : ' and the explicit message
414 """
415 if not self.longMessage:
416 return msg or standardMsg
417 if msg is None:
418 return standardMsg
Benjamin Peterson847a4112010-03-14 15:04:17 +0000419 try:
420 # don't switch to '{}' formatting in Python 2.X
421 # it changes the way unicode input is handled
422 return '%s : %s' % (standardMsg, msg)
423 except UnicodeDecodeError:
424 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000425
426
427 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
428 """Fail unless an exception of class excClass is thrown
429 by callableObj when invoked with arguments args and keyword
430 arguments kwargs. If a different type of exception is
431 thrown, it will not be caught, and the test case will be
432 deemed to have suffered an error, exactly as for an
433 unexpected exception.
434
435 If called with callableObj omitted or None, will return a
436 context object used like this::
437
Michael Foord1c42b122010-02-05 22:58:21 +0000438 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000439 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000440
441 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000442 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000443 exception after the assertion::
444
445 with self.assertRaises(SomeException) as cm:
446 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000447 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000448 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000449 """
450 context = _AssertRaisesContext(excClass, self, callableObj)
451 if callableObj is None:
452 return context
453 with context:
454 callableObj(*args, **kwargs)
455
456 def _getAssertEqualityFunc(self, first, second):
457 """Get a detailed comparison function for the types of the two args.
458
459 Returns: A callable accepting (first, second, msg=None) that will
460 raise a failure exception if first != second with a useful human
461 readable error message for those types.
462 """
463 #
464 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
465 # and vice versa. I opted for the conservative approach in case
466 # subclasses are not intended to be compared in detail to their super
467 # class instances using a type equality func. This means testing
468 # subtypes won't automagically use the detailed comparison. Callers
469 # should use their type specific assertSpamEqual method to compare
470 # subclasses if the detailed comparison is desired and appropriate.
471 # See the discussion in http://bugs.python.org/issue2578.
472 #
473 if type(first) is type(second):
474 asserter = self._type_equality_funcs.get(type(first))
475 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000476 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000477
478 return self._baseAssertEqual
479
480 def _baseAssertEqual(self, first, second, msg=None):
481 """The default assertEqual implementation, not type specific."""
482 if not first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000483 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000484 msg = self._formatMessage(msg, standardMsg)
485 raise self.failureException(msg)
486
487 def assertEqual(self, first, second, msg=None):
488 """Fail if the two objects are unequal as determined by the '=='
489 operator.
490 """
491 assertion_func = self._getAssertEqualityFunc(first, second)
492 assertion_func(first, second, msg=msg)
493
494 def assertNotEqual(self, first, second, msg=None):
495 """Fail if the two objects are equal as determined by the '=='
496 operator.
497 """
498 if not first != second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000499 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
500 safe_repr(second)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000501 raise self.failureException(msg)
502
503 def assertAlmostEqual(self, first, second, *, places=7, msg=None):
504 """Fail if the two objects are unequal as determined by their
505 difference rounded to the given number of decimal places
506 (default 7) and comparing to zero.
507
508 Note that decimal places (from zero) are usually not the same
509 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000510
511 If the two objects compare equal then they will automatically
512 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000513 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000514 if first == second:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000515 # shortcut for inf
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000516 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000517 if round(abs(second-first), places) != 0:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000518 standardMsg = '%s != %s within %r places' % (safe_repr(first),
519 safe_repr(second),
520 places)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000521 msg = self._formatMessage(msg, standardMsg)
522 raise self.failureException(msg)
523
524 def assertNotAlmostEqual(self, first, second, *, places=7, msg=None):
525 """Fail if the two objects are equal as determined by their
526 difference rounded to the given number of decimal places
527 (default 7) and comparing to zero.
528
529 Note that decimal places (from zero) are usually not the same
530 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000531
532 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000533 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000534 if (first == second) or round(abs(second-first), places) == 0:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000535 standardMsg = '%s == %s within %r places' % (safe_repr(first),
536 safe_repr(second),
537 places)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000538 msg = self._formatMessage(msg, standardMsg)
539 raise self.failureException(msg)
540
541 # Synonyms for assertion methods
542
543 # The plurals are undocumented. Keep them that way to discourage use.
544 # Do not add more. Do not remove.
545 # Going through a deprecation cycle on these would annoy many people.
546 assertEquals = assertEqual
547 assertNotEquals = assertNotEqual
548 assertAlmostEquals = assertAlmostEqual
549 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord0e31b992010-02-10 15:52:56 +0000550 assert_ = assertTrue
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000551
552 # These fail* assertion method names are pending deprecation and will
553 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
554 def _deprecate(original_func):
555 def deprecated_func(*args, **kwargs):
556 warnings.warn(
557 'Please use {0} instead.'.format(original_func.__name__),
558 DeprecationWarning, 2)
559 return original_func(*args, **kwargs)
560 return deprecated_func
561
562 failUnlessEqual = _deprecate(assertEqual)
563 failIfEqual = _deprecate(assertNotEqual)
564 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
565 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
566 failUnless = _deprecate(assertTrue)
567 failUnlessRaises = _deprecate(assertRaises)
568 failIf = _deprecate(assertFalse)
569
570 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
571 """An equality assertion for ordered sequences (like lists and tuples).
572
R. David Murrayad13f222010-01-29 22:17:58 +0000573 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000574 which can be indexed, has a length, and has an equality operator.
575
576 Args:
577 seq1: The first sequence to compare.
578 seq2: The second sequence to compare.
579 seq_type: The expected datatype of the sequences, or None if no
580 datatype should be enforced.
581 msg: Optional message to use on failure instead of a list of
582 differences.
583 """
584 if seq_type != None:
585 seq_type_name = seq_type.__name__
586 if not isinstance(seq1, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000587 raise self.failureException('First sequence is not a %s: %s'
588 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000589 if not isinstance(seq2, seq_type):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000590 raise self.failureException('Second sequence is not a %s: %s'
591 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000592 else:
593 seq_type_name = "sequence"
594
595 differing = None
596 try:
597 len1 = len(seq1)
598 except (TypeError, NotImplementedError):
599 differing = 'First %s has no length. Non-sequence?' % (
600 seq_type_name)
601
602 if differing is None:
603 try:
604 len2 = len(seq2)
605 except (TypeError, NotImplementedError):
606 differing = 'Second %s has no length. Non-sequence?' % (
607 seq_type_name)
608
609 if differing is None:
610 if seq1 == seq2:
611 return
612
Benjamin Peterson847a4112010-03-14 15:04:17 +0000613 seq1_repr = safe_repr(seq1)
614 seq2_repr = safe_repr(seq2)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000615 if len(seq1_repr) > 30:
616 seq1_repr = seq1_repr[:30] + '...'
617 if len(seq2_repr) > 30:
618 seq2_repr = seq2_repr[:30] + '...'
619 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
620 differing = '%ss differ: %s != %s\n' % elements
621
622 for i in range(min(len1, len2)):
623 try:
624 item1 = seq1[i]
625 except (TypeError, IndexError, NotImplementedError):
626 differing += ('\nUnable to index element %d of first %s\n' %
627 (i, seq_type_name))
628 break
629
630 try:
631 item2 = seq2[i]
632 except (TypeError, IndexError, NotImplementedError):
633 differing += ('\nUnable to index element %d of second %s\n' %
634 (i, seq_type_name))
635 break
636
637 if item1 != item2:
638 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
639 (i, item1, item2))
640 break
641 else:
642 if (len1 == len2 and seq_type is None and
643 type(seq1) != type(seq2)):
644 # The sequences are the same, but have differing types.
645 return
646
647 if len1 > len2:
648 differing += ('\nFirst %s contains %d additional '
649 'elements.\n' % (seq_type_name, len1 - len2))
650 try:
651 differing += ('First extra element %d:\n%s\n' %
652 (len2, seq1[len2]))
653 except (TypeError, IndexError, NotImplementedError):
654 differing += ('Unable to index element %d '
655 'of first %s\n' % (len2, seq_type_name))
656 elif len1 < len2:
657 differing += ('\nSecond %s contains %d additional '
658 'elements.\n' % (seq_type_name, len2 - len1))
659 try:
660 differing += ('First extra element %d:\n%s\n' %
661 (len1, seq2[len1]))
662 except (TypeError, IndexError, NotImplementedError):
663 differing += ('Unable to index element %d '
664 'of second %s\n' % (len1, seq_type_name))
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000665 standardMsg = differing + '\n' + '\n'.join(
666 difflib.ndiff(pprint.pformat(seq1).splitlines(),
667 pprint.pformat(seq2).splitlines()))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000668 msg = self._formatMessage(msg, standardMsg)
669 self.fail(msg)
670
671 def assertListEqual(self, list1, list2, msg=None):
672 """A list-specific equality assertion.
673
674 Args:
675 list1: The first list to compare.
676 list2: The second list to compare.
677 msg: Optional message to use on failure instead of a list of
678 differences.
679
680 """
681 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
682
683 def assertTupleEqual(self, tuple1, tuple2, msg=None):
684 """A tuple-specific equality assertion.
685
686 Args:
687 tuple1: The first tuple to compare.
688 tuple2: The second tuple to compare.
689 msg: Optional message to use on failure instead of a list of
690 differences.
691 """
692 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
693
694 def assertSetEqual(self, set1, set2, msg=None):
695 """A set-specific equality assertion.
696
697 Args:
698 set1: The first set to compare.
699 set2: The second set to compare.
700 msg: Optional message to use on failure instead of a list of
701 differences.
702
703 For more general containership equality, assertSameElements will work
704 with things other than sets. This uses ducktyping to support
705 different types of sets, and is optimized for sets specifically
706 (parameters must support a difference method).
707 """
708 try:
709 difference1 = set1.difference(set2)
710 except TypeError as e:
711 self.fail('invalid type when attempting set difference: %s' % e)
712 except AttributeError as e:
713 self.fail('first argument does not support set difference: %s' % e)
714
715 try:
716 difference2 = set2.difference(set1)
717 except TypeError as e:
718 self.fail('invalid type when attempting set difference: %s' % e)
719 except AttributeError as e:
720 self.fail('second argument does not support set difference: %s' % e)
721
722 if not (difference1 or difference2):
723 return
724
725 lines = []
726 if difference1:
727 lines.append('Items in the first set but not the second:')
728 for item in difference1:
729 lines.append(repr(item))
730 if difference2:
731 lines.append('Items in the second set but not the first:')
732 for item in difference2:
733 lines.append(repr(item))
734
735 standardMsg = '\n'.join(lines)
736 self.fail(self._formatMessage(msg, standardMsg))
737
738 def assertIn(self, member, container, msg=None):
739 """Just like self.assertTrue(a in b), but with a nicer default message."""
740 if member not in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000741 standardMsg = '%s not found in %s' % (safe_repr(member),
742 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000743 self.fail(self._formatMessage(msg, standardMsg))
744
745 def assertNotIn(self, member, container, msg=None):
746 """Just like self.assertTrue(a not in b), but with a nicer default message."""
747 if member in container:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000748 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
749 safe_repr(container))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000750 self.fail(self._formatMessage(msg, standardMsg))
751
752 def assertIs(self, expr1, expr2, msg=None):
753 """Just like self.assertTrue(a is b), but with a nicer default message."""
754 if expr1 is not expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000755 standardMsg = '%s is not %s' % (safe_repr(expr1),
756 safe_repr(expr2))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000757 self.fail(self._formatMessage(msg, standardMsg))
758
759 def assertIsNot(self, expr1, expr2, msg=None):
760 """Just like self.assertTrue(a is not b), but with a nicer default message."""
761 if expr1 is expr2:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000762 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000763 self.fail(self._formatMessage(msg, standardMsg))
764
765 def assertDictEqual(self, d1, d2, msg=None):
766 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
767 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
768
769 if d1 != d2:
770 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
771 pprint.pformat(d1).splitlines(),
772 pprint.pformat(d2).splitlines())))
773 self.fail(self._formatMessage(msg, standardMsg))
774
775 def assertDictContainsSubset(self, expected, actual, msg=None):
776 """Checks whether actual is a superset of expected."""
777 missing = []
778 mismatched = []
779 for key, value in expected.items():
780 if key not in actual:
781 missing.append(key)
782 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000783 mismatched.append('%s, expected: %s, actual: %s' %
Benjamin Peterson847a4112010-03-14 15:04:17 +0000784 (safe_repr(key), safe_repr(value),
785 safe_repr(actual[key])))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000786
787 if not (missing or mismatched):
788 return
789
790 standardMsg = ''
791 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000792 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
793 missing)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000794 if mismatched:
795 if standardMsg:
796 standardMsg += '; '
797 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
798
799 self.fail(self._formatMessage(msg, standardMsg))
800
801 def assertSameElements(self, expected_seq, actual_seq, msg=None):
802 """An unordered sequence specific comparison.
803
804 Raises with an error message listing which elements of expected_seq
805 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000806
807 Duplicate elements are ignored when comparing *expected_seq* and
808 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
809 set(actual))`` but it works with sequences of unhashable objects as
810 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000811 """
812 try:
813 expected = set(expected_seq)
814 actual = set(actual_seq)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000815 missing = sorted(expected.difference(actual))
816 unexpected = sorted(actual.difference(expected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000817 except TypeError:
818 # Fall back to slower list-compare if any of the objects are
819 # not hashable.
820 expected = list(expected_seq)
821 actual = list(actual_seq)
822 try:
823 expected.sort()
824 actual.sort()
825 except TypeError:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000826 missing, unexpected = unorderable_list_difference(expected,
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000827 actual)
Benjamin Peterson847a4112010-03-14 15:04:17 +0000828 else:
829 missing, unexpected = sorted_list_difference(expected, actual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000830 errors = []
831 if missing:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000832 errors.append('Expected, but missing:\n %s' %
833 safe_repr(missing))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000834 if unexpected:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000835 errors.append('Unexpected, but present:\n %s' %
836 safe_repr(unexpected))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000837 if errors:
838 standardMsg = '\n'.join(errors)
839 self.fail(self._formatMessage(msg, standardMsg))
840
841 def assertMultiLineEqual(self, first, second, msg=None):
842 """Assert that two multi-line strings are equal."""
843 self.assert_(isinstance(first, str), (
844 'First argument is not a string'))
845 self.assert_(isinstance(second, str), (
846 'Second argument is not a string'))
847
848 if first != second:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000849 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
850 second.splitlines(True)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000851 self.fail(self._formatMessage(msg, standardMsg))
852
853 def assertLess(self, a, b, msg=None):
854 """Just like self.assertTrue(a < b), but with a nicer default message."""
855 if not a < b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000856 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000857 self.fail(self._formatMessage(msg, standardMsg))
858
859 def assertLessEqual(self, a, b, msg=None):
860 """Just like self.assertTrue(a <= b), but with a nicer default message."""
861 if not a <= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000862 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000863 self.fail(self._formatMessage(msg, standardMsg))
864
865 def assertGreater(self, a, b, msg=None):
866 """Just like self.assertTrue(a > b), but with a nicer default message."""
867 if not a > b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000868 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000869 self.fail(self._formatMessage(msg, standardMsg))
870
871 def assertGreaterEqual(self, a, b, msg=None):
872 """Just like self.assertTrue(a >= b), but with a nicer default message."""
873 if not a >= b:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000874 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000875 self.fail(self._formatMessage(msg, standardMsg))
876
877 def assertIsNone(self, obj, msg=None):
878 """Same as self.assertTrue(obj is None), with a nicer default message."""
879 if obj is not None:
Benjamin Peterson847a4112010-03-14 15:04:17 +0000880 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000881 self.fail(self._formatMessage(msg, standardMsg))
882
883 def assertIsNotNone(self, obj, msg=None):
884 """Included for symmetry with assertIsNone."""
885 if obj is None:
886 standardMsg = 'unexpectedly None'
887 self.fail(self._formatMessage(msg, standardMsg))
888
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000889 def assertIsInstance(self, obj, cls, msg=None):
890 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
891 default message."""
892 if not isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000893 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000894 self.fail(self._formatMessage(msg, standardMsg))
895
896 def assertNotIsInstance(self, obj, cls, msg=None):
897 """Included for symmetry with assertIsInstance."""
898 if isinstance(obj, cls):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000899 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000900 self.fail(self._formatMessage(msg, standardMsg))
901
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000902 def assertRaisesRegexp(self, expected_exception, expected_regexp,
903 callable_obj=None, *args, **kwargs):
904 """Asserts that the message in a raised exception matches a regexp.
905
906 Args:
907 expected_exception: Exception class expected to be raised.
908 expected_regexp: Regexp (re pattern object or string) expected
909 to be found in error message.
910 callable_obj: Function to be called.
911 args: Extra args.
912 kwargs: Extra kwargs.
913 """
914 context = _AssertRaisesContext(expected_exception, self, callable_obj,
915 expected_regexp)
916 if callable_obj is None:
917 return context
918 with context:
919 callable_obj(*args, **kwargs)
920
Georg Brandl89fad142010-03-14 10:23:39 +0000921 def assertRegexpMatches(self, text, expected_regexp, msg=None):
922 if isinstance(expected_regexp, (str, bytes)):
923 expected_regexp = re.compile(expected_regexp)
924 if not expected_regexp.search(text):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000925 msg = msg or "Regexp didn't match"
Georg Brandl89fad142010-03-14 10:23:39 +0000926 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000927 raise self.failureException(msg)
928
929
930class FunctionTestCase(TestCase):
931 """A test case that wraps a test function.
932
933 This is useful for slipping pre-existing test functions into the
934 unittest framework. Optionally, set-up and tidy-up functions can be
935 supplied. As with TestCase, the tidy-up ('tearDown') function will
936 always be called if the set-up ('setUp') function ran successfully.
937 """
938
939 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
940 super(FunctionTestCase, self).__init__()
941 self._setUpFunc = setUp
942 self._tearDownFunc = tearDown
943 self._testFunc = testFunc
944 self._description = description
945
946 def setUp(self):
947 if self._setUpFunc is not None:
948 self._setUpFunc()
949
950 def tearDown(self):
951 if self._tearDownFunc is not None:
952 self._tearDownFunc()
953
954 def runTest(self):
955 self._testFunc()
956
957 def id(self):
958 return self._testFunc.__name__
959
960 def __eq__(self, other):
961 if not isinstance(other, self.__class__):
962 return NotImplemented
963
964 return self._setUpFunc == other._setUpFunc and \
965 self._tearDownFunc == other._tearDownFunc and \
966 self._testFunc == other._testFunc and \
967 self._description == other._description
968
969 def __ne__(self, other):
970 return not self == other
971
972 def __hash__(self):
973 return hash((type(self), self._setUpFunc, self._tearDownFunc,
974 self._testFunc, self._description))
975
976 def __str__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000977 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000978 self._testFunc.__name__)
979
980 def __repr__(self):
Benjamin Peterson847a4112010-03-14 15:04:17 +0000981 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000982 self._testFunc)
983
984 def shortDescription(self):
985 if self._description is not None:
986 return self._description
987 doc = self._testFunc.__doc__
988 return doc and doc.split("\n")[0].strip() or None