blob: 18d977f54bfcf7e584a052d046fd96333683e42e [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):
102 pass
103
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
Kristján Valur Jónsson92a653a2009-11-13 16:10:13 +0000119 #store exception, without traceback, for later retrieval
Benjamin Peterson589c2d32009-11-13 22:09:10 +0000120 self.exc_value = 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)
192
193 def addTypeEqualityFunc(self, typeobj, function):
194 """Add a type specific assertEqual style function to compare a type.
195
196 This method is for use by TestCase subclasses that need to register
197 their own type equality functions to provide nicer error messages.
198
199 Args:
200 typeobj: The data type to call this function on when both values
201 are of the same type in assertEqual().
202 function: The callable taking two arguments and an optional
203 msg= argument that raises self.failureException with a
204 useful error message when the two arguments are not equal.
205 """
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000206 self._type_equality_funcs[typeobj] = function
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000207
208 def addCleanup(self, function, *args, **kwargs):
209 """Add a function, with arguments, to be called when the test is
210 completed. Functions added are called on a LIFO basis and are
211 called after tearDown on test failure or success.
212
213 Cleanup items are called even if setUp fails (unlike tearDown)."""
214 self._cleanups.append((function, args, kwargs))
215
216 def setUp(self):
217 "Hook method for setting up the test fixture before exercising it."
218 pass
219
220 def tearDown(self):
221 "Hook method for deconstructing the test fixture after testing it."
222 pass
223
224 def countTestCases(self):
225 return 1
226
227 def defaultTestResult(self):
228 return result.TestResult()
229
230 def shortDescription(self):
231 """Returns both the test method name and first line of its docstring.
232
233 If no docstring is given, only returns the method name.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000234 """
235 desc = str(self)
236 doc_first_line = None
237
238 if self._testMethodDoc:
239 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
240 if doc_first_line:
241 desc = '\n'.join((desc, doc_first_line))
242 return desc
243
244 def id(self):
245 return "%s.%s" % (util.strclass(self.__class__), self._testMethodName)
246
247 def __eq__(self, other):
248 if type(self) is not type(other):
249 return NotImplemented
250
251 return self._testMethodName == other._testMethodName
252
253 def __ne__(self, other):
254 return not self == other
255
256 def __hash__(self):
257 return hash((type(self), self._testMethodName))
258
259 def __str__(self):
260 return "%s (%s)" % (self._testMethodName, util.strclass(self.__class__))
261
262 def __repr__(self):
263 return "<%s testMethod=%s>" % \
264 (util.strclass(self.__class__), self._testMethodName)
265
266 def run(self, result=None):
267 orig_result = result
268 if result is None:
269 result = self.defaultTestResult()
270 startTestRun = getattr(result, 'startTestRun', None)
271 if startTestRun is not None:
272 startTestRun()
273
274 self._resultForDoCleanups = result
275 result.startTest(self)
276 if getattr(self.__class__, "__unittest_skip__", False):
277 # If the whole class was skipped.
278 try:
279 result.addSkip(self, self.__class__.__unittest_skip_why__)
280 finally:
281 result.stopTest(self)
282 return
283 testMethod = getattr(self, self._testMethodName)
284 try:
285 success = False
286 try:
287 self.setUp()
288 except SkipTest as e:
289 result.addSkip(self, str(e))
290 except Exception:
291 result.addError(self, sys.exc_info())
292 else:
293 try:
294 testMethod()
295 except self.failureException:
296 result.addFailure(self, sys.exc_info())
297 except _ExpectedFailure as e:
298 result.addExpectedFailure(self, e.exc_info)
299 except _UnexpectedSuccess:
300 result.addUnexpectedSuccess(self)
301 except SkipTest as e:
302 result.addSkip(self, str(e))
303 except Exception:
304 result.addError(self, sys.exc_info())
305 else:
306 success = True
307
308 try:
309 self.tearDown()
310 except Exception:
311 result.addError(self, sys.exc_info())
312 success = False
313
314 cleanUpSuccess = self.doCleanups()
315 success = success and cleanUpSuccess
316 if success:
317 result.addSuccess(self)
318 finally:
319 result.stopTest(self)
320 if orig_result is None:
321 stopTestRun = getattr(result, 'stopTestRun', None)
322 if stopTestRun is not None:
323 stopTestRun()
324
325 def doCleanups(self):
326 """Execute all cleanup functions. Normally called for you after
327 tearDown."""
328 result = self._resultForDoCleanups
329 ok = True
330 while self._cleanups:
331 function, args, kwargs = self._cleanups.pop(-1)
332 try:
333 function(*args, **kwargs)
334 except Exception:
335 ok = False
336 result.addError(self, sys.exc_info())
337 return ok
338
339 def __call__(self, *args, **kwds):
340 return self.run(*args, **kwds)
341
342 def debug(self):
343 """Run the test without collecting errors in a TestResult"""
344 self.setUp()
345 getattr(self, self._testMethodName)()
346 self.tearDown()
347
348 def skipTest(self, reason):
349 """Skip this test."""
350 raise SkipTest(reason)
351
352 def fail(self, msg=None):
353 """Fail immediately, with the given message."""
354 raise self.failureException(msg)
355
356 def assertFalse(self, expr, msg=None):
357 "Fail the test if the expression is true."
358 if expr:
359 msg = self._formatMessage(msg, "%r is not False" % expr)
360 raise self.failureException(msg)
361
362 def assertTrue(self, expr, msg=None):
363 """Fail the test unless the expression is true."""
364 if not expr:
365 msg = self._formatMessage(msg, "%r is not True" % expr)
366 raise self.failureException(msg)
367
368 def _formatMessage(self, msg, standardMsg):
369 """Honour the longMessage attribute when generating failure messages.
370 If longMessage is False this means:
371 * Use only an explicit message if it is provided
372 * Otherwise use the standard message for the assert
373
374 If longMessage is True:
375 * Use the standard message
376 * If an explicit message is provided, plus ' : ' and the explicit message
377 """
378 if not self.longMessage:
379 return msg or standardMsg
380 if msg is None:
381 return standardMsg
382 return standardMsg + ' : ' + msg
383
384
385 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
386 """Fail unless an exception of class excClass is thrown
387 by callableObj when invoked with arguments args and keyword
388 arguments kwargs. If a different type of exception is
389 thrown, it will not be caught, and the test case will be
390 deemed to have suffered an error, exactly as for an
391 unexpected exception.
392
393 If called with callableObj omitted or None, will return a
394 context object used like this::
395
Michael Foord1c42b122010-02-05 22:58:21 +0000396 with self.assertRaises(SomeException):
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000397 do_something()
Michael Foord1c42b122010-02-05 22:58:21 +0000398
399 The context manager keeps a reference to the exception as
400 the exc_value attribute. This allows you to inspect the
401 exception after the assertion::
402
403 with self.assertRaises(SomeException) as cm:
404 do_something()
405 the_exception = cm.exc_value
406 self.assertEquals(the_exception.error_code, 3)
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000407 """
408 context = _AssertRaisesContext(excClass, self, callableObj)
409 if callableObj is None:
410 return context
411 with context:
412 callableObj(*args, **kwargs)
413
414 def _getAssertEqualityFunc(self, first, second):
415 """Get a detailed comparison function for the types of the two args.
416
417 Returns: A callable accepting (first, second, msg=None) that will
418 raise a failure exception if first != second with a useful human
419 readable error message for those types.
420 """
421 #
422 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
423 # and vice versa. I opted for the conservative approach in case
424 # subclasses are not intended to be compared in detail to their super
425 # class instances using a type equality func. This means testing
426 # subtypes won't automagically use the detailed comparison. Callers
427 # should use their type specific assertSpamEqual method to compare
428 # subclasses if the detailed comparison is desired and appropriate.
429 # See the discussion in http://bugs.python.org/issue2578.
430 #
431 if type(first) is type(second):
432 asserter = self._type_equality_funcs.get(type(first))
433 if asserter is not None:
Benjamin Peterson8f326b22009-12-13 02:10:36 +0000434 return asserter
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000435
436 return self._baseAssertEqual
437
438 def _baseAssertEqual(self, first, second, msg=None):
439 """The default assertEqual implementation, not type specific."""
440 if not first == second:
441 standardMsg = '%r != %r' % (first, second)
442 msg = self._formatMessage(msg, standardMsg)
443 raise self.failureException(msg)
444
445 def assertEqual(self, first, second, msg=None):
446 """Fail if the two objects are unequal as determined by the '=='
447 operator.
448 """
449 assertion_func = self._getAssertEqualityFunc(first, second)
450 assertion_func(first, second, msg=msg)
451
452 def assertNotEqual(self, first, second, msg=None):
453 """Fail if the two objects are equal as determined by the '=='
454 operator.
455 """
456 if not first != second:
457 msg = self._formatMessage(msg, '%r == %r' % (first, second))
458 raise self.failureException(msg)
459
460 def assertAlmostEqual(self, first, second, *, places=7, msg=None):
461 """Fail if the two objects are unequal as determined by their
462 difference rounded to the given number of decimal places
463 (default 7) and comparing to zero.
464
465 Note that decimal places (from zero) are usually not the same
466 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000467
468 If the two objects compare equal then they will automatically
469 compare almost equal.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000470 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000471 if first == second:
472 # shortcut for ite
473 return
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000474 if round(abs(second-first), places) != 0:
475 standardMsg = '%r != %r within %r places' % (first, second, places)
476 msg = self._formatMessage(msg, standardMsg)
477 raise self.failureException(msg)
478
479 def assertNotAlmostEqual(self, first, second, *, places=7, msg=None):
480 """Fail if the two objects are equal as determined by their
481 difference rounded to the given number of decimal places
482 (default 7) and comparing to zero.
483
484 Note that decimal places (from zero) are usually not the same
485 as significant digits (measured from the most signficant digit).
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000486
487 Objects that are equal automatically fail.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000488 """
Benjamin Peterson4ac9ce42009-10-04 14:49:41 +0000489 if (first == second) or round(abs(second-first), places) == 0:
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000490 standardMsg = '%r == %r within %r places' % (first, second, places)
491 msg = self._formatMessage(msg, standardMsg)
492 raise self.failureException(msg)
493
494 # Synonyms for assertion methods
495
496 # The plurals are undocumented. Keep them that way to discourage use.
497 # Do not add more. Do not remove.
498 # Going through a deprecation cycle on these would annoy many people.
499 assertEquals = assertEqual
500 assertNotEquals = assertNotEqual
501 assertAlmostEquals = assertAlmostEqual
502 assertNotAlmostEquals = assertNotAlmostEqual
503 assert_ = assertTrue
504
505 # These fail* assertion method names are pending deprecation and will
506 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
507 def _deprecate(original_func):
508 def deprecated_func(*args, **kwargs):
509 warnings.warn(
510 'Please use {0} instead.'.format(original_func.__name__),
511 DeprecationWarning, 2)
512 return original_func(*args, **kwargs)
513 return deprecated_func
514
515 failUnlessEqual = _deprecate(assertEqual)
516 failIfEqual = _deprecate(assertNotEqual)
517 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
518 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
519 failUnless = _deprecate(assertTrue)
520 failUnlessRaises = _deprecate(assertRaises)
521 failIf = _deprecate(assertFalse)
522
523 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
524 """An equality assertion for ordered sequences (like lists and tuples).
525
R. David Murrayad13f222010-01-29 22:17:58 +0000526 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000527 which can be indexed, has a length, and has an equality operator.
528
529 Args:
530 seq1: The first sequence to compare.
531 seq2: The second sequence to compare.
532 seq_type: The expected datatype of the sequences, or None if no
533 datatype should be enforced.
534 msg: Optional message to use on failure instead of a list of
535 differences.
536 """
537 if seq_type != None:
538 seq_type_name = seq_type.__name__
539 if not isinstance(seq1, seq_type):
540 raise self.failureException('First sequence is not a %s: %r'
541 % (seq_type_name, seq1))
542 if not isinstance(seq2, seq_type):
543 raise self.failureException('Second sequence is not a %s: %r'
544 % (seq_type_name, seq2))
545 else:
546 seq_type_name = "sequence"
547
548 differing = None
549 try:
550 len1 = len(seq1)
551 except (TypeError, NotImplementedError):
552 differing = 'First %s has no length. Non-sequence?' % (
553 seq_type_name)
554
555 if differing is None:
556 try:
557 len2 = len(seq2)
558 except (TypeError, NotImplementedError):
559 differing = 'Second %s has no length. Non-sequence?' % (
560 seq_type_name)
561
562 if differing is None:
563 if seq1 == seq2:
564 return
565
566 seq1_repr = repr(seq1)
567 seq2_repr = repr(seq2)
568 if len(seq1_repr) > 30:
569 seq1_repr = seq1_repr[:30] + '...'
570 if len(seq2_repr) > 30:
571 seq2_repr = seq2_repr[:30] + '...'
572 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
573 differing = '%ss differ: %s != %s\n' % elements
574
575 for i in range(min(len1, len2)):
576 try:
577 item1 = seq1[i]
578 except (TypeError, IndexError, NotImplementedError):
579 differing += ('\nUnable to index element %d of first %s\n' %
580 (i, seq_type_name))
581 break
582
583 try:
584 item2 = seq2[i]
585 except (TypeError, IndexError, NotImplementedError):
586 differing += ('\nUnable to index element %d of second %s\n' %
587 (i, seq_type_name))
588 break
589
590 if item1 != item2:
591 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
592 (i, item1, item2))
593 break
594 else:
595 if (len1 == len2 and seq_type is None and
596 type(seq1) != type(seq2)):
597 # The sequences are the same, but have differing types.
598 return
599
600 if len1 > len2:
601 differing += ('\nFirst %s contains %d additional '
602 'elements.\n' % (seq_type_name, len1 - len2))
603 try:
604 differing += ('First extra element %d:\n%s\n' %
605 (len2, seq1[len2]))
606 except (TypeError, IndexError, NotImplementedError):
607 differing += ('Unable to index element %d '
608 'of first %s\n' % (len2, seq_type_name))
609 elif len1 < len2:
610 differing += ('\nSecond %s contains %d additional '
611 'elements.\n' % (seq_type_name, len2 - len1))
612 try:
613 differing += ('First extra element %d:\n%s\n' %
614 (len1, seq2[len1]))
615 except (TypeError, IndexError, NotImplementedError):
616 differing += ('Unable to index element %d '
617 'of second %s\n' % (len1, seq_type_name))
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000618 standardMsg = differing + '\n' + '\n'.join(
619 difflib.ndiff(pprint.pformat(seq1).splitlines(),
620 pprint.pformat(seq2).splitlines()))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000621 msg = self._formatMessage(msg, standardMsg)
622 self.fail(msg)
623
624 def assertListEqual(self, list1, list2, msg=None):
625 """A list-specific equality assertion.
626
627 Args:
628 list1: The first list to compare.
629 list2: The second list to compare.
630 msg: Optional message to use on failure instead of a list of
631 differences.
632
633 """
634 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
635
636 def assertTupleEqual(self, tuple1, tuple2, msg=None):
637 """A tuple-specific equality assertion.
638
639 Args:
640 tuple1: The first tuple to compare.
641 tuple2: The second tuple to compare.
642 msg: Optional message to use on failure instead of a list of
643 differences.
644 """
645 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
646
647 def assertSetEqual(self, set1, set2, msg=None):
648 """A set-specific equality assertion.
649
650 Args:
651 set1: The first set to compare.
652 set2: The second set to compare.
653 msg: Optional message to use on failure instead of a list of
654 differences.
655
656 For more general containership equality, assertSameElements will work
657 with things other than sets. This uses ducktyping to support
658 different types of sets, and is optimized for sets specifically
659 (parameters must support a difference method).
660 """
661 try:
662 difference1 = set1.difference(set2)
663 except TypeError as e:
664 self.fail('invalid type when attempting set difference: %s' % e)
665 except AttributeError as e:
666 self.fail('first argument does not support set difference: %s' % e)
667
668 try:
669 difference2 = set2.difference(set1)
670 except TypeError as e:
671 self.fail('invalid type when attempting set difference: %s' % e)
672 except AttributeError as e:
673 self.fail('second argument does not support set difference: %s' % e)
674
675 if not (difference1 or difference2):
676 return
677
678 lines = []
679 if difference1:
680 lines.append('Items in the first set but not the second:')
681 for item in difference1:
682 lines.append(repr(item))
683 if difference2:
684 lines.append('Items in the second set but not the first:')
685 for item in difference2:
686 lines.append(repr(item))
687
688 standardMsg = '\n'.join(lines)
689 self.fail(self._formatMessage(msg, standardMsg))
690
691 def assertIn(self, member, container, msg=None):
692 """Just like self.assertTrue(a in b), but with a nicer default message."""
693 if member not in container:
694 standardMsg = '%r not found in %r' % (member, container)
695 self.fail(self._formatMessage(msg, standardMsg))
696
697 def assertNotIn(self, member, container, msg=None):
698 """Just like self.assertTrue(a not in b), but with a nicer default message."""
699 if member in container:
700 standardMsg = '%r unexpectedly found in %r' % (member, container)
701 self.fail(self._formatMessage(msg, standardMsg))
702
703 def assertIs(self, expr1, expr2, msg=None):
704 """Just like self.assertTrue(a is b), but with a nicer default message."""
705 if expr1 is not expr2:
706 standardMsg = '%r is not %r' % (expr1, expr2)
707 self.fail(self._formatMessage(msg, standardMsg))
708
709 def assertIsNot(self, expr1, expr2, msg=None):
710 """Just like self.assertTrue(a is not b), but with a nicer default message."""
711 if expr1 is expr2:
712 standardMsg = 'unexpectedly identical: %r' % (expr1,)
713 self.fail(self._formatMessage(msg, standardMsg))
714
715 def assertDictEqual(self, d1, d2, msg=None):
716 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
717 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
718
719 if d1 != d2:
720 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
721 pprint.pformat(d1).splitlines(),
722 pprint.pformat(d2).splitlines())))
723 self.fail(self._formatMessage(msg, standardMsg))
724
725 def assertDictContainsSubset(self, expected, actual, msg=None):
726 """Checks whether actual is a superset of expected."""
727 missing = []
728 mismatched = []
729 for key, value in expected.items():
730 if key not in actual:
731 missing.append(key)
732 elif value != actual[key]:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000733 mismatched.append('%s, expected: %s, actual: %s' %
734 (key, value, actual[key]))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000735
736 if not (missing or mismatched):
737 return
738
739 standardMsg = ''
740 if missing:
741 standardMsg = 'Missing: %r' % ','.join(missing)
742 if mismatched:
743 if standardMsg:
744 standardMsg += '; '
745 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
746
747 self.fail(self._formatMessage(msg, standardMsg))
748
749 def assertSameElements(self, expected_seq, actual_seq, msg=None):
750 """An unordered sequence specific comparison.
751
752 Raises with an error message listing which elements of expected_seq
753 are missing from actual_seq and vice versa if any.
Michael Foord1c42b122010-02-05 22:58:21 +0000754
755 Duplicate elements are ignored when comparing *expected_seq* and
756 *actual_seq*. It is the equivalent of ``assertEqual(set(expected),
757 set(actual))`` but it works with sequences of unhashable objects as
758 well.
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000759 """
760 try:
761 expected = set(expected_seq)
762 actual = set(actual_seq)
763 missing = list(expected.difference(actual))
764 unexpected = list(actual.difference(expected))
765 missing.sort()
766 unexpected.sort()
767 except TypeError:
768 # Fall back to slower list-compare if any of the objects are
769 # not hashable.
770 expected = list(expected_seq)
771 actual = list(actual_seq)
772 try:
773 expected.sort()
774 actual.sort()
775 except TypeError:
776 missing, unexpected = util.unorderable_list_difference(expected,
777 actual)
778 else:
779 missing, unexpected = util.sorted_list_difference(expected,
780 actual)
781 errors = []
782 if missing:
783 errors.append('Expected, but missing:\n %r' % missing)
784 if unexpected:
785 errors.append('Unexpected, but present:\n %r' % unexpected)
786 if errors:
787 standardMsg = '\n'.join(errors)
788 self.fail(self._formatMessage(msg, standardMsg))
789
790 def assertMultiLineEqual(self, first, second, msg=None):
791 """Assert that two multi-line strings are equal."""
792 self.assert_(isinstance(first, str), (
793 'First argument is not a string'))
794 self.assert_(isinstance(second, str), (
795 'Second argument is not a string'))
796
797 if first != second:
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000798 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True),
799 second.splitlines(True)))
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000800 self.fail(self._formatMessage(msg, standardMsg))
801
802 def assertLess(self, a, b, msg=None):
803 """Just like self.assertTrue(a < b), but with a nicer default message."""
804 if not a < b:
805 standardMsg = '%r not less than %r' % (a, b)
806 self.fail(self._formatMessage(msg, standardMsg))
807
808 def assertLessEqual(self, a, b, msg=None):
809 """Just like self.assertTrue(a <= b), but with a nicer default message."""
810 if not a <= b:
811 standardMsg = '%r not less than or equal to %r' % (a, b)
812 self.fail(self._formatMessage(msg, standardMsg))
813
814 def assertGreater(self, a, b, msg=None):
815 """Just like self.assertTrue(a > b), but with a nicer default message."""
816 if not a > b:
817 standardMsg = '%r not greater than %r' % (a, b)
818 self.fail(self._formatMessage(msg, standardMsg))
819
820 def assertGreaterEqual(self, a, b, msg=None):
821 """Just like self.assertTrue(a >= b), but with a nicer default message."""
822 if not a >= b:
823 standardMsg = '%r not greater than or equal to %r' % (a, b)
824 self.fail(self._formatMessage(msg, standardMsg))
825
826 def assertIsNone(self, obj, msg=None):
827 """Same as self.assertTrue(obj is None), with a nicer default message."""
828 if obj is not None:
829 standardMsg = '%r is not None' % obj
830 self.fail(self._formatMessage(msg, standardMsg))
831
832 def assertIsNotNone(self, obj, msg=None):
833 """Included for symmetry with assertIsNone."""
834 if obj is None:
835 standardMsg = 'unexpectedly None'
836 self.fail(self._formatMessage(msg, standardMsg))
837
Benjamin Peterson6e8c7572009-10-04 20:19:21 +0000838 def assertIsInstance(self, obj, cls, msg=None):
839 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
840 default message."""
841 if not isinstance(obj, cls):
842 standardMsg = '%r is not an instance of %r' % (obj, cls)
843 self.fail(self._formatMessage(msg, standardMsg))
844
845 def assertNotIsInstance(self, obj, cls, msg=None):
846 """Included for symmetry with assertIsInstance."""
847 if isinstance(obj, cls):
848 standardMsg = '%r is an instance of %r' % (obj, cls)
849 self.fail(self._formatMessage(msg, standardMsg))
850
Benjamin Petersonbed7d042009-07-19 21:01:52 +0000851 def assertRaisesRegexp(self, expected_exception, expected_regexp,
852 callable_obj=None, *args, **kwargs):
853 """Asserts that the message in a raised exception matches a regexp.
854
855 Args:
856 expected_exception: Exception class expected to be raised.
857 expected_regexp: Regexp (re pattern object or string) expected
858 to be found in error message.
859 callable_obj: Function to be called.
860 args: Extra args.
861 kwargs: Extra kwargs.
862 """
863 context = _AssertRaisesContext(expected_exception, self, callable_obj,
864 expected_regexp)
865 if callable_obj is None:
866 return context
867 with context:
868 callable_obj(*args, **kwargs)
869
870 def assertRegexpMatches(self, text, expected_regex, msg=None):
871 if isinstance(expected_regex, (str, bytes)):
872 expected_regex = re.compile(expected_regex)
873 if not expected_regex.search(text):
874 msg = msg or "Regexp didn't match"
875 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
876 raise self.failureException(msg)
877
878
879class FunctionTestCase(TestCase):
880 """A test case that wraps a test function.
881
882 This is useful for slipping pre-existing test functions into the
883 unittest framework. Optionally, set-up and tidy-up functions can be
884 supplied. As with TestCase, the tidy-up ('tearDown') function will
885 always be called if the set-up ('setUp') function ran successfully.
886 """
887
888 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
889 super(FunctionTestCase, self).__init__()
890 self._setUpFunc = setUp
891 self._tearDownFunc = tearDown
892 self._testFunc = testFunc
893 self._description = description
894
895 def setUp(self):
896 if self._setUpFunc is not None:
897 self._setUpFunc()
898
899 def tearDown(self):
900 if self._tearDownFunc is not None:
901 self._tearDownFunc()
902
903 def runTest(self):
904 self._testFunc()
905
906 def id(self):
907 return self._testFunc.__name__
908
909 def __eq__(self, other):
910 if not isinstance(other, self.__class__):
911 return NotImplemented
912
913 return self._setUpFunc == other._setUpFunc and \
914 self._tearDownFunc == other._tearDownFunc and \
915 self._testFunc == other._testFunc and \
916 self._description == other._description
917
918 def __ne__(self, other):
919 return not self == other
920
921 def __hash__(self):
922 return hash((type(self), self._setUpFunc, self._tearDownFunc,
923 self._testFunc, self._description))
924
925 def __str__(self):
926 return "%s (%s)" % (util.strclass(self.__class__),
927 self._testFunc.__name__)
928
929 def __repr__(self):
930 return "<%s testFunc=%s>" % (util.strclass(self.__class__),
931 self._testFunc)
932
933 def shortDescription(self):
934 if self._description is not None:
935 return self._description
936 doc = self._testFunc.__doc__
937 return doc and doc.split("\n")[0].strip() or None