blob: cd8f4fa0092c8e8b34a92131e8acc5548587b84a [file] [log] [blame]
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001"""Test case implementation"""
2
Michael Foorde6e0e262010-12-19 15:52:56 +00003import collections
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00004import sys
5import functools
6import difflib
7import pprint
8import re
9import warnings
10
Michael Foord225a0992010-02-18 20:30:09 +000011from . import result
Michael Foord98e7b762010-03-20 03:00:34 +000012from .util import (
13 strclass, safe_repr, sorted_list_difference, unorderable_list_difference
14)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000015
Michael Foordb1aa30f2010-03-22 00:06:30 +000016__unittest = True
Michael Foordb1aa30f2010-03-22 00:06:30 +000017
Michael Foord5fe21ff2010-06-05 13:38:16 +000018
19DIFF_OMITTED = ('\nDiff is %s characters long. '
20 'Set self.maxDiff to None to see it.')
21
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000022class SkipTest(Exception):
23 """
24 Raise this exception in a test to skip it.
25
26 Usually you can use TestResult.skip() or one of the skipping decorators
27 instead of raising this directly.
28 """
29 pass
30
31class _ExpectedFailure(Exception):
32 """
33 Raise this when a test is expected to fail.
34
35 This is an implementation detail.
36 """
37
38 def __init__(self, exc_info):
39 super(_ExpectedFailure, self).__init__()
40 self.exc_info = exc_info
41
42class _UnexpectedSuccess(Exception):
43 """
44 The test was supposed to fail, but it didn't!
45 """
46 pass
47
48def _id(obj):
49 return obj
50
51def skip(reason):
52 """
53 Unconditionally skip a test.
54 """
55 def decorator(test_item):
Michael Foord53e8eea2010-03-07 20:22:12 +000056 if not (isinstance(test_item, type) and issubclass(test_item, TestCase)):
57 @functools.wraps(test_item)
58 def skip_wrapper(*args, **kwargs):
59 raise SkipTest(reason)
60 test_item = skip_wrapper
61
62 test_item.__unittest_skip__ = True
63 test_item.__unittest_skip_why__ = reason
64 return test_item
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +000065 return decorator
66
67def skipIf(condition, reason):
68 """
69 Skip a test if the condition is true.
70 """
71 if condition:
72 return skip(reason)
73 return _id
74
75def skipUnless(condition, reason):
76 """
77 Skip a test unless the condition is true.
78 """
79 if not condition:
80 return skip(reason)
81 return _id
82
83
84def expectedFailure(func):
85 @functools.wraps(func)
86 def wrapper(*args, **kwargs):
87 try:
88 func(*args, **kwargs)
89 except Exception:
90 raise _ExpectedFailure(sys.exc_info())
91 raise _UnexpectedSuccess
92 return wrapper
93
94
95class _AssertRaisesContext(object):
96 """A context manager used to implement TestCase.assertRaises* methods."""
97
98 def __init__(self, expected, test_case, expected_regexp=None):
99 self.expected = expected
100 self.failureException = test_case.failureException
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000101 self.expected_regexp = expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000102
103 def __enter__(self):
Michael Foord2bd52dc2010-02-07 18:44:12 +0000104 return self
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000105
106 def __exit__(self, exc_type, exc_value, tb):
107 if exc_type is None:
108 try:
109 exc_name = self.expected.__name__
110 except AttributeError:
111 exc_name = str(self.expected)
112 raise self.failureException(
113 "{0} not raised".format(exc_name))
114 if not issubclass(exc_type, self.expected):
115 # let unexpected exceptions pass through
116 return False
Georg Brandldc3694b2010-02-07 17:02:22 +0000117 self.exception = exc_value # store for later retrieval
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000118 if self.expected_regexp is None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000119 return True
120
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000121 expected_regexp = self.expected_regexp
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000122 if isinstance(expected_regexp, basestring):
123 expected_regexp = re.compile(expected_regexp)
124 if not expected_regexp.search(str(exc_value)):
125 raise self.failureException('"%s" does not match "%s"' %
126 (expected_regexp.pattern, str(exc_value)))
127 return True
128
129
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000130class TestCase(object):
131 """A class whose instances are single test cases.
132
133 By default, the test code itself should be placed in a method named
134 'runTest'.
135
136 If the fixture may be used for many test cases, create as
137 many test methods as are needed. When instantiating such a TestCase
138 subclass, specify in the constructor arguments the name of the test method
139 that the instance is to execute.
140
141 Test authors should subclass TestCase for their own tests. Construction
142 and deconstruction of the test's environment ('fixture') can be
143 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
144
145 If it is necessary to override the __init__ method, the base class
146 __init__ method must always be called. It is important that subclasses
147 should not change the signature of their __init__ method, since instances
148 of the classes are instantiated automatically by parts of the framework
149 in order to be run.
150 """
151
152 # This attribute determines which exception will be raised when
153 # the instance's assertion methods fail; test methods raising this
154 # exception will be deemed to have 'failed' rather than 'errored'
155
156 failureException = AssertionError
157
158 # This attribute determines whether long messages (including repr of
159 # objects used in assert methods) will be printed on failure in *addition*
160 # to any explicit message passed.
161
162 longMessage = False
163
Michael Foordae1bb9a2010-06-09 12:29:56 +0000164 # This attribute sets the maximum length of a diff in failure messages
Michael Foorde37d75f2010-06-05 12:10:52 +0000165 # by assert methods using difflib. It is looked up as an instance attribute
166 # so can be configured by individual tests if required.
Michael Foordc532c572010-06-05 23:58:40 +0000167
Michael Foorde37d75f2010-06-05 12:10:52 +0000168 maxDiff = 80*8
169
Michael Foord5ffa3252010-03-07 22:04:55 +0000170 # Attribute used by TestSuite for classSetUp
171
172 _classSetupFailed = False
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000173
174 def __init__(self, methodName='runTest'):
175 """Create an instance of the class that will use the named test
176 method when executed. Raises a ValueError if the instance does
177 not have a method with the specified name.
178 """
179 self._testMethodName = methodName
180 self._resultForDoCleanups = None
181 try:
182 testMethod = getattr(self, methodName)
183 except AttributeError:
Michael Foordc2294dd2010-02-18 21:37:07 +0000184 raise ValueError("no such test method in %s: %s" %
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000185 (self.__class__, methodName))
186 self._testMethodDoc = testMethod.__doc__
187 self._cleanups = []
188
189 # Map types to custom assertEqual functions that will compare
190 # instances of said type in more detail to generate a more useful
191 # error message.
192 self._type_equality_funcs = {}
193 self.addTypeEqualityFunc(dict, self.assertDictEqual)
194 self.addTypeEqualityFunc(list, self.assertListEqual)
195 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
196 self.addTypeEqualityFunc(set, self.assertSetEqual)
197 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
Michael Foordfe6349c2010-02-08 22:41:16 +0000198 self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000199
200 def addTypeEqualityFunc(self, typeobj, function):
201 """Add a type specific assertEqual style function to compare a type.
202
203 This method is for use by TestCase subclasses that need to register
204 their own type equality functions to provide nicer error messages.
205
206 Args:
207 typeobj: The data type to call this function on when both values
208 are of the same type in assertEqual().
209 function: The callable taking two arguments and an optional
210 msg= argument that raises self.failureException with a
211 useful error message when the two arguments are not equal.
212 """
Benjamin Petersond46430b2009-11-29 22:26:26 +0000213 self._type_equality_funcs[typeobj] = function
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000214
215 def addCleanup(self, function, *args, **kwargs):
216 """Add a function, with arguments, to be called when the test is
217 completed. Functions added are called on a LIFO basis and are
218 called after tearDown on test failure or success.
219
220 Cleanup items are called even if setUp fails (unlike tearDown)."""
221 self._cleanups.append((function, args, kwargs))
222
223 def setUp(self):
224 "Hook method for setting up the test fixture before exercising it."
225 pass
226
227 def tearDown(self):
228 "Hook method for deconstructing the test fixture after testing it."
229 pass
230
Michael Foord5ffa3252010-03-07 22:04:55 +0000231 @classmethod
232 def setUpClass(cls):
233 "Hook method for setting up class fixture before running tests in the class."
234
235 @classmethod
236 def tearDownClass(cls):
237 "Hook method for deconstructing the class fixture after running all tests in the class."
238
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000239 def countTestCases(self):
240 return 1
241
242 def defaultTestResult(self):
243 return result.TestResult()
244
245 def shortDescription(self):
Michael Foorddb43b5a2010-02-10 14:25:12 +0000246 """Returns a one-line description of the test, or None if no
247 description has been provided.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000248
Michael Foorddb43b5a2010-02-10 14:25:12 +0000249 The default implementation of this method returns the first line of
250 the specified test method's docstring.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000251 """
Michael Foorddb43b5a2010-02-10 14:25:12 +0000252 doc = self._testMethodDoc
253 return doc and doc.split("\n")[0].strip() or None
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000254
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000255
256 def id(self):
Michael Foord225a0992010-02-18 20:30:09 +0000257 return "%s.%s" % (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000258
259 def __eq__(self, other):
260 if type(self) is not type(other):
261 return NotImplemented
262
263 return self._testMethodName == other._testMethodName
264
265 def __ne__(self, other):
266 return not self == other
267
268 def __hash__(self):
269 return hash((type(self), self._testMethodName))
270
271 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +0000272 return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000273
274 def __repr__(self):
275 return "<%s testMethod=%s>" % \
Michael Foord225a0992010-02-18 20:30:09 +0000276 (strclass(self.__class__), self._testMethodName)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000277
Michael Foordae3db0a2010-02-22 23:28:32 +0000278 def _addSkip(self, result, reason):
279 addSkip = getattr(result, 'addSkip', None)
280 if addSkip is not None:
281 addSkip(self, reason)
282 else:
283 warnings.warn("TestResult has no addSkip method, skips not reported",
284 RuntimeWarning, 2)
285 result.addSuccess(self)
286
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000287 def run(self, result=None):
288 orig_result = result
289 if result is None:
290 result = self.defaultTestResult()
291 startTestRun = getattr(result, 'startTestRun', None)
292 if startTestRun is not None:
293 startTestRun()
294
295 self._resultForDoCleanups = result
296 result.startTest(self)
Michael Foord53e8eea2010-03-07 20:22:12 +0000297
298 testMethod = getattr(self, self._testMethodName)
299 if (getattr(self.__class__, "__unittest_skip__", False) or
300 getattr(testMethod, "__unittest_skip__", False)):
301 # If the class or method was skipped.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000302 try:
Michael Foord53e8eea2010-03-07 20:22:12 +0000303 skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
304 or getattr(testMethod, '__unittest_skip_why__', ''))
305 self._addSkip(result, skip_why)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000306 finally:
307 result.stopTest(self)
308 return
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000309 try:
310 success = False
311 try:
312 self.setUp()
313 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000314 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000315 except KeyboardInterrupt:
316 raise
317 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000318 result.addError(self, sys.exc_info())
319 else:
320 try:
321 testMethod()
Michael Foorda17f0762010-12-19 14:53:19 +0000322 except KeyboardInterrupt:
323 raise
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000324 except self.failureException:
325 result.addFailure(self, sys.exc_info())
326 except _ExpectedFailure as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000327 addExpectedFailure = getattr(result, 'addExpectedFailure', None)
328 if addExpectedFailure is not None:
329 addExpectedFailure(self, e.exc_info)
330 else:
331 warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
332 RuntimeWarning)
333 result.addSuccess(self)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000334 except _UnexpectedSuccess:
Michael Foordae3db0a2010-02-22 23:28:32 +0000335 addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
336 if addUnexpectedSuccess is not None:
337 addUnexpectedSuccess(self)
338 else:
339 warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
340 RuntimeWarning)
341 result.addFailure(self, sys.exc_info())
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000342 except SkipTest as e:
Michael Foordae3db0a2010-02-22 23:28:32 +0000343 self._addSkip(result, str(e))
Michael Foorda17f0762010-12-19 14:53:19 +0000344 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000345 result.addError(self, sys.exc_info())
346 else:
347 success = True
348
349 try:
350 self.tearDown()
Michael Foorda17f0762010-12-19 14:53:19 +0000351 except KeyboardInterrupt:
352 raise
353 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000354 result.addError(self, sys.exc_info())
355 success = False
356
357 cleanUpSuccess = self.doCleanups()
358 success = success and cleanUpSuccess
359 if success:
360 result.addSuccess(self)
361 finally:
362 result.stopTest(self)
363 if orig_result is None:
364 stopTestRun = getattr(result, 'stopTestRun', None)
365 if stopTestRun is not None:
366 stopTestRun()
367
368 def doCleanups(self):
369 """Execute all cleanup functions. Normally called for you after
370 tearDown."""
371 result = self._resultForDoCleanups
372 ok = True
373 while self._cleanups:
374 function, args, kwargs = self._cleanups.pop(-1)
375 try:
376 function(*args, **kwargs)
Michael Foorda17f0762010-12-19 14:53:19 +0000377 except KeyboardInterrupt:
378 raise
379 except:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000380 ok = False
381 result.addError(self, sys.exc_info())
382 return ok
383
384 def __call__(self, *args, **kwds):
385 return self.run(*args, **kwds)
386
387 def debug(self):
388 """Run the test without collecting errors in a TestResult"""
389 self.setUp()
390 getattr(self, self._testMethodName)()
391 self.tearDown()
Michael Foord0fedb282010-06-08 22:44:52 +0000392 while self._cleanups:
393 function, args, kwargs = self._cleanups.pop(-1)
394 function(*args, **kwargs)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000395
396 def skipTest(self, reason):
397 """Skip this test."""
398 raise SkipTest(reason)
399
400 def fail(self, msg=None):
401 """Fail immediately, with the given message."""
402 raise self.failureException(msg)
403
404 def assertFalse(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000405 """Check that the expression is false."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000406 if expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000407 msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000408 raise self.failureException(msg)
409
410 def assertTrue(self, expr, msg=None):
Ezio Melottic139a562010-12-18 17:58:29 +0000411 """Check that the expression is true."""
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000412 if not expr:
Ezio Melottic139a562010-12-18 17:58:29 +0000413 msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000414 raise self.failureException(msg)
415
416 def _formatMessage(self, msg, standardMsg):
417 """Honour the longMessage attribute when generating failure messages.
418 If longMessage is False this means:
419 * Use only an explicit message if it is provided
420 * Otherwise use the standard message for the assert
421
422 If longMessage is True:
423 * Use the standard message
424 * If an explicit message is provided, plus ' : ' and the explicit message
425 """
426 if not self.longMessage:
427 return msg or standardMsg
428 if msg is None:
429 return standardMsg
Michael Foord53e8eea2010-03-07 20:22:12 +0000430 try:
431 # don't switch to '{}' formatting in Python 2.X
432 # it changes the way unicode input is handled
433 return '%s : %s' % (standardMsg, msg)
434 except UnicodeDecodeError:
435 return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000436
437
438 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
439 """Fail unless an exception of class excClass is thrown
440 by callableObj when invoked with arguments args and keyword
441 arguments kwargs. If a different type of exception is
442 thrown, it will not be caught, and the test case will be
443 deemed to have suffered an error, exactly as for an
444 unexpected exception.
445
446 If called with callableObj omitted or None, will return a
447 context object used like this::
448
Michael Foordd0edec32010-02-05 22:55:09 +0000449 with self.assertRaises(SomeException):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000450 do_something()
Michael Foordd0edec32010-02-05 22:55:09 +0000451
452 The context manager keeps a reference to the exception as
Ezio Melotticd4f6572010-02-08 21:52:08 +0000453 the 'exception' attribute. This allows you to inspect the
Michael Foordd0edec32010-02-05 22:55:09 +0000454 exception after the assertion::
455
456 with self.assertRaises(SomeException) as cm:
457 do_something()
Georg Brandldc3694b2010-02-07 17:02:22 +0000458 the_exception = cm.exception
Michael Foord757cc4d2010-02-05 23:22:37 +0000459 self.assertEqual(the_exception.error_code, 3)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000460 """
461 context = _AssertRaisesContext(excClass, self)
462 if callableObj is None:
463 return context
464 with context:
465 callableObj(*args, **kwargs)
466
467 def _getAssertEqualityFunc(self, first, second):
468 """Get a detailed comparison function for the types of the two args.
469
470 Returns: A callable accepting (first, second, msg=None) that will
471 raise a failure exception if first != second with a useful human
472 readable error message for those types.
473 """
474 #
475 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
476 # and vice versa. I opted for the conservative approach in case
477 # subclasses are not intended to be compared in detail to their super
478 # class instances using a type equality func. This means testing
479 # subtypes won't automagically use the detailed comparison. Callers
480 # should use their type specific assertSpamEqual method to compare
481 # subclasses if the detailed comparison is desired and appropriate.
482 # See the discussion in http://bugs.python.org/issue2578.
483 #
484 if type(first) is type(second):
485 asserter = self._type_equality_funcs.get(type(first))
486 if asserter is not None:
Benjamin Petersond46430b2009-11-29 22:26:26 +0000487 return asserter
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000488
489 return self._baseAssertEqual
490
491 def _baseAssertEqual(self, first, second, msg=None):
492 """The default assertEqual implementation, not type specific."""
493 if not first == second:
Michael Foord225a0992010-02-18 20:30:09 +0000494 standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000495 msg = self._formatMessage(msg, standardMsg)
496 raise self.failureException(msg)
497
498 def assertEqual(self, first, second, msg=None):
499 """Fail if the two objects are unequal as determined by the '=='
500 operator.
501 """
502 assertion_func = self._getAssertEqualityFunc(first, second)
503 assertion_func(first, second, msg=msg)
504
505 def assertNotEqual(self, first, second, msg=None):
506 """Fail if the two objects are equal as determined by the '=='
507 operator.
508 """
509 if not first != second:
Michael Foord225a0992010-02-18 20:30:09 +0000510 msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
511 safe_repr(second)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000512 raise self.failureException(msg)
513
Michael Foorda7e08fe2010-03-27 19:10:11 +0000514
515 def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000516 """Fail if the two objects are unequal as determined by their
517 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000518 (default 7) and comparing to zero, or by comparing that the
519 between the two objects is more than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000520
521 Note that decimal places (from zero) are usually not the same
522 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000523
524 If the two objects compare equal then they will automatically
525 compare almost equal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000526 """
Michael Foordc3f79372009-09-13 16:40:02 +0000527 if first == second:
Michael Foorda7e08fe2010-03-27 19:10:11 +0000528 # shortcut
Michael Foordc3f79372009-09-13 16:40:02 +0000529 return
Michael Foorda7e08fe2010-03-27 19:10:11 +0000530 if delta is not None and places is not None:
531 raise TypeError("specify delta or places not both")
532
533 if delta is not None:
534 if abs(first - second) <= delta:
535 return
536
537 standardMsg = '%s != %s within %s delta' % (safe_repr(first),
538 safe_repr(second),
539 safe_repr(delta))
540 else:
541 if places is None:
542 places = 7
543
544 if round(abs(second-first), places) == 0:
545 return
546
Michael Foord225a0992010-02-18 20:30:09 +0000547 standardMsg = '%s != %s within %r places' % (safe_repr(first),
548 safe_repr(second),
549 places)
Michael Foorda7e08fe2010-03-27 19:10:11 +0000550 msg = self._formatMessage(msg, standardMsg)
551 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000552
Michael Foorda7e08fe2010-03-27 19:10:11 +0000553 def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000554 """Fail if the two objects are equal as determined by their
555 difference rounded to the given number of decimal places
Michael Foorda7e08fe2010-03-27 19:10:11 +0000556 (default 7) and comparing to zero, or by comparing that the
557 between the two objects is less than the given delta.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000558
559 Note that decimal places (from zero) are usually not the same
560 as significant digits (measured from the most signficant digit).
Michael Foordc3f79372009-09-13 16:40:02 +0000561
562 Objects that are equal automatically fail.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000563 """
Michael Foorda7e08fe2010-03-27 19:10:11 +0000564 if delta is not None and places is not None:
565 raise TypeError("specify delta or places not both")
566 if delta is not None:
567 if not (first == second) and abs(first - second) > delta:
568 return
569 standardMsg = '%s == %s within %s delta' % (safe_repr(first),
570 safe_repr(second),
571 safe_repr(delta))
572 else:
573 if places is None:
574 places = 7
575 if not (first == second) and round(abs(second-first), places) != 0:
576 return
Michael Foord225a0992010-02-18 20:30:09 +0000577 standardMsg = '%s == %s within %r places' % (safe_repr(first),
Michael Foorda7e08fe2010-03-27 19:10:11 +0000578 safe_repr(second),
579 places)
580
581 msg = self._formatMessage(msg, standardMsg)
582 raise self.failureException(msg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000583
584 # Synonyms for assertion methods
585
586 # The plurals are undocumented. Keep them that way to discourage use.
587 # Do not add more. Do not remove.
588 # Going through a deprecation cycle on these would annoy many people.
589 assertEquals = assertEqual
590 assertNotEquals = assertNotEqual
591 assertAlmostEquals = assertAlmostEqual
592 assertNotAlmostEquals = assertNotAlmostEqual
Michael Foord67dfc772010-02-10 14:31:30 +0000593 assert_ = assertTrue
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000594
595 # These fail* assertion method names are pending deprecation and will
596 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
597 def _deprecate(original_func):
598 def deprecated_func(*args, **kwargs):
599 warnings.warn(
600 'Please use {0} instead.'.format(original_func.__name__),
601 PendingDeprecationWarning, 2)
602 return original_func(*args, **kwargs)
603 return deprecated_func
604
605 failUnlessEqual = _deprecate(assertEqual)
606 failIfEqual = _deprecate(assertNotEqual)
607 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
608 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
609 failUnless = _deprecate(assertTrue)
610 failUnlessRaises = _deprecate(assertRaises)
611 failIf = _deprecate(assertFalse)
612
Michael Foorde37d75f2010-06-05 12:10:52 +0000613 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000614 """An equality assertion for ordered sequences (like lists and tuples).
615
R. David Murray05b41712010-01-29 19:35:39 +0000616 For the purposes of this function, a valid ordered sequence type is one
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000617 which can be indexed, has a length, and has an equality operator.
618
619 Args:
620 seq1: The first sequence to compare.
621 seq2: The second sequence to compare.
622 seq_type: The expected datatype of the sequences, or None if no
623 datatype should be enforced.
624 msg: Optional message to use on failure instead of a list of
625 differences.
626 """
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000627 if seq_type is not None:
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000628 seq_type_name = seq_type.__name__
629 if not isinstance(seq1, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000630 raise self.failureException('First sequence is not a %s: %s'
631 % (seq_type_name, safe_repr(seq1)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000632 if not isinstance(seq2, seq_type):
Michael Foord225a0992010-02-18 20:30:09 +0000633 raise self.failureException('Second sequence is not a %s: %s'
634 % (seq_type_name, safe_repr(seq2)))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000635 else:
636 seq_type_name = "sequence"
637
638 differing = None
639 try:
640 len1 = len(seq1)
641 except (TypeError, NotImplementedError):
642 differing = 'First %s has no length. Non-sequence?' % (
643 seq_type_name)
644
645 if differing is None:
646 try:
647 len2 = len(seq2)
648 except (TypeError, NotImplementedError):
649 differing = 'Second %s has no length. Non-sequence?' % (
650 seq_type_name)
651
652 if differing is None:
653 if seq1 == seq2:
654 return
655
Michael Foord225a0992010-02-18 20:30:09 +0000656 seq1_repr = safe_repr(seq1)
657 seq2_repr = safe_repr(seq2)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000658 if len(seq1_repr) > 30:
659 seq1_repr = seq1_repr[:30] + '...'
660 if len(seq2_repr) > 30:
661 seq2_repr = seq2_repr[:30] + '...'
662 elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
663 differing = '%ss differ: %s != %s\n' % elements
664
665 for i in xrange(min(len1, len2)):
666 try:
667 item1 = seq1[i]
668 except (TypeError, IndexError, NotImplementedError):
669 differing += ('\nUnable to index element %d of first %s\n' %
670 (i, seq_type_name))
671 break
672
673 try:
674 item2 = seq2[i]
675 except (TypeError, IndexError, NotImplementedError):
676 differing += ('\nUnable to index element %d of second %s\n' %
677 (i, seq_type_name))
678 break
679
680 if item1 != item2:
681 differing += ('\nFirst differing element %d:\n%s\n%s\n' %
682 (i, item1, item2))
683 break
684 else:
685 if (len1 == len2 and seq_type is None and
686 type(seq1) != type(seq2)):
687 # The sequences are the same, but have differing types.
688 return
689
690 if len1 > len2:
691 differing += ('\nFirst %s contains %d additional '
692 'elements.\n' % (seq_type_name, len1 - len2))
693 try:
694 differing += ('First extra element %d:\n%s\n' %
695 (len2, seq1[len2]))
696 except (TypeError, IndexError, NotImplementedError):
697 differing += ('Unable to index element %d '
698 'of first %s\n' % (len2, seq_type_name))
699 elif len1 < len2:
700 differing += ('\nSecond %s contains %d additional '
701 'elements.\n' % (seq_type_name, len2 - len1))
702 try:
703 differing += ('First extra element %d:\n%s\n' %
704 (len1, seq2[len1]))
705 except (TypeError, IndexError, NotImplementedError):
706 differing += ('Unable to index element %d '
707 'of second %s\n' % (len1, seq_type_name))
Michael Foord01007022010-06-05 11:23:51 +0000708 standardMsg = differing
709 diffMsg = '\n' + '\n'.join(
Georg Brandl46cc46a2009-10-01 20:11:14 +0000710 difflib.ndiff(pprint.pformat(seq1).splitlines(),
711 pprint.pformat(seq2).splitlines()))
Michael Foorde37d75f2010-06-05 12:10:52 +0000712 standardMsg = self._truncateMessage(standardMsg, diffMsg)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000713 msg = self._formatMessage(msg, standardMsg)
714 self.fail(msg)
715
Michael Foorde37d75f2010-06-05 12:10:52 +0000716 def _truncateMessage(self, message, diff):
717 max_diff = self.maxDiff
Michael Foorda4412872010-06-05 11:46:59 +0000718 if max_diff is None or len(diff) <= max_diff:
719 return message + diff
Michael Foord5fe21ff2010-06-05 13:38:16 +0000720 return message + (DIFF_OMITTED % len(diff))
Michael Foorda4412872010-06-05 11:46:59 +0000721
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000722 def assertListEqual(self, list1, list2, msg=None):
723 """A list-specific equality assertion.
724
725 Args:
726 list1: The first list to compare.
727 list2: The second list to compare.
728 msg: Optional message to use on failure instead of a list of
729 differences.
730
731 """
732 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
733
734 def assertTupleEqual(self, tuple1, tuple2, msg=None):
735 """A tuple-specific equality assertion.
736
737 Args:
738 tuple1: The first tuple to compare.
739 tuple2: The second tuple to compare.
740 msg: Optional message to use on failure instead of a list of
741 differences.
742 """
743 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
744
745 def assertSetEqual(self, set1, set2, msg=None):
746 """A set-specific equality assertion.
747
748 Args:
749 set1: The first set to compare.
750 set2: The second set to compare.
751 msg: Optional message to use on failure instead of a list of
752 differences.
753
Michael Foord98e7b762010-03-20 03:00:34 +0000754 assertSetEqual uses ducktyping to support different types of sets, and
755 is optimized for sets specifically (parameters must support a
756 difference method).
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000757 """
758 try:
759 difference1 = set1.difference(set2)
760 except TypeError, e:
761 self.fail('invalid type when attempting set difference: %s' % e)
762 except AttributeError, e:
763 self.fail('first argument does not support set difference: %s' % e)
764
765 try:
766 difference2 = set2.difference(set1)
767 except TypeError, e:
768 self.fail('invalid type when attempting set difference: %s' % e)
769 except AttributeError, e:
770 self.fail('second argument does not support set difference: %s' % e)
771
772 if not (difference1 or difference2):
773 return
774
775 lines = []
776 if difference1:
777 lines.append('Items in the first set but not the second:')
778 for item in difference1:
779 lines.append(repr(item))
780 if difference2:
781 lines.append('Items in the second set but not the first:')
782 for item in difference2:
783 lines.append(repr(item))
784
785 standardMsg = '\n'.join(lines)
786 self.fail(self._formatMessage(msg, standardMsg))
787
788 def assertIn(self, member, container, msg=None):
789 """Just like self.assertTrue(a in b), but with a nicer default message."""
790 if member not in container:
Michael Foord225a0992010-02-18 20:30:09 +0000791 standardMsg = '%s not found in %s' % (safe_repr(member),
792 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000793 self.fail(self._formatMessage(msg, standardMsg))
794
795 def assertNotIn(self, member, container, msg=None):
796 """Just like self.assertTrue(a not in b), but with a nicer default message."""
797 if member in container:
Michael Foord225a0992010-02-18 20:30:09 +0000798 standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
799 safe_repr(container))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000800 self.fail(self._formatMessage(msg, standardMsg))
801
802 def assertIs(self, expr1, expr2, msg=None):
803 """Just like self.assertTrue(a is b), but with a nicer default message."""
804 if expr1 is not expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000805 standardMsg = '%s is not %s' % (safe_repr(expr1),
Michael Foordc2294dd2010-02-18 21:37:07 +0000806 safe_repr(expr2))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000807 self.fail(self._formatMessage(msg, standardMsg))
808
809 def assertIsNot(self, expr1, expr2, msg=None):
810 """Just like self.assertTrue(a is not b), but with a nicer default message."""
811 if expr1 is expr2:
Michael Foord225a0992010-02-18 20:30:09 +0000812 standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000813 self.fail(self._formatMessage(msg, standardMsg))
814
815 def assertDictEqual(self, d1, d2, msg=None):
Ezio Melotti2623a372010-11-21 13:34:58 +0000816 self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
817 self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000818
819 if d1 != d2:
Michael Foord674648e2010-06-05 12:58:39 +0000820 standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
Michael Foorde37d75f2010-06-05 12:10:52 +0000821 diff = ('\n' + '\n'.join(difflib.ndiff(
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000822 pprint.pformat(d1).splitlines(),
823 pprint.pformat(d2).splitlines())))
Michael Foord674648e2010-06-05 12:58:39 +0000824 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000825 self.fail(self._formatMessage(msg, standardMsg))
826
827 def assertDictContainsSubset(self, expected, actual, msg=None):
828 """Checks whether actual is a superset of expected."""
829 missing = []
830 mismatched = []
831 for key, value in expected.iteritems():
832 if key not in actual:
833 missing.append(key)
834 elif value != actual[key]:
Georg Brandl46cc46a2009-10-01 20:11:14 +0000835 mismatched.append('%s, expected: %s, actual: %s' %
Michael Foordc2294dd2010-02-18 21:37:07 +0000836 (safe_repr(key), safe_repr(value),
837 safe_repr(actual[key])))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000838
839 if not (missing or mismatched):
840 return
841
842 standardMsg = ''
843 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000844 standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
845 missing)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000846 if mismatched:
847 if standardMsg:
848 standardMsg += '; '
849 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
850
851 self.fail(self._formatMessage(msg, standardMsg))
852
Michael Foord98e7b762010-03-20 03:00:34 +0000853 def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
Michael Foorde6e0e262010-12-19 15:52:56 +0000854 """An unordered sequence specific comparison. It asserts that
855 actual_seq and expected_seq have the same element counts.
856 Equivalent to::
Michael Foord98e7b762010-03-20 03:00:34 +0000857
Michael Foorde6e0e262010-12-19 15:52:56 +0000858 self.assertEqual(Counter(iter(actual_seq)),
859 Counter(iter(expected_seq)))
Michael Foordd0edec32010-02-05 22:55:09 +0000860
Michael Foord98e7b762010-03-20 03:00:34 +0000861 Asserts that each element has the same count in both sequences.
862 Example:
863 - [0, 1, 1] and [1, 0, 1] compare equal.
864 - [0, 0, 1] and [0, 1] compare unequal.
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000865 """
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000866 with warnings.catch_warnings():
867 if sys.py3kwarning:
868 # Silence Py3k warning raised during the sorting
Florent Xicluna4a0f8b82010-03-21 10:50:44 +0000869 for _msg in ["(code|dict|type) inequality comparisons",
Michael Foord98e7b762010-03-20 03:00:34 +0000870 "builtin_function_or_method order comparisons",
871 "comparing unequal types"]:
Michael Foorda7152552010-03-07 23:10:36 +0000872 warnings.filterwarnings("ignore", _msg, DeprecationWarning)
Florent Xicluna1f3b4e12010-03-07 12:14:25 +0000873 try:
Michael Foorde6e0e262010-12-19 15:52:56 +0000874 actual = collections.Counter(iter(actual_seq))
875 expected = collections.Counter(iter(expected_seq))
Michael Foord98e7b762010-03-20 03:00:34 +0000876 except TypeError:
877 # Unsortable items (example: set(), complex(), ...)
Michael Foord98e7b762010-03-20 03:00:34 +0000878 actual = list(actual_seq)
Michael Foorde6e0e262010-12-19 15:52:56 +0000879 expected = list(expected_seq)
880 missing, unexpected = unorderable_list_difference(expected, actual)
Michael Foord98e7b762010-03-20 03:00:34 +0000881 else:
Michael Foorde6e0e262010-12-19 15:52:56 +0000882 if actual == expected:
883 return
884 missing = list(expected - actual)
885 unexpected = list(actual - expected)
Michael Foord98e7b762010-03-20 03:00:34 +0000886
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000887 errors = []
888 if missing:
Michael Foord225a0992010-02-18 20:30:09 +0000889 errors.append('Expected, but missing:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000890 safe_repr(missing))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000891 if unexpected:
Michael Foord225a0992010-02-18 20:30:09 +0000892 errors.append('Unexpected, but present:\n %s' %
Michael Foord98e7b762010-03-20 03:00:34 +0000893 safe_repr(unexpected))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000894 if errors:
895 standardMsg = '\n'.join(errors)
896 self.fail(self._formatMessage(msg, standardMsg))
897
898 def assertMultiLineEqual(self, first, second, msg=None):
899 """Assert that two multi-line strings are equal."""
Ezio Melotti2623a372010-11-21 13:34:58 +0000900 self.assertIsInstance(first, basestring,
901 'First argument is not a string')
902 self.assertIsInstance(second, basestring,
903 'Second argument is not a string')
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000904
905 if first != second:
Michael Foord94f071c2010-07-10 13:51:42 +0000906 firstlines = first.splitlines(True)
907 secondlines = second.splitlines(True)
908 if len(firstlines) == 1 and first.strip('\r\n') == first:
909 firstlines = [first + '\n']
910 secondlines = [second + '\n']
911 standardMsg = '%s != %s' % (safe_repr(first, True),
912 safe_repr(second, True))
913 diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
Michael Foord674648e2010-06-05 12:58:39 +0000914 standardMsg = self._truncateMessage(standardMsg, diff)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000915 self.fail(self._formatMessage(msg, standardMsg))
916
917 def assertLess(self, a, b, msg=None):
918 """Just like self.assertTrue(a < b), but with a nicer default message."""
919 if not a < b:
Michael Foord225a0992010-02-18 20:30:09 +0000920 standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000921 self.fail(self._formatMessage(msg, standardMsg))
922
923 def assertLessEqual(self, a, b, msg=None):
924 """Just like self.assertTrue(a <= b), but with a nicer default message."""
925 if not a <= b:
Michael Foord225a0992010-02-18 20:30:09 +0000926 standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000927 self.fail(self._formatMessage(msg, standardMsg))
928
929 def assertGreater(self, a, b, msg=None):
930 """Just like self.assertTrue(a > b), but with a nicer default message."""
931 if not a > b:
Michael Foord225a0992010-02-18 20:30:09 +0000932 standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000933 self.fail(self._formatMessage(msg, standardMsg))
934
935 def assertGreaterEqual(self, a, b, msg=None):
936 """Just like self.assertTrue(a >= b), but with a nicer default message."""
937 if not a >= b:
Michael Foord225a0992010-02-18 20:30:09 +0000938 standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000939 self.fail(self._formatMessage(msg, standardMsg))
940
941 def assertIsNone(self, obj, msg=None):
942 """Same as self.assertTrue(obj is None), with a nicer default message."""
943 if obj is not None:
Michael Foord225a0992010-02-18 20:30:09 +0000944 standardMsg = '%s is not None' % (safe_repr(obj),)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000945 self.fail(self._formatMessage(msg, standardMsg))
946
947 def assertIsNotNone(self, obj, msg=None):
948 """Included for symmetry with assertIsNone."""
949 if obj is None:
950 standardMsg = 'unexpectedly None'
951 self.fail(self._formatMessage(msg, standardMsg))
952
Georg Brandlf895cf52009-10-01 20:59:31 +0000953 def assertIsInstance(self, obj, cls, msg=None):
954 """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
955 default message."""
956 if not isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000957 standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000958 self.fail(self._formatMessage(msg, standardMsg))
959
960 def assertNotIsInstance(self, obj, cls, msg=None):
961 """Included for symmetry with assertIsInstance."""
962 if isinstance(obj, cls):
Michael Foord225a0992010-02-18 20:30:09 +0000963 standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
Georg Brandlf895cf52009-10-01 20:59:31 +0000964 self.fail(self._formatMessage(msg, standardMsg))
965
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000966 def assertRaisesRegexp(self, expected_exception, expected_regexp,
967 callable_obj=None, *args, **kwargs):
968 """Asserts that the message in a raised exception matches a regexp.
969
970 Args:
971 expected_exception: Exception class expected to be raised.
972 expected_regexp: Regexp (re pattern object or string) expected
973 to be found in error message.
974 callable_obj: Function to be called.
975 args: Extra args.
976 kwargs: Extra kwargs.
977 """
978 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
979 if callable_obj is None:
980 return context
981 with context:
982 callable_obj(*args, **kwargs)
983
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000984 def assertRegexpMatches(self, text, expected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000985 """Fail the test unless the text matches the regular expression."""
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000986 if isinstance(expected_regexp, basestring):
987 expected_regexp = re.compile(expected_regexp)
988 if not expected_regexp.search(text):
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000989 msg = msg or "Regexp didn't match"
Georg Brandlb0eb4d32010-02-07 11:34:15 +0000990 msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +0000991 raise self.failureException(msg)
992
Michael Foorda04c7a02010-04-02 22:55:59 +0000993 def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
Michael Foord959c16d2010-05-08 16:40:52 +0000994 """Fail the test if the text matches the regular expression."""
Michael Foorda04c7a02010-04-02 22:55:59 +0000995 if isinstance(unexpected_regexp, basestring):
996 unexpected_regexp = re.compile(unexpected_regexp)
997 match = unexpected_regexp.search(text)
998 if match:
999 msg = msg or "Regexp matched"
1000 msg = '%s: %r matches %r in %r' % (msg,
1001 text[match.start():match.end()],
1002 unexpected_regexp.pattern,
1003 text)
1004 raise self.failureException(msg)
1005
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001006
1007class FunctionTestCase(TestCase):
1008 """A test case that wraps a test function.
1009
1010 This is useful for slipping pre-existing test functions into the
1011 unittest framework. Optionally, set-up and tidy-up functions can be
1012 supplied. As with TestCase, the tidy-up ('tearDown') function will
1013 always be called if the set-up ('setUp') function ran successfully.
1014 """
1015
1016 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1017 super(FunctionTestCase, self).__init__()
1018 self._setUpFunc = setUp
1019 self._tearDownFunc = tearDown
1020 self._testFunc = testFunc
1021 self._description = description
1022
1023 def setUp(self):
1024 if self._setUpFunc is not None:
1025 self._setUpFunc()
1026
1027 def tearDown(self):
1028 if self._tearDownFunc is not None:
1029 self._tearDownFunc()
1030
1031 def runTest(self):
1032 self._testFunc()
1033
1034 def id(self):
1035 return self._testFunc.__name__
1036
1037 def __eq__(self, other):
1038 if not isinstance(other, self.__class__):
1039 return NotImplemented
1040
1041 return self._setUpFunc == other._setUpFunc and \
1042 self._tearDownFunc == other._tearDownFunc and \
1043 self._testFunc == other._testFunc and \
1044 self._description == other._description
1045
1046 def __ne__(self, other):
1047 return not self == other
1048
1049 def __hash__(self):
1050 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1051 self._testFunc, self._description))
1052
1053 def __str__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001054 return "%s (%s)" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001055 self._testFunc.__name__)
1056
1057 def __repr__(self):
Michael Foord225a0992010-02-18 20:30:09 +00001058 return "<%s tec=%s>" % (strclass(self.__class__),
Benjamin Petersond7b0eeb2009-07-19 20:18:21 +00001059 self._testFunc)
1060
1061 def shortDescription(self):
1062 if self._description is not None:
1063 return self._description
1064 doc = self._testFunc.__doc__
1065 return doc and doc.split("\n")[0].strip() or None