blob: cd0764d5c24efb4a20538caf1c88352ca002870a [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
10from . import result, util
11
12
13class SkipTest(Exception):
14 """
15 Raise this exception in a test to skip it.
16
17 Usually you can use TestResult.skip() or one of the skipping decorators
18 instead of raising this directly.
19 """
20 pass
21
22class _ExpectedFailure(Exception):
23 """
24 Raise this when a test is expected to fail.
25
26 This is an implementation detail.
27 """
28
29 def __init__(self, exc_info):
30 super(_ExpectedFailure, self).__init__()
31 self.exc_info = exc_info
32
33class _UnexpectedSuccess(Exception):
34 """
35 The test was supposed to fail, but it didn't!
36 """
37 pass
38
39def _id(obj):
40 return obj
41
42def skip(reason):
43 """
44 Unconditionally skip a test.
45 """
46 def decorator(test_item):
47 if isinstance(test_item, type) and issubclass(test_item, TestCase):
48 test_item.__unittest_skip__ = True
49 test_item.__unittest_skip_why__ = reason
50 return test_item
51 @functools.wraps(test_item)
52 def skip_wrapper(*args, **kwargs):
53 raise SkipTest(reason)
54 return skip_wrapper
55 return decorator
56
57def skipIf(condition, reason):
58 """
59 Skip a test if the condition is true.
60 """
61 if condition:
62 return skip(reason)
63 return _id
64
65def skipUnless(condition, reason):
66 """
67 Skip a test unless the condition is true.
68 """
69 if not condition:
70 return skip(reason)
71 return _id
72
73
74def expectedFailure(func):
75 @functools.wraps(func)
76 def wrapper(*args, **kwargs):
77 try:
78 func(*args, **kwargs)
79 except Exception:
80 raise _ExpectedFailure(sys.exc_info())
81 raise _UnexpectedSuccess
82 return wrapper
83
84
85class _AssertRaisesContext(object):
86 """A context manager used to implement TestCase.assertRaises* methods."""
87
88 def __init__(self, expected, test_case, callable_obj=None,
89 expected_regexp=None):
90 self.expected = expected
91 self.failureException = test_case.failureException
92 if callable_obj is not None:
93 try:
94 self.obj_name = callable_obj.__name__
95 except AttributeError:
96 self.obj_name = str(callable_obj)
97 else:
98 self.obj_name = None
99 self.expected_regex = expected_regexp
100
101 def __enter__(self):
Ezio Melotti49008232010-02-08 21:57:48 +0000102 return self
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000103
104 def __exit__(self, exc_type, exc_value, tb):
105 if exc_type is None:
106 try:
107 exc_name = self.expected.__name__
108 except AttributeError:
109 exc_name = str(self.expected)
110 if self.obj_name:
111 raise self.failureException("{0} not raised by {1}"
112 .format(exc_name, self.obj_name))
113 else:
114 raise self.failureException("{0} not raised"
115 .format(exc_name))
116 if not issubclass(exc_type, self.expected):
117 # let unexpected exceptions pass through
118 return False
Ezio Melotti49008232010-02-08 21:57:48 +0000119 # store exception, without traceback, for later retrieval
120 self.exception = exc_value.with_traceback(None)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000121 if self.expected_regex is None:
122 return True
123
124 expected_regexp = self.expected_regex
125 if isinstance(expected_regexp, (bytes, str)):
126 expected_regexp = re.compile(expected_regexp)
127 if not expected_regexp.search(str(exc_value)):
128 raise self.failureException('"%s" does not match "%s"' %
129 (expected_regexp.pattern, str(exc_value)))
130 return True
131
132
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000133class TestCase(object):
134 """A class whose instances are single test cases.
135
136 By default, the test code itself should be placed in a method named
137 'runTest'.
138
139 If the fixture may be used for many test cases, create as
140 many test methods as are needed. When instantiating such a TestCase
141 subclass, specify in the constructor arguments the name of the test method
142 that the instance is to execute.
143
144 Test authors should subclass TestCase for their own tests. Construction
145 and deconstruction of the test's environment ('fixture') can be
146 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
147
148 If it is necessary to override the __init__ method, the base class
149 __init__ method must always be called. It is important that subclasses
150 should not change the signature of their __init__ method, since instances
151 of the classes are instantiated automatically by parts of the framework
152 in order to be run.
153 """
154
155 # This attribute determines which exception will be raised when
156 # the instance's assertion methods fail; test methods raising this
157 # exception will be deemed to have 'failed' rather than 'errored'
158
159 failureException = AssertionError
160
161 # This attribute determines whether long messages (including repr of
162 # objects used in assert methods) will be printed on failure in *addition*
163 # to any explicit message passed.
164
165 longMessage = False
166
167
168 def __init__(self, methodName='runTest'):
169 """Create an instance of the class that will use the named test
170 method when executed. Raises a ValueError if the instance does
171 not have a method with the specified name.
172 """
173 self._testMethodName = methodName
174 self._resultForDoCleanups = None
175 try:
176 testMethod = getattr(self, methodName)
177 except AttributeError:
178 raise ValueError("no such test method in %s: %s" % \
179 (self.__class__, methodName))
180 self._testMethodDoc = testMethod.__doc__
181 self._cleanups = []
182
183 # Map types to custom assertEqual functions that will compare
184 # instances of said type in more detail to generate a more useful
185 # error message.
186 self._type_equality_funcs = {}
187 self.addTypeEqualityFunc(dict, self.assertDictEqual)
188 self.addTypeEqualityFunc(list, self.assertListEqual)
189 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
190 self.addTypeEqualityFunc(set, self.assertSetEqual)
191 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foord02834952010-02-08 23:10:39 +0000192 self.addTypeEqualityFunc(str, self.assertMultiLineEqual)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000193
194 def addTypeEqualityFunc(self, typeobj, function):
195 """Add a type specific assertEqual style function to compare a type.
196
197 This method is for use by TestCase subclasses that need to register
198 their own type equality functions to provide nicer error messages.
199
200 Args:
201 typeobj: The data type to call this function on when both values
202 are of the same type in assertEqual().
203 function: The callable taking two arguments and an optional
204 msg= argument that raises self.failureException with a
205 useful error message when the two arguments are not equal.
206 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000207 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000208
209 def addCleanup(self, function, *args, **kwargs):
210 """Add a function, with arguments, to be called when the test is
211 completed. Functions added are called on a LIFO basis and are
212 called after tearDown on test failure or success.
213
214 Cleanup items are called even if setUp fails (unlike tearDown)."""
215 self._cleanups.append((function, args, kwargs))
216
217 def setUp(self):
218 "Hook method for setting up the test fixture before exercising it."
219 pass
220
221 def tearDown(self):
222 "Hook method for deconstructing the test fixture after testing it."
223 pass
224
225 def countTestCases(self):
226 return 1
227
228 def defaultTestResult(self):
229 return result.TestResult()
230
231 def shortDescription(self):
Michael Foord34c94622010-02-10 15:51:42 +0000232 """Returns a one-line description of the test, or None if no
233 description has been provided.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000234
Michael Foord34c94622010-02-10 15:51:42 +0000235 The default implementation of this method returns the first line of
236 the specified test method's docstring.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000237 """
Michael Foord34c94622010-02-10 15:51:42 +0000238 doc = self._testMethodDoc
239 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000240
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000241
242 def id(self):
243 return "%s.%s" % (util.strclass(self.__class__), self._testMethodName)
244
245 def __eq__(self, other):
246 if type(self) is not type(other):
247 return NotImplemented
248
249 return self._testMethodName == other._testMethodName
250
251 def __ne__(self, other):
252 return not self == other
253
254 def __hash__(self):
255 return hash((type(self), self._testMethodName))
256
257 def __str__(self):
258 return "%s (%s)" % (self._testMethodName, util.strclass(self.__class__))
259
260 def __repr__(self):
261 return "<%s testMethod=%s>" % \
262 (util.strclass(self.__class__), self._testMethodName)
263
264 def run(self, result=None):
265 orig_result = result
266 if result is None:
267 result = self.defaultTestResult()
268 startTestRun = getattr(result, 'startTestRun', None)
269 if startTestRun is not None:
270 startTestRun()
271
272 self._resultForDoCleanups = result
273 result.startTest(self)
274 if getattr(self.__class__, "__unittest_skip__", False):
275 # If the whole class was skipped.
276 try:
277 result.addSkip(self, self.__class__.__unittest_skip_why__)
278 finally:
279 result.stopTest(self)
280 return
281 testMethod = getattr(self, self._testMethodName)
282 try:
283 success = False
284 try:
285 self.setUp()
286 except SkipTest as e:
287 result.addSkip(self, str(e))
288 except Exception:
289 result.addError(self, sys.exc_info())
290 else:
291 try:
292 testMethod()
293 except self.failureException:
294 result.addFailure(self, sys.exc_info())
295 except _ExpectedFailure as e:
296 result.addExpectedFailure(self, e.exc_info)
297 except _UnexpectedSuccess:
298 result.addUnexpectedSuccess(self)
299 except SkipTest as e:
300 result.addSkip(self, str(e))
301 except Exception:
302 result.addError(self, sys.exc_info())
303 else:
304 success = True
305
306 try:
307 self.tearDown()
308 except Exception:
309 result.addError(self, sys.exc_info())
310 success = False
311
312 cleanUpSuccess = self.doCleanups()
313 success = success and cleanUpSuccess
314 if success:
315 result.addSuccess(self)
316 finally:
317 result.stopTest(self)
318 if orig_result is None:
319 stopTestRun = getattr(result, 'stopTestRun', None)
320 if stopTestRun is not None:
321 stopTestRun()
322
323 def doCleanups(self):
324 """Execute all cleanup functions. Normally called for you after
325 tearDown."""
326 result = self._resultForDoCleanups
327 ok = True
328 while self._cleanups:
329 function, args, kwargs = self._cleanups.pop(-1)
330 try:
331 function(*args, **kwargs)
332 except Exception:
333 ok = False
334 result.addError(self, sys.exc_info())
335 return ok
336
337 def __call__(self, *args, **kwds):
338 return self.run(*args, **kwds)
339
340 def debug(self):
341 """Run the test without collecting errors in a TestResult"""
342 self.setUp()
343 getattr(self, self._testMethodName)()
344 self.tearDown()
345
346 def skipTest(self, reason):
347 """Skip this test."""
348 raise SkipTest(reason)
349
350 def fail(self, msg=None):
351 """Fail immediately, with the given message."""
352 raise self.failureException(msg)
353
354 def assertFalse(self, expr, msg=None):
355 "Fail the test if the expression is true."
356 if expr:
357 msg = self._formatMessage(msg, "%r is not False" % expr)
358 raise self.failureException(msg)
359
360 def assertTrue(self, expr, msg=None):
361 """Fail the test unless the expression is true."""
362 if not expr:
363 msg = self._formatMessage(msg, "%r is not True" % expr)
364 raise self.failureException(msg)
365
366 def _formatMessage(self, msg, standardMsg):
367 """Honour the longMessage attribute when generating failure messages.
368 If longMessage is False this means:
369 * Use only an explicit message if it is provided
370 * Otherwise use the standard message for the assert
371
372 If longMessage is True:
373 * Use the standard message
374 * If an explicit message is provided, plus ' : ' and the explicit message
375 """
376 if not self.longMessage:
377 return msg or standardMsg
378 if msg is None:
379 return standardMsg
380 return standardMsg + ' : ' + msg
381
382
383 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
384 """Fail unless an exception of class excClass is thrown
385 by callableObj when invoked with arguments args and keyword
386 arguments kwargs. If a different type of exception is
387 thrown, it will not be caught, and the test case will be
388 deemed to have suffered an error, exactly as for an
389 unexpected exception.
390
391 If called with callableObj omitted or None, will return a
392 context object used like this::
393
Michael Foord1c42b122010-02-05 22:58:21 +0000394 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000395 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000396
397 The context manager keeps a reference to the exception as
Ezio Melotti49008232010-02-08 21:57:48 +0000398 the 'exception' attribute. This allows you to inspect the
Michael Foord1c42b122010-02-05 22:58:21 +0000399 exception after the assertion::
400
401 with self.assertRaises(SomeException) as cm:
402 do_something()
Ezio Melotti49008232010-02-08 21:57:48 +0000403 the_exception = cm.exception
Michael Foordb57ac6d2010-02-05 23:26:29 +0000404 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000405 """
406 context = _AssertRaisesContext(excClass, self, callableObj)
407 if callableObj is None:
408 return context
409 with context:
410 callableObj(*args, **kwargs)
411
412 def _getAssertEqualityFunc(self, first, second):
413 """Get a detailed comparison function for the types of the two args.
414
415 Returns: A callable accepting (first, second, msg=None) that will
416 raise a failure exception if first != second with a useful human
417 readable error message for those types.
418 """
419 #
420 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
421 # and vice versa. I opted for the conservative approach in case
422 # subclasses are not intended to be compared in detail to their super
423 # class instances using a type equality func. This means testing
424 # subtypes won't automagically use the detailed comparison. Callers
425 # should use their type specific assertSpamEqual method to compare
426 # subclasses if the detailed comparison is desired and appropriate.
427 # See the discussion in http://bugs.python.org/issue2578.
428 #
429 if type(first) is type(second):
430 asserter = self._type_equality_funcs.get(type(first))
431 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000432 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000433
434 return self._baseAssertEqual
435
436 def _baseAssertEqual(self, first, second, msg=None):
437 """The default assertEqual implementation, not type specific."""
438 if not first == second:
439 standardMsg = '%r != %r' % (first, second)
440 msg = self._formatMessage(msg, standardMsg)
441 raise self.failureException(msg)
442
443 def assertEqual(self, first, second, msg=None):
444 """Fail if the two objects are unequal as determined by the '=='
445 operator.
446 """
447 assertion_func = self._getAssertEqualityFunc(first, second)
448 assertion_func(first, second, msg=msg)
449
450 def assertNotEqual(self, first, second, msg=None):
451 """Fail if the two objects are equal as determined by the '=='
452 operator.
453 """
454 if not first != second:
455 msg = self._formatMessage(msg, '%r == %r' % (first, second))
456 raise self.failureException(msg)
457
458 def assertAlmostEqual(self, first, second, *, places=7, msg=None):
459 """Fail if the two objects are unequal as determined by their
460 difference rounded to the given number of decimal places
461 (default 7) and comparing to zero.
462
463 Note that decimal places (from zero) are usually not the same
464 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000465
466 If the two objects compare equal then they will automatically
467 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000468 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000469 if first == second:
470 # shortcut for ite
471 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000472 if round(abs(second-first), places) != 0:
473 standardMsg = '%r != %r within %r places' % (first, second, places)
474 msg = self._formatMessage(msg, standardMsg)
475 raise self.failureException(msg)
476
477 def assertNotAlmostEqual(self, first, second, *, places=7, msg=None):
478 """Fail if the two objects are equal as determined by their
479 difference rounded to the given number of decimal places
480 (default 7) and comparing to zero.
481
482 Note that decimal places (from zero) are usually not the same
483 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000484
485 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000486 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000487 if (first == second) or round(abs(second-first), places) == 0:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000488 standardMsg = '%r == %r within %r places' % (first, second, places)
489 msg = self._formatMessage(msg, standardMsg)
490 raise self.failureException(msg)
491
492 # Synonyms for assertion methods
493
494 # The plurals are undocumented. Keep them that way to discourage use.
495 # Do not add more. Do not remove.
496 # Going through a deprecation cycle on these would annoy many people.
497 assertEquals = assertEqual
498 assertNotEquals = assertNotEqual
499 assertAlmostEquals = assertAlmostEqual
500 assertNotAlmostEquals = assertNotAlmostEqual
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000501
502 # These fail* assertion method names are pending deprecation and will
503 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
504 def _deprecate(original_func):
505 def deprecated_func(*args, **kwargs):
506 warnings.warn(
507 'Please use {0} instead.'.format(original_func.__name__),
508 DeprecationWarning, 2)
509 return original_func(*args, **kwargs)
510 return deprecated_func
511
512 failUnlessEqual = _deprecate(assertEqual)
513 failIfEqual = _deprecate(assertNotEqual)
514 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
515 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
516 failUnless = _deprecate(assertTrue)
Michael Foord34c94622010-02-10 15:51:42 +0000517 assert_ = _deprecate(assertTrue)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000518 failUnlessRaises = _deprecate(assertRaises)
519 failIf = _deprecate(assertFalse)
520
521 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
522 """An equality assertion for ordered sequences (like lists and tuples).
523
R. David Murrayad13f222010-01-29 22:17:58 +0000524 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000525 which can be indexed, has a length, and has an equality operator.
526
527 Args:
528 seq1: The first sequence to compare.
529 seq2: The second sequence to compare.
530 seq_type: The expected datatype of the sequences, or None if no
531 datatype should be enforced.
532 msg: Optional message to use on failure instead of a list of
533 differences.
534 """
535 if seq_type != None:
536 seq_type_name = seq_type.__name__
537 if not isinstance(seq1, seq_type):
538 raise self.failureException('First sequence is not a %s: %r'
539 % (seq_type_name, seq1))
540 if not isinstance(seq2, seq_type):
541 raise self.failureException('Second sequence is not a %s: %r'
542 % (seq_type_name, seq2))
543 else:
544 seq_type_name = "sequence"
545
546 differing = None
547 try:
548 len1 = len(seq1)
549 except (TypeError, NotImplementedError):
550 differing = 'First %s has no length. Non-sequence?' % (
551 seq_type_name)
552
553 if differing is None:
554 try:
555 len2 = len(seq2)
556 except (TypeError, NotImplementedError):
557 differing = 'Second %s has no length. Non-sequence?' % (
558 seq_type_name)
559
560 if differing is None:
561 if seq1 == seq2:
562 return
563
564 seq1_repr = repr(seq1)
565 seq2_repr = repr(seq2)
566 if len(seq1_repr) > 30:
567 seq1_repr = seq1_repr[:30] + '...'
568 if len(seq2_repr) > 30:
569 seq2_repr = seq2_repr[:30] + '...'
570 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
571 differing = '%ss differ: %s != %s\n' % elements
572
573 for i in range(min(len1, len2)):
574 try:
575 item1 = seq1[i]
576 except (TypeError, IndexError, NotImplementedError):
577 differing += ('\nUnable to index element %d of first %s\n' %
578 (i, seq_type_name))
579 break
580
581 try:
582 item2 = seq2[i]
583 except (TypeError, IndexError, NotImplementedError):
584 differing += ('\nUnable to index element %d of second %s\n' %
585 (i, seq_type_name))
586 break
587
588 if item1 != item2:
589 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
590 (i, item1, item2))
591 break
592 else:
593 if (len1 == len2 and seq_type is None and
594 type(seq1) != type(seq2)):
595 # The sequences are the same, but have differing types.
596 return
597
598 if len1 > len2:
599 differing += ('\nFirst %s contains %d additional '
600 'elements.\n' % (seq_type_name, len1 - len2))
601 try:
602 differing += ('First extra element %d:\n%s\n' %
603 (len2, seq1[len2]))
604 except (TypeError, IndexError, NotImplementedError):
605 differing += ('Unable to index element %d '
606 'of first %s\n' % (len2, seq_type_name))
607 elif len1 < len2:
608 differing += ('\nSecond %s contains %d additional '
609 'elements.\n' % (seq_type_name, len2 - len1))
610 try:
611 differing += ('First extra element %d:\n%s\n' %
612 (len1, seq2[len1]))
613 except (TypeError, IndexError, NotImplementedError):
614 differing += ('Unable to index element %d '
615 'of second %s\n' % (len1, seq_type_name))
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000616 standardMsg = differing + '\n' + '\n'.join(
617 difflib.ndiff(pprint.pformat(seq1).splitlines(),
618 pprint.pformat(seq2).splitlines()))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000619 msg = self._formatMessage(msg, standardMsg)
620 self.fail(msg)
621
622 def assertListEqual(self, list1, list2, msg=None):
623 """A list-specific equality assertion.
624
625 Args:
626 list1: The first list to compare.
627 list2: The second list to compare.
628 msg: Optional message to use on failure instead of a list of
629 differences.
630
631 """
632 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
633
634 def assertTupleEqual(self, tuple1, tuple2, msg=None):
635 """A tuple-specific equality assertion.
636
637 Args:
638 tuple1: The first tuple to compare.
639 tuple2: The second tuple to compare.
640 msg: Optional message to use on failure instead of a list of
641 differences.
642 """
643 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
644
645 def assertSetEqual(self, set1, set2, msg=None):
646 """A set-specific equality assertion.
647
648 Args:
649 set1: The first set to compare.
650 set2: The second set to compare.
651 msg: Optional message to use on failure instead of a list of
652 differences.
653
654 For more general containership equality, assertSameElements will work
655 with things other than sets. This uses ducktyping to support
656 different types of sets, and is optimized for sets specifically
657 (parameters must support a difference method).
658 """
659 try:
660 difference1 = set1.difference(set2)
661 except TypeError as e:
662 self.fail('invalid type when attempting set difference: %s' % e)
663 except AttributeError as e:
664 self.fail('first argument does not support set difference: %s' % e)
665
666 try:
667 difference2 = set2.difference(set1)
668 except TypeError as e:
669 self.fail('invalid type when attempting set difference: %s' % e)
670 except AttributeError as e:
671 self.fail('second argument does not support set difference: %s' % e)
672
673 if not (difference1 or difference2):
674 return
675
676 lines = []
677 if difference1:
678 lines.append('Items in the first set but not the second:')
679 for item in difference1:
680 lines.append(repr(item))
681 if difference2:
682 lines.append('Items in the second set but not the first:')
683 for item in difference2:
684 lines.append(repr(item))
685
686 standardMsg = '\n'.join(lines)
687 self.fail(self._formatMessage(msg, standardMsg))
688
689 def assertIn(self, member, container, msg=None):
690 """Just like self.assertTrue(a in b), but with a nicer default message."""
691 if member not in container:
692 standardMsg = '%r not found in %r' % (member, container)
693 self.fail(self._formatMessage(msg, standardMsg))
694
695 def assertNotIn(self, member, container, msg=None):
696 """Just like self.assertTrue(a not in b), but with a nicer default message."""
697 if member in container:
698 standardMsg = '%r unexpectedly found in %r' % (member, container)
699 self.fail(self._formatMessage(msg, standardMsg))
700
701 def assertIs(self, expr1, expr2, msg=None):
702 """Just like self.assertTrue(a is b), but with a nicer default message."""
703 if expr1 is not expr2:
704 standardMsg = '%r is not %r' % (expr1, expr2)
705 self.fail(self._formatMessage(msg, standardMsg))
706
707 def assertIsNot(self, expr1, expr2, msg=None):
708 """Just like self.assertTrue(a is not b), but with a nicer default message."""
709 if expr1 is expr2:
710 standardMsg = 'unexpectedly identical: %r' % (expr1,)
711 self.fail(self._formatMessage(msg, standardMsg))
712
713 def assertDictEqual(self, d1, d2, msg=None):
714 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
715 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
716
717 if d1 != d2:
718 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
719 pprint.pformat(d1).splitlines(),
720 pprint.pformat(d2).splitlines())))
721 self.fail(self._formatMessage(msg, standardMsg))
722
723 def assertDictContainsSubset(self, expected, actual, msg=None):
724 """Checks whether actual is a superset of expected."""
725 missing = []
726 mismatched = []
727 for key, value in expected.items():
728 if key not in actual:
729 missing.append(key)
730 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000731 mismatched.append('%s, expected: %s, actual: %s' %
732 (key, value, actual[key]))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000733
734 if not (missing or mismatched):
735 return
736
737 standardMsg = ''
738 if missing:
739 standardMsg = 'Missing: %r' % ','.join(missing)
740 if mismatched:
741 if standardMsg:
742 standardMsg += '; '
743 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
744
745 self.fail(self._formatMessage(msg, standardMsg))
746
747 def assertSameElements(self, expected_seq, actual_seq, msg=None):
748 """An unordered sequence specific comparison.
749
750 Raises with an error message listing which elements of expected_seq
751 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000752
753 Duplicate elements are ignored when comparing *expected_seq* and
754 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
755 set(actual))`` but it works with sequences of unhashable objects as
756 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000757 """
758 try:
759 expected = set(expected_seq)
760 actual = set(actual_seq)
761 missing = list(expected.difference(actual))
762 unexpected = list(actual.difference(expected))
763 missing.sort()
764 unexpected.sort()
765 except TypeError:
766 # Fall back to slower list-compare if any of the objects are
767 # not hashable.
768 expected = list(expected_seq)
769 actual = list(actual_seq)
770 try:
771 expected.sort()
772 actual.sort()
773 except TypeError:
774 missing, unexpected = util.unorderable_list_difference(expected,
775 actual)
776 else:
777 missing, unexpected = util.sorted_list_difference(expected,
778 actual)
779 errors = []
780 if missing:
781 errors.append('Expected, but missing:\n %r' % missing)
782 if unexpected:
783 errors.append('Unexpected, but present:\n %r' % unexpected)
784 if errors:
785 standardMsg = '\n'.join(errors)
786 self.fail(self._formatMessage(msg, standardMsg))
787
788 def assertMultiLineEqual(self, first, second, msg=None):
789 """Assert that two multi-line strings are equal."""
790 self.assert_(isinstance(first, str), (
791 'First argument is not a string'))
792 self.assert_(isinstance(second, str), (
793 'Second argument is not a string'))
794
795 if first != second:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000796 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
797 second.splitlines(True)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000798 self.fail(self._formatMessage(msg, standardMsg))
799
800 def assertLess(self, a, b, msg=None):
801 """Just like self.assertTrue(a < b), but with a nicer default message."""
802 if not a < b:
803 standardMsg = '%r not less than %r' % (a, b)
804 self.fail(self._formatMessage(msg, standardMsg))
805
806 def assertLessEqual(self, a, b, msg=None):
807 """Just like self.assertTrue(a <= b), but with a nicer default message."""
808 if not a <= b:
809 standardMsg = '%r not less than or equal to %r' % (a, b)
810 self.fail(self._formatMessage(msg, standardMsg))
811
812 def assertGreater(self, a, b, msg=None):
813 """Just like self.assertTrue(a > b), but with a nicer default message."""
814 if not a > b:
815 standardMsg = '%r not greater than %r' % (a, b)
816 self.fail(self._formatMessage(msg, standardMsg))
817
818 def assertGreaterEqual(self, a, b, msg=None):
819 """Just like self.assertTrue(a >= b), but with a nicer default message."""
820 if not a >= b:
821 standardMsg = '%r not greater than or equal to %r' % (a, b)
822 self.fail(self._formatMessage(msg, standardMsg))
823
824 def assertIsNone(self, obj, msg=None):
825 """Same as self.assertTrue(obj is None), with a nicer default message."""
826 if obj is not None:
827 standardMsg = '%r is not None' % obj
828 self.fail(self._formatMessage(msg, standardMsg))
829
830 def assertIsNotNone(self, obj, msg=None):
831 """Included for symmetry with assertIsNone."""
832 if obj is None:
833 standardMsg = 'unexpectedly None'
834 self.fail(self._formatMessage(msg, standardMsg))
835
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000836 def assertIsInstance(self, obj, cls, msg=None):
837 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
838 default message."""
839 if not isinstance(obj, cls):
840 standardMsg = '%r is not an instance of %r' % (obj, cls)
841 self.fail(self._formatMessage(msg, standardMsg))
842
843 def assertNotIsInstance(self, obj, cls, msg=None):
844 """Included for symmetry with assertIsInstance."""
845 if isinstance(obj, cls):
846 standardMsg = '%r is an instance of %r' % (obj, cls)
847 self.fail(self._formatMessage(msg, standardMsg))
848
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000849 def assertRaisesRegexp(self, expected_exception, expected_regexp,
850 callable_obj=None, *args, **kwargs):
851 """Asserts that the message in a raised exception matches a regexp.
852
853 Args:
854 expected_exception: Exception class expected to be raised.
855 expected_regexp: Regexp (re pattern object or string) expected
856 to be found in error message.
857 callable_obj: Function to be called.
858 args: Extra args.
859 kwargs: Extra kwargs.
860 """
861 context = _AssertRaisesContext(expected_exception, self, callable_obj,
862 expected_regexp)
863 if callable_obj is None:
864 return context
865 with context:
866 callable_obj(*args, **kwargs)
867
868 def assertRegexpMatches(self, text, expected_regex, msg=None):
869 if isinstance(expected_regex, (str, bytes)):
870 expected_regex = re.compile(expected_regex)
871 if not expected_regex.search(text):
872 msg = msg or "Regexp didn't match"
873 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
874 raise self.failureException(msg)
875
876
877class FunctionTestCase(TestCase):
878 """A test case that wraps a test function.
879
880 This is useful for slipping pre-existing test functions into the
881 unittest framework. Optionally, set-up and tidy-up functions can be
882 supplied. As with TestCase, the tidy-up ('tearDown') function will
883 always be called if the set-up ('setUp') function ran successfully.
884 """
885
886 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
887 super(FunctionTestCase, self).__init__()
888 self._setUpFunc = setUp
889 self._tearDownFunc = tearDown
890 self._testFunc = testFunc
891 self._description = description
892
893 def setUp(self):
894 if self._setUpFunc is not None:
895 self._setUpFunc()
896
897 def tearDown(self):
898 if self._tearDownFunc is not None:
899 self._tearDownFunc()
900
901 def runTest(self):
902 self._testFunc()
903
904 def id(self):
905 return self._testFunc.__name__
906
907 def __eq__(self, other):
908 if not isinstance(other, self.__class__):
909 return NotImplemented
910
911 return self._setUpFunc == other._setUpFunc and \
912 self._tearDownFunc == other._tearDownFunc and \
913 self._testFunc == other._testFunc and \
914 self._description == other._description
915
916 def __ne__(self, other):
917 return not self == other
918
919 def __hash__(self):
920 return hash((type(self), self._setUpFunc, self._tearDownFunc,
921 self._testFunc, self._description))
922
923 def __str__(self):
924 return "%s (%s)" % (util.strclass(self.__class__),
925 self._testFunc.__name__)
926
927 def __repr__(self):
928 return "<%s testFunc=%s>" % (util.strclass(self.__class__),
929 self._testFunc)
930
931 def shortDescription(self):
932 if self._description is not None:
933 return self._description
934 doc = self._testFunc.__doc__
935 return doc and doc.split("\n")[0].strip() or None