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