blob: 244a45beec90b46d5a0b8cb34cbeb6be86a9eaec [file] [log] [blame]
Fred Drake02538202001-03-21 18:09:46 +00001#!/usr/bin/env python
Steve Purcell5ddd1a82001-03-22 08:45:36 +00002'''
Fred Drake02538202001-03-21 18:09:46 +00003Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
4Smalltalk testing framework.
5
Fred Drake02538202001-03-21 18:09:46 +00006This module contains the core framework classes that form the basis of
7specific test cases and suites (TestCase, TestSuite etc.), and also a
8text-based utility class for running the tests and reporting the results
Jeremy Hyltonefef5da2001-10-22 18:14:15 +00009 (TextTestRunner).
Fred Drake02538202001-03-21 18:09:46 +000010
Steve Purcell5ddd1a82001-03-22 08:45:36 +000011Simple usage:
12
13 import unittest
14
15 class IntegerArithmenticTestCase(unittest.TestCase):
16 def testAdd(self): ## test method names begin 'test*'
Benjamin Peterson7fe73a12009-04-04 16:35:46 +000017 self.assertEqual((1 + 2), 3)
18 self.assertEqual(0 + 1, 1)
Steve Purcell7b065702001-09-06 08:24:40 +000019 def testMultiply(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +000020 self.assertEqual((0 * 10), 0)
21 self.assertEqual((5 * 8), 40)
Steve Purcell5ddd1a82001-03-22 08:45:36 +000022
23 if __name__ == '__main__':
24 unittest.main()
25
26Further information is available in the bundled documentation, and from
27
Benjamin Peterson52baa292009-03-24 00:56:30 +000028 http://docs.python.org/library/unittest.html
Steve Purcell5ddd1a82001-03-22 08:45:36 +000029
Steve Purcell7e743842003-09-22 11:08:12 +000030Copyright (c) 1999-2003 Steve Purcell
Benjamin Peterson52baa292009-03-24 00:56:30 +000031Copyright (c) 2003-2009 Python Software Foundation
Fred Drake02538202001-03-21 18:09:46 +000032This module is free software, and you may redistribute it and/or modify
33it under the same terms as Python itself, so long as this copyright message
34and disclaimer are retained in their original form.
35
36IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
37SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
38THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
39DAMAGE.
40
41THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
42LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
44AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
45SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Steve Purcell5ddd1a82001-03-22 08:45:36 +000046'''
Fred Drake02538202001-03-21 18:09:46 +000047
Benjamin Peterson7fe73a12009-04-04 16:35:46 +000048import difflib
Benjamin Peterson5254c042009-03-23 22:25:03 +000049import functools
Benjamin Peterson7fe73a12009-04-04 16:35:46 +000050import os
51import pprint
52import re
53import sys
54import time
55import traceback
56import types
57import warnings
Fred Drake02538202001-03-21 18:09:46 +000058
59##############################################################################
Steve Purcelld75e7e42003-09-15 11:01:21 +000060# Exported classes and functions
61##############################################################################
Benjamin Peterson52baa292009-03-24 00:56:30 +000062__all__ = ['TestResult', 'TestCase', 'TestSuite', 'ClassTestSuite',
63 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
Benjamin Peterson4c93dcb2009-03-24 01:33:55 +000064 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
Benjamin Peterson52baa292009-03-24 00:56:30 +000065 'expectedFailure']
Steve Purcelld75e7e42003-09-15 11:01:21 +000066
Steve Purcell7e743842003-09-22 11:08:12 +000067# Expose obsolete functions for backwards compatibility
Steve Purcelld75e7e42003-09-15 11:01:21 +000068__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
69
70
71##############################################################################
Fred Drake02538202001-03-21 18:09:46 +000072# Test framework core
73##############################################################################
74
Steve Purcelldc391a62002-08-09 09:46:23 +000075def _strclass(cls):
76 return "%s.%s" % (cls.__module__, cls.__name__)
77
Benjamin Peterson5254c042009-03-23 22:25:03 +000078
79class SkipTest(Exception):
80 """
81 Raise this exception in a test to skip it.
82
83 Usually you can use TestResult.skip() or one of the skipping decorators
84 instead of raising this directly.
85 """
86 pass
87
88class _ExpectedFailure(Exception):
89 """
90 Raise this when a test is expected to fail.
91
92 This is an implementation detail.
93 """
94
95 def __init__(self, exc_info):
96 super(_ExpectedFailure, self).__init__()
97 self.exc_info = exc_info
98
99class _UnexpectedSuccess(Exception):
100 """
101 The test was supposed to fail, but it didn't!
102 """
103 pass
104
105def _id(obj):
106 return obj
107
108def skip(reason):
109 """
110 Unconditionally skip a test.
111 """
112 def decorator(test_item):
113 if isinstance(test_item, type) and issubclass(test_item, TestCase):
114 test_item.__unittest_skip__ = True
115 test_item.__unittest_skip_why__ = reason
116 return test_item
117 @functools.wraps(test_item)
118 def skip_wrapper(*args, **kwargs):
119 raise SkipTest(reason)
120 return skip_wrapper
121 return decorator
122
123def skipIf(condition, reason):
124 """
125 Skip a test if the condition is true.
126 """
127 if condition:
128 return skip(reason)
129 return _id
130
131def skipUnless(condition, reason):
132 """
133 Skip a test unless the condition is true.
134 """
135 if not condition:
136 return skip(reason)
137 return _id
138
139
140def expectedFailure(func):
141 @functools.wraps(func)
142 def wrapper(*args, **kwargs):
143 try:
144 func(*args, **kwargs)
145 except Exception:
146 raise _ExpectedFailure(sys.exc_info())
147 raise _UnexpectedSuccess
148 return wrapper
149
Steve Purcellb8d5f242003-12-06 13:03:13 +0000150__unittest = 1
151
Benjamin Peterson1467ac82009-01-09 03:42:38 +0000152class TestResult(object):
Fred Drake02538202001-03-21 18:09:46 +0000153 """Holder for test result information.
154
155 Test results are automatically managed by the TestCase and TestSuite
156 classes, and do not need to be explicitly manipulated by writers of tests.
157
158 Each instance holds the total number of tests run, and collections of
159 failures and errors that occurred among those test runs. The collections
Steve Purcell7b065702001-09-06 08:24:40 +0000160 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
Fred Drake656f9ec2001-09-06 19:13:14 +0000161 formatted traceback of the error that occurred.
Fred Drake02538202001-03-21 18:09:46 +0000162 """
163 def __init__(self):
164 self.failures = []
165 self.errors = []
166 self.testsRun = 0
Benjamin Peterson5254c042009-03-23 22:25:03 +0000167 self.skipped = []
Benjamin Peterson52baa292009-03-24 00:56:30 +0000168 self.expectedFailures = []
169 self.unexpectedSuccesses = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000170 self.shouldStop = False
Fred Drake02538202001-03-21 18:09:46 +0000171
172 def startTest(self, test):
173 "Called when the given test is about to be run"
174 self.testsRun = self.testsRun + 1
175
176 def stopTest(self, test):
177 "Called when the given test has been run"
178 pass
179
180 def addError(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000181 """Called when an error has occurred. 'err' is a tuple of values as
182 returned by sys.exc_info().
183 """
Steve Purcellb8d5f242003-12-06 13:03:13 +0000184 self.errors.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000185
186 def addFailure(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000187 """Called when an error has occurred. 'err' is a tuple of values as
188 returned by sys.exc_info()."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000189 self.failures.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000190
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000191 def addSuccess(self, test):
192 "Called when a test has completed successfully"
193 pass
194
Benjamin Peterson5254c042009-03-23 22:25:03 +0000195 def addSkip(self, test, reason):
196 """Called when a test is skipped."""
197 self.skipped.append((test, reason))
198
199 def addExpectedFailure(self, test, err):
200 """Called when an expected failure/error occured."""
Benjamin Peterson52baa292009-03-24 00:56:30 +0000201 self.expectedFailures.append(
Benjamin Peterson5254c042009-03-23 22:25:03 +0000202 (test, self._exc_info_to_string(err, test)))
203
204 def addUnexpectedSuccess(self, test):
205 """Called when a test was expected to fail, but succeed."""
Benjamin Peterson52baa292009-03-24 00:56:30 +0000206 self.unexpectedSuccesses.append(test)
Benjamin Peterson5254c042009-03-23 22:25:03 +0000207
Fred Drake02538202001-03-21 18:09:46 +0000208 def wasSuccessful(self):
209 "Tells whether or not this result was a success"
210 return len(self.failures) == len(self.errors) == 0
211
212 def stop(self):
213 "Indicates that the tests should be aborted"
Steve Purcell7e743842003-09-22 11:08:12 +0000214 self.shouldStop = True
Tim Petersa19a1682001-03-29 04:36:09 +0000215
Steve Purcellb8d5f242003-12-06 13:03:13 +0000216 def _exc_info_to_string(self, err, test):
Steve Purcell7b065702001-09-06 08:24:40 +0000217 """Converts a sys.exc_info()-style tuple of values into a string."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000218 exctype, value, tb = err
219 # Skip test runner traceback levels
220 while tb and self._is_relevant_tb_level(tb):
221 tb = tb.tb_next
222 if exctype is test.failureException:
223 # Skip assert*() traceback levels
224 length = self._count_relevant_tb_levels(tb)
Collin Winterce36ad82007-08-30 01:19:48 +0000225 return ''.join(traceback.format_exception(exctype, value,
226 tb, length))
Steve Purcellb8d5f242003-12-06 13:03:13 +0000227 return ''.join(traceback.format_exception(exctype, value, tb))
228
229 def _is_relevant_tb_level(self, tb):
Guido van Rossume2b70bc2006-08-18 22:13:04 +0000230 return '__unittest' in tb.tb_frame.f_globals
Steve Purcellb8d5f242003-12-06 13:03:13 +0000231
232 def _count_relevant_tb_levels(self, tb):
233 length = 0
234 while tb and not self._is_relevant_tb_level(tb):
235 length += 1
236 tb = tb.tb_next
237 return length
Steve Purcell7b065702001-09-06 08:24:40 +0000238
Fred Drake02538202001-03-21 18:09:46 +0000239 def __repr__(self):
240 return "<%s run=%i errors=%i failures=%i>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +0000241 (_strclass(self.__class__), self.testsRun, len(self.errors),
Fred Drake02538202001-03-21 18:09:46 +0000242 len(self.failures))
243
Benjamin Peterson52baa292009-03-24 00:56:30 +0000244
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000245class _AssertRaisesContext(object):
246 """A context manager used to implement TestCase.assertRaises* methods."""
Benjamin Peterson52baa292009-03-24 00:56:30 +0000247
248
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000249 def __init__(self, expected, test_case, callable_obj=None,
250 expected_regexp=None):
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000251 self.expected = expected
252 self.failureException = test_case.failureException
253 if callable_obj is not None:
254 try:
255 self.obj_name = callable_obj.__name__
256 except AttributeError:
257 self.obj_name = str(callable_obj)
258 else:
259 self.obj_name = None
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000260 self.expected_regex = expected_regexp
Benjamin Peterson52baa292009-03-24 00:56:30 +0000261
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000262 def __enter__(self):
263 pass
Benjamin Peterson52baa292009-03-24 00:56:30 +0000264
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000265 def __exit__(self, exc_type, exc_value, traceback):
266 if exc_type is None:
267 try:
268 exc_name = self.expected.__name__
269 except AttributeError:
270 exc_name = str(self.expected)
271 if self.obj_name:
272 raise self.failureException("{0} not raised by {1}"
273 .format(exc_name, self.obj_name))
274 else:
275 raise self.failureException("{0} not raised"
276 .format(exc_name))
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000277 if not issubclass(exc_type, self.expected):
278 # let unexpected exceptions pass through
279 return False
280 if self.expected_regex is None:
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000281 return True
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000282
283 expected_regexp = self.expected_regex
284 if isinstance(expected_regexp, (bytes, str)):
285 expected_regexp = re.compile(expected_regexp)
286 if not expected_regexp.search(str(exc_value)):
287 raise self.failureException('"%s" does not match "%s"' %
288 (expected_regexp.pattern, str(exc_value)))
289 return True
290
291
292class _AssertWrapper(object):
293 """Wrap entries in the _type_equality_funcs registry to make them deep
294 copyable."""
295
296 def __init__(self, function):
297 self.function = function
298
299 def __deepcopy__(self, memo):
300 memo[id(self)] = self
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000301
Benjamin Peterson52baa292009-03-24 00:56:30 +0000302
Benjamin Peterson1467ac82009-01-09 03:42:38 +0000303class TestCase(object):
Fred Drake02538202001-03-21 18:09:46 +0000304 """A class whose instances are single test cases.
305
Fred Drake02538202001-03-21 18:09:46 +0000306 By default, the test code itself should be placed in a method named
307 'runTest'.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000308
Tim Petersa19a1682001-03-29 04:36:09 +0000309 If the fixture may be used for many test cases, create as
Fred Drake02538202001-03-21 18:09:46 +0000310 many test methods as are needed. When instantiating such a TestCase
311 subclass, specify in the constructor arguments the name of the test method
312 that the instance is to execute.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000313
Tim Petersa19a1682001-03-29 04:36:09 +0000314 Test authors should subclass TestCase for their own tests. Construction
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000315 and deconstruction of the test's environment ('fixture') can be
316 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
317
318 If it is necessary to override the __init__ method, the base class
319 __init__ method must always be called. It is important that subclasses
320 should not change the signature of their __init__ method, since instances
321 of the classes are instantiated automatically by parts of the framework
322 in order to be run.
Fred Drake02538202001-03-21 18:09:46 +0000323 """
Steve Purcell15d89272001-04-12 09:05:01 +0000324
325 # This attribute determines which exception will be raised when
326 # the instance's assertion methods fail; test methods raising this
327 # exception will be deemed to have 'failed' rather than 'errored'
328
329 failureException = AssertionError
330
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000331 # This attribute determines whether long messages (including repr of
332 # objects used in assert methods) will be printed on failure in *addition*
333 # to any explicit message passed.
334
335 longMessage = False
336
337
Fred Drake02538202001-03-21 18:09:46 +0000338 def __init__(self, methodName='runTest'):
339 """Create an instance of the class that will use the named test
340 method when executed. Raises a ValueError if the instance does
341 not have a method with the specified name.
342 """
Benjamin Peterson52baa292009-03-24 00:56:30 +0000343 self._testMethodName = methodName
Fred Drake02538202001-03-21 18:09:46 +0000344 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000345 testMethod = getattr(self, methodName)
Fred Drake02538202001-03-21 18:09:46 +0000346 except AttributeError:
Benjamin Peterson1467ac82009-01-09 03:42:38 +0000347 raise ValueError("no such test method in %s: %s" % \
348 (self.__class__, methodName))
Benjamin Peterson52baa292009-03-24 00:56:30 +0000349 self._testMethodDoc = testMethod.__doc__
Fred Drake02538202001-03-21 18:09:46 +0000350
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000351 # Map types to custom assertEqual functions that will compare
352 # instances of said type in more detail to generate a more useful
353 # error message.
354 self._type_equality_funcs = {}
355 self.addTypeEqualityFunc(dict, self.assertDictEqual)
356 self.addTypeEqualityFunc(list, self.assertListEqual)
357 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
358 self.addTypeEqualityFunc(set, self.assertSetEqual)
359 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
360
361 def addTypeEqualityFunc(self, typeobj, function):
362 """Add a type specific assertEqual style function to compare a type.
363
364 This method is for use by TestCase subclasses that need to register
365 their own type equality functions to provide nicer error messages.
366
367 Args:
368 typeobj: The data type to call this function on when both values
369 are of the same type in assertEqual().
370 function: The callable taking two arguments and an optional
371 msg= argument that raises self.failureException with a
372 useful error message when the two arguments are not equal.
373 """
374 self._type_equality_funcs[typeobj] = _AssertWrapper(function)
375
Fred Drake02538202001-03-21 18:09:46 +0000376 def setUp(self):
377 "Hook method for setting up the test fixture before exercising it."
378 pass
379
380 def tearDown(self):
381 "Hook method for deconstructing the test fixture after testing it."
382 pass
383
384 def countTestCases(self):
385 return 1
386
387 def defaultTestResult(self):
388 return TestResult()
389
390 def shortDescription(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000391 """Returns both the test method name and first line of its docstring.
Fred Drake02538202001-03-21 18:09:46 +0000392
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000393 If no docstring is given, only returns the method name.
394
395 This method overrides unittest.TestCase.shortDescription(), which
396 only returns the first line of the docstring, obscuring the name
397 of the test upon failure.
Fred Drake02538202001-03-21 18:09:46 +0000398 """
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000399 desc = str(self)
400 doc_first_line = None
401
402 if self._testMethodDoc:
403 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
404 if doc_first_line:
405 desc = '\n'.join((desc, doc_first_line))
406 return desc
Fred Drake02538202001-03-21 18:09:46 +0000407
408 def id(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000409 return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000410
Guido van Rossumd8faa362007-04-27 19:54:29 +0000411 def __eq__(self, other):
412 if type(self) is not type(other):
Benjamin Peterson52baa292009-03-24 00:56:30 +0000413 return NotImplemented
Guido van Rossumd8faa362007-04-27 19:54:29 +0000414
415 return self._testMethodName == other._testMethodName
416
417 def __ne__(self, other):
418 return not self == other
419
420 def __hash__(self):
421 return hash((type(self), self._testMethodName))
422
Fred Drake02538202001-03-21 18:09:46 +0000423 def __str__(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000424 return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
Fred Drake02538202001-03-21 18:09:46 +0000425
426 def __repr__(self):
427 return "<%s testMethod=%s>" % \
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000428 (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000429
430 def run(self, result=None):
Benjamin Peterson52baa292009-03-24 00:56:30 +0000431 if result is None:
432 result = self.defaultTestResult()
Fred Drake02538202001-03-21 18:09:46 +0000433 result.startTest(self)
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000434 testMethod = getattr(self, self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000435 try:
436 try:
437 self.setUp()
Benjamin Peterson5254c042009-03-23 22:25:03 +0000438 except SkipTest as e:
439 result.addSkip(self, str(e))
440 return
Benjamin Peterson1467ac82009-01-09 03:42:38 +0000441 except Exception:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000442 result.addError(self, sys.exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000443 return
444
Benjamin Peterson5254c042009-03-23 22:25:03 +0000445 success = False
Fred Drake02538202001-03-21 18:09:46 +0000446 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000447 testMethod()
Skip Montanaroae5c37b2003-07-13 15:18:12 +0000448 except self.failureException:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000449 result.addFailure(self, sys.exc_info())
Benjamin Peterson5254c042009-03-23 22:25:03 +0000450 except _ExpectedFailure as e:
451 result.addExpectedFailure(self, e.exc_info)
452 except _UnexpectedSuccess:
453 result.addUnexpectedSuccess(self)
454 except SkipTest as e:
455 result.addSkip(self, str(e))
Benjamin Peterson1467ac82009-01-09 03:42:38 +0000456 except Exception:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000457 result.addError(self, sys.exc_info())
Benjamin Peterson5254c042009-03-23 22:25:03 +0000458 else:
459 success = True
Fred Drake02538202001-03-21 18:09:46 +0000460
461 try:
462 self.tearDown()
Benjamin Peterson1467ac82009-01-09 03:42:38 +0000463 except Exception:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000464 result.addError(self, sys.exc_info())
Benjamin Peterson5254c042009-03-23 22:25:03 +0000465 success = False
466 if success:
467 result.addSuccess(self)
Fred Drake02538202001-03-21 18:09:46 +0000468 finally:
469 result.stopTest(self)
470
Raymond Hettinger664347b2004-12-04 21:21:53 +0000471 def __call__(self, *args, **kwds):
472 return self.run(*args, **kwds)
Steve Purcell7e743842003-09-22 11:08:12 +0000473
Fred Drake02538202001-03-21 18:09:46 +0000474 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000475 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000476 self.setUp()
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000477 getattr(self, self._testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000478 self.tearDown()
479
Benjamin Petersone549ead2009-03-28 21:42:05 +0000480 def skipTest(self, reason):
Benjamin Peterson5254c042009-03-23 22:25:03 +0000481 """Skip this test."""
482 raise SkipTest(reason)
483
Steve Purcell15d89272001-04-12 09:05:01 +0000484 def fail(self, msg=None):
485 """Fail immediately, with the given message."""
Collin Winterce36ad82007-08-30 01:19:48 +0000486 raise self.failureException(msg)
Fred Drake02538202001-03-21 18:09:46 +0000487
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000488 def assertFalse(self, expr, msg=None):
Fred Drake02538202001-03-21 18:09:46 +0000489 "Fail the test if the expression is true."
Benjamin Peterson52baa292009-03-24 00:56:30 +0000490 if expr:
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000491 msg = self._formatMessage(msg, "%r is not False" % expr)
Benjamin Peterson52baa292009-03-24 00:56:30 +0000492 raise self.failureException(msg)
Fred Drake02538202001-03-21 18:09:46 +0000493
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000494 def assertTrue(self, expr, msg=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000495 """Fail the test unless the expression is true."""
Benjamin Peterson52baa292009-03-24 00:56:30 +0000496 if not expr:
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000497 msg = self._formatMessage(msg, "%r is not True" % expr)
Benjamin Peterson52baa292009-03-24 00:56:30 +0000498 raise self.failureException(msg)
Steve Purcell15d89272001-04-12 09:05:01 +0000499
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000500 def _formatMessage(self, msg, standardMsg):
501 """Honour the longMessage attribute when generating failure messages.
502 If longMessage is False this means:
503 * Use only an explicit message if it is provided
504 * Otherwise use the standard message for the assert
505
506 If longMessage is True:
507 * Use the standard message
508 * If an explicit message is provided, plus ' : ' and the explicit message
509 """
510 if not self.longMessage:
511 return msg or standardMsg
512 if msg is None:
513 return standardMsg
514 return standardMsg + ' : ' + msg
515
516
517 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
Steve Purcell15d89272001-04-12 09:05:01 +0000518 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000519 by callableObj when invoked with arguments args and keyword
520 arguments kwargs. If a different type of exception is
521 thrown, it will not be caught, and the test case will be
522 deemed to have suffered an error, exactly as for an
523 unexpected exception.
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000524
525 If called with callableObj omitted or None, will return a
526 context object used like this::
527
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000528 with self.assertRaises(some_error_class):
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000529 do_something()
Fred Drake02538202001-03-21 18:09:46 +0000530 """
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000531 context = _AssertRaisesContext(excClass, self, callableObj)
Antoine Pitrou5acd41e2008-12-28 14:29:00 +0000532 if callableObj is None:
533 return context
534 with context:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000535 callableObj(*args, **kwargs)
Fred Drake02538202001-03-21 18:09:46 +0000536
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000537 def _getAssertEqualityFunc(self, first, second):
538 """Get a detailed comparison function for the types of the two args.
539
540 Returns: A callable accepting (first, second, msg=None) that will
541 raise a failure exception if first != second with a useful human
542 readable error message for those types.
543 """
544 #
545 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
546 # and vice versa. I opted for the conservative approach in case
547 # subclasses are not intended to be compared in detail to their super
548 # class instances using a type equality func. This means testing
549 # subtypes won't automagically use the detailed comparison. Callers
550 # should use their type specific assertSpamEqual method to compare
551 # subclasses if the detailed comparison is desired and appropriate.
552 # See the discussion in http://bugs.python.org/issue2578.
553 #
554 if type(first) is type(second):
555 asserter = self._type_equality_funcs.get(type(first))
556 if asserter is not None:
557 return asserter.function
558
559 return self._baseAssertEqual
560
561 def _baseAssertEqual(self, first, second, msg=None):
562 """The default assertEqual implementation, not type specific."""
563 if not first == second:
564 standardMsg = '%r != %r' % (first, second)
565 msg = self._formatMessage(msg, standardMsg)
566 raise self.failureException(msg)
567
568 def assertEqual(self, first, second, msg=None):
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000569 """Fail if the two objects are unequal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000570 operator.
571 """
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000572 assertion_func = self._getAssertEqualityFunc(first, second)
573 assertion_func(first, second, msg=msg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000574
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000575 def assertNotEqual(self, first, second, msg=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000576 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000577 operator.
578 """
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000579 if not first != second:
580 msg = self._formatMessage(msg, '%r == %r' % (first, second))
581 raise self.failureException(msg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000582
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000583 def assertAlmostEqual(self, first, second, *, places=7, msg=None):
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000584 """Fail if the two objects are unequal as determined by their
585 difference rounded to the given number of decimal places
586 (default 7) and comparing to zero.
587
Steve Purcell397b45d2003-10-26 10:41:03 +0000588 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000589 as significant digits (measured from the most signficant digit).
590 """
Jeffrey Yasskin1cc55442007-09-06 18:55:17 +0000591 if round(abs(second-first), places) != 0:
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000592 standardMsg = '%r != %r within %r places' % (first, second, places)
593 msg = self._formatMessage(msg, standardMsg)
594 raise self.failureException(msg)
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000595
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000596 def assertNotAlmostEqual(self, first, second, *, places=7, msg=None):
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000597 """Fail if the two objects are equal as determined by their
598 difference rounded to the given number of decimal places
599 (default 7) and comparing to zero.
600
Steve Purcellcca34912003-10-26 16:38:16 +0000601 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000602 as significant digits (measured from the most signficant digit).
603 """
Jeffrey Yasskin1cc55442007-09-06 18:55:17 +0000604 if round(abs(second-first), places) == 0:
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000605 standardMsg = '%r == %r within %r places' % (first, second, places)
606 msg = self._formatMessage(msg, standardMsg)
607 raise self.failureException(msg)
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000608
Steve Purcell7e743842003-09-22 11:08:12 +0000609 # Synonyms for assertion methods
610
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000611 # The plurals are undocumented. Keep them that way to discourage use.
612 # Do not add more. Do not remove.
613 # Going through a deprecation cycle on these would annoy many people.
614 assertEquals = assertEqual
615 assertNotEquals = assertNotEqual
616 assertAlmostEquals = assertAlmostEqual
617 assertNotAlmostEquals = assertNotAlmostEqual
618 assert_ = assertTrue
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000619
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000620 # These fail* assertion method names are pending deprecation and will
621 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
622 def _deprecate(original_func):
623 def deprecated_func(*args, **kwargs):
624 warnings.warn(
625 'Please use {0} instead.'.format(original_func.__name__),
626 PendingDeprecationWarning, 2)
627 return original_func(*args, **kwargs)
628 return deprecated_func
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000629
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000630 failUnlessEqual = _deprecate(assertEqual)
631 failIfEqual = _deprecate(assertNotEqual)
632 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
633 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
634 failUnless = _deprecate(assertTrue)
635 failUnlessRaises = _deprecate(assertRaises)
636 failIf = _deprecate(assertFalse)
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000637
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000638 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
639 """An equality assertion for ordered sequences (like lists and tuples).
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000640
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000641 For the purposes of this function, a valid orderd sequence type is one
642 which can be indexed, has a length, and has an equality operator.
Steve Purcell15d89272001-04-12 09:05:01 +0000643
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000644 Args:
645 seq1: The first sequence to compare.
646 seq2: The second sequence to compare.
647 seq_type: The expected datatype of the sequences, or None if no
648 datatype should be enforced.
649 msg: Optional message to use on failure instead of a list of
650 differences.
651 """
652 if seq_type != None:
653 seq_type_name = seq_type.__name__
654 if not isinstance(seq1, seq_type):
655 raise self.failureException('First sequence is not a %s: %r'
656 % (seq_type_name, seq1))
657 if not isinstance(seq2, seq_type):
658 raise self.failureException('Second sequence is not a %s: %r'
659 % (seq_type_name, seq2))
660 else:
661 seq_type_name = "sequence"
Steve Purcell7e743842003-09-22 11:08:12 +0000662
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000663 differing = None
664 try:
665 len1 = len(seq1)
666 except (TypeError, NotImplementedError):
667 differing = 'First %s has no length. Non-sequence?' % (
668 seq_type_name)
Steve Purcell15d89272001-04-12 09:05:01 +0000669
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000670 if differing is None:
671 try:
672 len2 = len(seq2)
673 except (TypeError, NotImplementedError):
674 differing = 'Second %s has no length. Non-sequence?' % (
675 seq_type_name)
676
677 if differing is None:
678 if seq1 == seq2:
679 return
680
681 for i in range(min(len1, len2)):
682 try:
683 item1 = seq1[i]
684 except (TypeError, IndexError, NotImplementedError):
685 differing = ('Unable to index element %d of first %s\n' %
686 (i, seq_type_name))
687 break
688
689 try:
690 item2 = seq2[i]
691 except (TypeError, IndexError, NotImplementedError):
692 differing = ('Unable to index element %d of second %s\n' %
693 (i, seq_type_name))
694 break
695
696 if item1 != item2:
697 differing = ('First differing element %d:\n%s\n%s\n' %
698 (i, item1, item2))
699 break
700 else:
701 if (len1 == len2 and seq_type is None and
702 type(seq1) != type(seq2)):
703 # The sequences are the same, but have differing types.
704 return
705 # A catch-all message for handling arbitrary user-defined
706 # sequences.
707 differing = '%ss differ:\n' % seq_type_name.capitalize()
708 if len1 > len2:
709 differing = ('First %s contains %d additional '
710 'elements.\n' % (seq_type_name, len1 - len2))
711 try:
712 differing += ('First extra element %d:\n%s\n' %
713 (len2, seq1[len2]))
714 except (TypeError, IndexError, NotImplementedError):
715 differing += ('Unable to index element %d '
716 'of first %s\n' % (len2, seq_type_name))
717 elif len1 < len2:
718 differing = ('Second %s contains %d additional '
719 'elements.\n' % (seq_type_name, len2 - len1))
720 try:
721 differing += ('First extra element %d:\n%s\n' %
722 (len1, seq2[len1]))
723 except (TypeError, IndexError, NotImplementedError):
724 differing += ('Unable to index element %d '
725 'of second %s\n' % (len1, seq_type_name))
726 standardMsg = differing + '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(),
727 pprint.pformat(seq2).splitlines()))
728 msg = self._formatMessage(msg, standardMsg)
729 self.fail(msg)
730
731 def assertListEqual(self, list1, list2, msg=None):
732 """A list-specific equality assertion.
733
734 Args:
735 list1: The first list to compare.
736 list2: The second list to compare.
737 msg: Optional message to use on failure instead of a list of
738 differences.
739
740 """
741 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
742
743 def assertTupleEqual(self, tuple1, tuple2, msg=None):
744 """A tuple-specific equality assertion.
745
746 Args:
747 tuple1: The first tuple to compare.
748 tuple2: The second tuple to compare.
749 msg: Optional message to use on failure instead of a list of
750 differences.
751 """
752 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
753
754 def assertSetEqual(self, set1, set2, msg=None):
755 """A set-specific equality assertion.
756
757 Args:
758 set1: The first set to compare.
759 set2: The second set to compare.
760 msg: Optional message to use on failure instead of a list of
761 differences.
762
763 For more general containership equality, assertSameElements will work
764 with things other than sets. This uses ducktyping to support
765 different types of sets, and is optimized for sets specifically
766 (parameters must support a difference method).
767 """
768 try:
769 difference1 = set1.difference(set2)
770 except TypeError as e:
771 self.fail('invalid type when attempting set difference: %s' % e)
772 except AttributeError as e:
773 self.fail('first argument does not support set difference: %s' % e)
774
775 try:
776 difference2 = set2.difference(set1)
777 except TypeError as e:
778 self.fail('invalid type when attempting set difference: %s' % e)
779 except AttributeError as e:
780 self.fail('second argument does not support set difference: %s' % e)
781
782 if not (difference1 or difference2):
783 return
784
785 lines = []
786 if difference1:
787 lines.append('Items in the first set but not the second:')
788 for item in difference1:
789 lines.append(repr(item))
790 if difference2:
791 lines.append('Items in the second set but not the first:')
792 for item in difference2:
793 lines.append(repr(item))
794
795 standardMsg = '\n'.join(lines)
796 self.fail(self._formatMessage(msg, standardMsg))
797
798 def assertIn(self, member, container, msg=None):
799 """Just like self.assertTrue(a in b), but with a nicer default message."""
800 if member not in container:
801 standardMsg = '%r not found in %r' % (member, container)
802 self.fail(self._formatMessage(msg, standardMsg))
803
804 def assertNotIn(self, member, container, msg=None):
805 """Just like self.assertTrue(a not in b), but with a nicer default message."""
806 if member in container:
807 standardMsg = '%r unexpectedly found in %r' % (member, container)
808 self.fail(self._formatMessage(msg, standardMsg))
809
810 def assertDictEqual(self, d1, d2, msg=None):
811 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
812 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
813
814 if d1 != d2:
815 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
816 pprint.pformat(d1).splitlines(),
817 pprint.pformat(d2).splitlines())))
818 self.fail(self._formatMessage(msg, standardMsg))
819
820 def assertDictContainsSubset(self, expected, actual, msg=None):
821 """Checks whether actual is a superset of expected."""
822 missing = []
823 mismatched = []
824 for key, value in expected.items():
825 if key not in actual:
826 missing.append(key)
827 elif value != actual[key]:
828 mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key]))
829
830 if not (missing or mismatched):
831 return
832
833 standardMsg = ''
834 if missing:
835 standardMsg = 'Missing: %r' % ','.join(missing)
836 if mismatched:
837 if standardMsg:
838 standardMsg += '; '
839 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
840
841 self.fail(self._formatMessage(msg, standardMsg))
842
843 def assertSameElements(self, expected_seq, actual_seq, msg=None):
844 """An unordered sequence specific comparison.
845
846 Raises with an error message listing which elements of expected_seq
847 are missing from actual_seq and vice versa if any.
848 """
849 try:
850 expected = set(expected_seq)
851 actual = set(actual_seq)
852 missing = list(expected.difference(actual))
853 unexpected = list(actual.difference(expected))
854 missing.sort()
855 unexpected.sort()
856 except TypeError:
857 # Fall back to slower list-compare if any of the objects are
858 # not hashable.
859 expected = list(expected_seq)
860 actual = list(actual_seq)
Michael Foorda5809c82009-04-04 18:55:09 +0000861 try:
862 expected.sort()
863 actual.sort()
864 except TypeError:
865 missing, unexpected = _UnorderableListDifference(expected, actual)
866 else:
867 missing, unexpected = _SortedListDifference(expected, actual)
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000868 errors = []
869 if missing:
870 errors.append('Expected, but missing:\n %r' % missing)
871 if unexpected:
872 errors.append('Unexpected, but present:\n %r' % unexpected)
873 if errors:
874 standardMsg = '\n'.join(errors)
875 self.fail(self._formatMessage(msg, standardMsg))
876
877 def assertMultiLineEqual(self, first, second, msg=None):
878 """Assert that two multi-line strings are equal."""
879 self.assert_(isinstance(first, str), (
880 'First argument is not a string'))
881 self.assert_(isinstance(second, str), (
882 'Second argument is not a string'))
883
884 if first != second:
885 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True)))
886 self.fail(self._formatMessage(msg, standardMsg))
887
888 def assertLess(self, a, b, msg=None):
889 """Just like self.assertTrue(a < b), but with a nicer default message."""
890 if not a < b:
891 standardMsg = '%r not less than %r' % (a, b)
892 self.fail(self._formatMessage(msg, standardMsg))
893
894 def assertLessEqual(self, a, b, msg=None):
895 """Just like self.assertTrue(a <= b), but with a nicer default message."""
896 if not a <= b:
897 standardMsg = '%r not less than or equal to %r' % (a, b)
898 self.fail(self._formatMessage(msg, standardMsg))
899
900 def assertGreater(self, a, b, msg=None):
901 """Just like self.assertTrue(a > b), but with a nicer default message."""
902 if not a > b:
903 standardMsg = '%r not greater than %r' % (a, b)
904 self.fail(self._formatMessage(msg, standardMsg))
905
906 def assertGreaterEqual(self, a, b, msg=None):
907 """Just like self.assertTrue(a >= b), but with a nicer default message."""
908 if not a >= b:
909 standardMsg = '%r not greater than or equal to %r' % (a, b)
910 self.fail(self._formatMessage(msg, standardMsg))
911
912 def assertIsNone(self, obj, msg=None):
913 """Same as self.assertTrue(obj is None), with a nicer default message."""
914 if obj is not None:
915 standardMsg = '%r is not None' % obj
916 self.fail(self._formatMessage(msg, standardMsg))
917
918 def assertIsNotNone(self, obj, msg=None):
919 """Included for symmetry with assertIsNone."""
920 if obj is None:
921 standardMsg = 'unexpectedly None'
922 self.fail(self._formatMessage(msg, standardMsg))
923
924 def assertRaisesRegexp(self, expected_exception, expected_regexp,
925 callable_obj=None, *args, **kwargs):
926 """Asserts that the message in a raised exception matches a regexp.
927
928 Args:
929 expected_exception: Exception class expected to be raised.
930 expected_regexp: Regexp (re pattern object or string) expected
931 to be found in error message.
932 callable_obj: Function to be called.
933 args: Extra args.
934 kwargs: Extra kwargs.
935 """
936 context = _AssertRaisesContext(expected_exception, self, callable_obj,
937 expected_regexp)
938 if callable_obj is None:
939 return context
940 with context:
941 callable_obj(*args, **kwargs)
942
943 def assertRegexpMatches(self, text, expected_regex, msg=None):
944 if isinstance(expected_regex, (str, bytes)):
945 expected_regex = re.compile(expected_regex)
946 if not expected_regex.search(text):
947 msg = msg or "Regexp didn't match"
948 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
949 raise self.failureException(msg)
950
951
952def _SortedListDifference(expected, actual):
953 """Finds elements in only one or the other of two, sorted input lists.
954
955 Returns a two-element tuple of lists. The first list contains those
956 elements in the "expected" list but not in the "actual" list, and the
957 second contains those elements in the "actual" list but not in the
958 "expected" list. Duplicate elements in either input list are ignored.
959 """
960 i = j = 0
961 missing = []
962 unexpected = []
963 while True:
964 try:
965 e = expected[i]
966 a = actual[j]
967 if e < a:
968 missing.append(e)
969 i += 1
970 while expected[i] == e:
971 i += 1
972 elif e > a:
973 unexpected.append(a)
974 j += 1
975 while actual[j] == a:
976 j += 1
977 else:
978 i += 1
979 try:
980 while expected[i] == e:
981 i += 1
982 finally:
983 j += 1
984 while actual[j] == a:
985 j += 1
986 except IndexError:
987 missing.extend(expected[i:])
988 unexpected.extend(actual[j:])
989 break
990 return missing, unexpected
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000991
Michael Foorda5809c82009-04-04 18:55:09 +0000992def _UnorderableListDifference(expected, actual):
993 """Same behavior as _SortedListDifference but
994 for lists of unorderable items (like dicts).
995
996 As it does a linear search per item (remove) it
997 has O(n*n) performance."""
998 missing = []
999 while expected:
1000 item = expected.pop()
1001 try:
1002 actual.remove(item)
1003 except ValueError:
1004 missing.append(item)
1005
1006 # anything left in actual is unexpected
1007 return missing, actual
Fred Drake02538202001-03-21 18:09:46 +00001008
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001009class TestSuite(object):
Fred Drake02538202001-03-21 18:09:46 +00001010 """A test suite is a composite test consisting of a number of TestCases.
1011
1012 For use, create an instance of TestSuite, then add test case instances.
1013 When all tests have been added, the suite can be passed to a test
1014 runner, such as TextTestRunner. It will run the individual test cases
1015 in the order in which they were added, aggregating the results. When
1016 subclassing, do not forget to call the base class constructor.
1017 """
1018 def __init__(self, tests=()):
1019 self._tests = []
1020 self.addTests(tests)
1021
1022 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +00001023 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +00001024
Guido van Rossumd8faa362007-04-27 19:54:29 +00001025 def __eq__(self, other):
Benjamin Peterson5254c042009-03-23 22:25:03 +00001026 if not isinstance(other, self.__class__):
1027 return NotImplemented
Guido van Rossumd8faa362007-04-27 19:54:29 +00001028 return self._tests == other._tests
1029
1030 def __ne__(self, other):
1031 return not self == other
1032
Jim Fultonfafd8742004-08-28 15:22:12 +00001033 def __iter__(self):
1034 return iter(self._tests)
1035
Fred Drake02538202001-03-21 18:09:46 +00001036 def countTestCases(self):
1037 cases = 0
1038 for test in self._tests:
Steve Purcell7e743842003-09-22 11:08:12 +00001039 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +00001040 return cases
1041
1042 def addTest(self, test):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001043 # sanity checks
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001044 if not hasattr(test, '__call__'):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001045 raise TypeError("the test to add must be callable")
Guido van Rossum13257902007-06-07 23:15:56 +00001046 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001047 raise TypeError("TestCases and TestSuites must be instantiated "
1048 "before passing them to addTest()")
Fred Drake02538202001-03-21 18:09:46 +00001049 self._tests.append(test)
1050
1051 def addTests(self, tests):
Guido van Rossum3172c5d2007-10-16 18:12:55 +00001052 if isinstance(tests, str):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001053 raise TypeError("tests must be an iterable of tests, not a string")
Fred Drake02538202001-03-21 18:09:46 +00001054 for test in tests:
1055 self.addTest(test)
1056
1057 def run(self, result):
Fred Drake02538202001-03-21 18:09:46 +00001058 for test in self._tests:
1059 if result.shouldStop:
1060 break
1061 test(result)
1062 return result
1063
Raymond Hettinger664347b2004-12-04 21:21:53 +00001064 def __call__(self, *args, **kwds):
1065 return self.run(*args, **kwds)
1066
Fred Drake02538202001-03-21 18:09:46 +00001067 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001068 """Run the tests without collecting errors in a TestResult"""
Benjamin Peterson52baa292009-03-24 00:56:30 +00001069 for test in self._tests:
1070 test.debug()
Fred Drake02538202001-03-21 18:09:46 +00001071
1072
Benjamin Peterson5254c042009-03-23 22:25:03 +00001073class ClassTestSuite(TestSuite):
1074 """
1075 Suite of tests derived from a single TestCase class.
1076 """
1077
1078 def __init__(self, tests, class_collected_from):
1079 super(ClassTestSuite, self).__init__(tests)
1080 self.collected_from = class_collected_from
1081
1082 def id(self):
1083 module = getattr(self.collected_from, "__module__", None)
1084 if module is not None:
1085 return "{0}.{1}".format(module, self.collected_from.__name__)
1086 return self.collected_from.__name__
1087
1088 def run(self, result):
1089 if getattr(self.collected_from, "__unittest_skip__", False):
1090 # ClassTestSuite result pretends to be a TestCase enough to be
1091 # reported.
1092 result.startTest(self)
1093 try:
1094 result.addSkip(self, self.collected_from.__unittest_skip_why__)
1095 finally:
1096 result.stopTest(self)
1097 else:
1098 result = super(ClassTestSuite, self).run(result)
1099 return result
1100
1101 shortDescription = id
1102
1103
Fred Drake02538202001-03-21 18:09:46 +00001104class FunctionTestCase(TestCase):
1105 """A test case that wraps a test function.
1106
1107 This is useful for slipping pre-existing test functions into the
Guido van Rossumd8faa362007-04-27 19:54:29 +00001108 unittest framework. Optionally, set-up and tidy-up functions can be
Fred Drake02538202001-03-21 18:09:46 +00001109 supplied. As with TestCase, the tidy-up ('tearDown') function will
1110 always be called if the set-up ('setUp') function ran successfully.
1111 """
1112
Benjamin Peterson52baa292009-03-24 00:56:30 +00001113 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1114 super(FunctionTestCase, self).__init__()
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001115 self._setUpFunc = setUp
1116 self._tearDownFunc = tearDown
1117 self._testFunc = testFunc
1118 self._description = description
Fred Drake02538202001-03-21 18:09:46 +00001119
1120 def setUp(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001121 if self._setUpFunc is not None:
1122 self._setUpFunc()
Fred Drake02538202001-03-21 18:09:46 +00001123
1124 def tearDown(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001125 if self._tearDownFunc is not None:
1126 self._tearDownFunc()
Fred Drake02538202001-03-21 18:09:46 +00001127
1128 def runTest(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001129 self._testFunc()
Fred Drake02538202001-03-21 18:09:46 +00001130
1131 def id(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001132 return self._testFunc.__name__
Fred Drake02538202001-03-21 18:09:46 +00001133
Guido van Rossumd8faa362007-04-27 19:54:29 +00001134 def __eq__(self, other):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001135 if not isinstance(other, self.__class__):
1136 return NotImplemented
Guido van Rossumd8faa362007-04-27 19:54:29 +00001137
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001138 return self._setUpFunc == other._setUpFunc and \
1139 self._tearDownFunc == other._tearDownFunc and \
1140 self._testFunc == other._testFunc and \
1141 self._description == other._description
Guido van Rossumd8faa362007-04-27 19:54:29 +00001142
1143 def __ne__(self, other):
1144 return not self == other
1145
1146 def __hash__(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001147 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1148 self._testFunc, self._description))
Guido van Rossumd8faa362007-04-27 19:54:29 +00001149
Fred Drake02538202001-03-21 18:09:46 +00001150 def __str__(self):
Collin Winterce36ad82007-08-30 01:19:48 +00001151 return "%s (%s)" % (_strclass(self.__class__),
1152 self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +00001153
1154 def __repr__(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001155 return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc)
Fred Drake02538202001-03-21 18:09:46 +00001156
1157 def shortDescription(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001158 if self._description is not None:
1159 return self._description
1160 doc = self._testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +00001161 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +00001162
1163
1164
1165##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001166# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +00001167##############################################################################
1168
Raymond Hettingerd4cb56d2008-01-30 02:55:10 +00001169def CmpToKey(mycmp):
1170 'Convert a cmp= function into a key= function'
1171 class K(object):
1172 def __init__(self, obj, *args):
1173 self.obj = obj
1174 def __lt__(self, other):
1175 return mycmp(self.obj, other.obj) == -1
1176 return K
1177
Mark Dickinsona56c4672009-01-27 18:17:45 +00001178def three_way_cmp(x, y):
1179 """Return -1 if x < y, 0 if x == y and 1 if x > y"""
1180 return (x > y) - (x < y)
1181
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001182class TestLoader(object):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001183 """
1184 This class is responsible for loading tests according to various criteria
1185 and returning them wrapped in a TestSuite
Fred Drake02538202001-03-21 18:09:46 +00001186 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001187 testMethodPrefix = 'test'
Mark Dickinsona56c4672009-01-27 18:17:45 +00001188 sortTestMethodsUsing = staticmethod(three_way_cmp)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001189 suiteClass = TestSuite
Benjamin Peterson5254c042009-03-23 22:25:03 +00001190 classSuiteClass = ClassTestSuite
Fred Drake02538202001-03-21 18:09:46 +00001191
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001192 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001193 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +00001194 if issubclass(testCaseClass, TestSuite):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001195 raise TypeError("Test cases should not be derived from TestSuite." \
1196 " Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +00001197 testCaseNames = self.getTestCaseNames(testCaseClass)
1198 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1199 testCaseNames = ['runTest']
Benjamin Peterson5254c042009-03-23 22:25:03 +00001200 suite = self.classSuiteClass(map(testCaseClass, testCaseNames),
1201 testCaseClass)
1202 return suite
Fred Drake02538202001-03-21 18:09:46 +00001203
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001204 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +00001205 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001206 tests = []
1207 for name in dir(module):
1208 obj = getattr(module, name)
Guido van Rossum13257902007-06-07 23:15:56 +00001209 if isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001210 tests.append(self.loadTestsFromTestCase(obj))
1211 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +00001212
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001213 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001214 """Return a suite of all tests cases given a string specifier.
1215
1216 The name may resolve either to a module, a test case class, a
1217 test method within a test case class, or a callable object which
1218 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +00001219
Steve Purcell15d89272001-04-12 09:05:01 +00001220 The method optionally resolves the names relative to a given module.
1221 """
Steve Purcell7e743842003-09-22 11:08:12 +00001222 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001223 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +00001224 parts_copy = parts[:]
1225 while parts_copy:
1226 try:
1227 module = __import__('.'.join(parts_copy))
1228 break
1229 except ImportError:
1230 del parts_copy[-1]
Benjamin Peterson52baa292009-03-24 00:56:30 +00001231 if not parts_copy:
1232 raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +00001233 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001234 obj = module
1235 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +00001236 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +00001237
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001238 if isinstance(obj, types.ModuleType):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001239 return self.loadTestsFromModule(obj)
Guido van Rossum13257902007-06-07 23:15:56 +00001240 elif isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001241 return self.loadTestsFromTestCase(obj)
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001242 elif (isinstance(obj, types.FunctionType) and
Guido van Rossum13257902007-06-07 23:15:56 +00001243 isinstance(parent, type) and
Guido van Rossumd8faa362007-04-27 19:54:29 +00001244 issubclass(parent, TestCase)):
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001245 name = obj.__name__
1246 inst = parent(name)
1247 # static methods follow a different path
Christian Heimes4975a1f2007-11-26 10:14:51 +00001248 if not isinstance(getattr(inst, name), types.FunctionType):
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001249 return TestSuite([inst])
Steve Purcell397b45d2003-10-26 10:41:03 +00001250 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +00001251 return obj
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001252
1253 if hasattr(obj, '__call__'):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001254 test = obj()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001255 if isinstance(test, TestSuite):
1256 return test
1257 elif isinstance(test, TestCase):
1258 return TestSuite([test])
1259 else:
1260 raise TypeError("calling %s returned %s, not a test" %
1261 (obj, test))
Fred Drake02538202001-03-21 18:09:46 +00001262 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001263 raise TypeError("don't know how to make test from: %s" % obj)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001264
1265 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001266 """Return a suite of all tests cases found using the given sequence
1267 of string specifiers. See 'loadTestsFromName()'.
1268 """
Steve Purcell7e743842003-09-22 11:08:12 +00001269 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001270 return self.suiteClass(suites)
1271
1272 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001273 """Return a sorted sequence of method names found within testCaseClass
1274 """
Collin Winterce36ad82007-08-30 01:19:48 +00001275 def isTestMethod(attrname, testCaseClass=testCaseClass,
1276 prefix=self.testMethodPrefix):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001277 return attrname.startswith(prefix) and \
1278 hasattr(getattr(testCaseClass, attrname), '__call__')
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001279 testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001280 if self.sortTestMethodsUsing:
Raymond Hettingerd4cb56d2008-01-30 02:55:10 +00001281 testFnNames.sort(key=CmpToKey(self.sortTestMethodsUsing))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001282 return testFnNames
1283
1284
1285
1286defaultTestLoader = TestLoader()
1287
1288
1289##############################################################################
1290# Patches for old functions: these functions should be considered obsolete
1291##############################################################################
1292
1293def _makeLoader(prefix, sortUsing, suiteClass=None):
1294 loader = TestLoader()
1295 loader.sortTestMethodsUsing = sortUsing
1296 loader.testMethodPrefix = prefix
1297 if suiteClass: loader.suiteClass = suiteClass
1298 return loader
1299
Mark Dickinsonc429a832009-01-27 20:27:05 +00001300def getTestCaseNames(testCaseClass, prefix, sortUsing=three_way_cmp):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001301 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1302
Mark Dickinsonc429a832009-01-27 20:27:05 +00001303def makeSuite(testCaseClass, prefix='test', sortUsing=three_way_cmp,
1304 suiteClass=TestSuite):
1305 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(
1306 testCaseClass)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001307
Mark Dickinsonc429a832009-01-27 20:27:05 +00001308def findTestCases(module, prefix='test', sortUsing=three_way_cmp,
1309 suiteClass=TestSuite):
1310 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(
1311 module)
Fred Drake02538202001-03-21 18:09:46 +00001312
1313
1314##############################################################################
1315# Text UI
1316##############################################################################
1317
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001318class _WritelnDecorator(object):
Fred Drake02538202001-03-21 18:09:46 +00001319 """Used to decorate file-like objects with a handy 'writeln' method"""
1320 def __init__(self,stream):
1321 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +00001322
1323 def __getattr__(self, attr):
1324 return getattr(self.stream,attr)
1325
Raymond Hettinger91dd19d2003-09-13 02:58:00 +00001326 def writeln(self, arg=None):
Benjamin Petersone549ead2009-03-28 21:42:05 +00001327 if arg:
1328 self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001329 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +00001330
Fred Drake02538202001-03-21 18:09:46 +00001331
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001332class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +00001333 """A test result class that can print formatted text results to a stream.
1334
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001335 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +00001336 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001337 separator1 = '=' * 70
1338 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +00001339
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001340 def __init__(self, stream, descriptions, verbosity):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001341 super(_TextTestResult, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001342 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001343 self.showAll = verbosity > 1
1344 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +00001345 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001346
1347 def getDescription(self, test):
1348 if self.descriptions:
1349 return test.shortDescription() or str(test)
1350 else:
1351 return str(test)
1352
Fred Drake02538202001-03-21 18:09:46 +00001353 def startTest(self, test):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001354 super(_TextTestResult, self).startTest(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001355 if self.showAll:
1356 self.stream.write(self.getDescription(test))
1357 self.stream.write(" ... ")
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001358 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001359
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001360 def addSuccess(self, test):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001361 super(_TextTestResult, self).addSuccess(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001362 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001363 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001364 elif self.dots:
1365 self.stream.write('.')
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001366 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001367
1368 def addError(self, test, err):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001369 super(_TextTestResult, self).addError(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001370 if self.showAll:
1371 self.stream.writeln("ERROR")
1372 elif self.dots:
1373 self.stream.write('E')
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001374 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001375
1376 def addFailure(self, test, err):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001377 super(_TextTestResult, self).addFailure(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001378 if self.showAll:
1379 self.stream.writeln("FAIL")
1380 elif self.dots:
1381 self.stream.write('F')
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001382 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001383
Benjamin Peterson5254c042009-03-23 22:25:03 +00001384 def addSkip(self, test, reason):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001385 super(_TextTestResult, self).addSkip(test, reason)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001386 if self.showAll:
1387 self.stream.writeln("skipped {0!r}".format(reason))
1388 elif self.dots:
1389 self.stream.write("s")
1390 self.stream.flush()
1391
1392 def addExpectedFailure(self, test, err):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001393 super(_TextTestResult, self).addExpectedFailure(test, err)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001394 if self.showAll:
1395 self.stream.writeln("expected failure")
1396 elif self.dots:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001397 self.stream.write("x")
Benjamin Peterson5254c042009-03-23 22:25:03 +00001398 self.stream.flush()
1399
1400 def addUnexpectedSuccess(self, test):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001401 super(_TextTestResult, self).addUnexpectedSuccess(test)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001402 if self.showAll:
1403 self.stream.writeln("unexpected success")
1404 elif self.dots:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001405 self.stream.write("u")
Benjamin Peterson5254c042009-03-23 22:25:03 +00001406 self.stream.flush()
1407
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001408 def printErrors(self):
1409 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001410 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001411 self.printErrorList('ERROR', self.errors)
1412 self.printErrorList('FAIL', self.failures)
1413
1414 def printErrorList(self, flavour, errors):
1415 for test, err in errors:
1416 self.stream.writeln(self.separator1)
1417 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1418 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +00001419 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +00001420
1421
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001422class TextTestRunner(object):
Fred Drake02538202001-03-21 18:09:46 +00001423 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +00001424
Fred Drake02538202001-03-21 18:09:46 +00001425 It prints out the names of tests as they are run, errors as they
1426 occur, and a summary of the results at the end of the test run.
1427 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001428 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +00001429 self.stream = _WritelnDecorator(stream)
1430 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001431 self.verbosity = verbosity
1432
1433 def _makeResult(self):
1434 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +00001435
1436 def run(self, test):
1437 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001438 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +00001439 startTime = time.time()
1440 test(result)
1441 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +00001442 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001443 result.printErrors()
1444 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +00001445 run = result.testsRun
1446 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +00001447 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +00001448 self.stream.writeln()
Benjamin Peterson52baa292009-03-24 00:56:30 +00001449 results = map(len, (result.expectedFailures,
1450 result.unexpectedSuccesses,
Benjamin Peterson5254c042009-03-23 22:25:03 +00001451 result.skipped))
Benjamin Peterson52baa292009-03-24 00:56:30 +00001452 expectedFails, unexpectedSuccesses, skipped = results
Benjamin Peterson5254c042009-03-23 22:25:03 +00001453 infos = []
Fred Drake02538202001-03-21 18:09:46 +00001454 if not result.wasSuccessful():
Benjamin Peterson5254c042009-03-23 22:25:03 +00001455 self.stream.write("FAILED")
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001456 failed, errored = len(result.failures), len(result.errors)
Fred Drake02538202001-03-21 18:09:46 +00001457 if failed:
Benjamin Peterson5254c042009-03-23 22:25:03 +00001458 infos.append("failures=%d" % failed)
Fred Drake02538202001-03-21 18:09:46 +00001459 if errored:
Benjamin Peterson5254c042009-03-23 22:25:03 +00001460 infos.append("errors=%d" % errored)
Fred Drake02538202001-03-21 18:09:46 +00001461 else:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001462 self.stream.write("OK")
Benjamin Peterson5254c042009-03-23 22:25:03 +00001463 if skipped:
1464 infos.append("skipped=%d" % skipped)
Benjamin Peterson52baa292009-03-24 00:56:30 +00001465 if expectedFails:
1466 infos.append("expected failures=%d" % expectedFails)
1467 if unexpectedSuccesses:
1468 infos.append("unexpected successes=%d" % unexpectedSuccesses)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001469 if infos:
1470 self.stream.writeln(" (%s)" % (", ".join(infos),))
Benjamin Petersone549ead2009-03-28 21:42:05 +00001471 else:
1472 self.stream.write("\n")
Fred Drake02538202001-03-21 18:09:46 +00001473 return result
Tim Petersa19a1682001-03-29 04:36:09 +00001474
Fred Drake02538202001-03-21 18:09:46 +00001475
Fred Drake02538202001-03-21 18:09:46 +00001476
1477##############################################################################
1478# Facilities for running tests from the command line
1479##############################################################################
1480
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001481class TestProgram(object):
Fred Drake02538202001-03-21 18:09:46 +00001482 """A command-line program that runs a set of tests; this is primarily
1483 for making test modules conveniently executable.
1484 """
1485 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +00001486Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001487
1488Options:
1489 -h, --help Show this message
1490 -v, --verbose Verbose output
1491 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +00001492
1493Examples:
1494 %(progName)s - run default set of tests
1495 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001496 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1497 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +00001498 in MyTestCase
1499"""
1500 def __init__(self, module='__main__', defaultTest=None,
Guido van Rossumd8faa362007-04-27 19:54:29 +00001501 argv=None, testRunner=TextTestRunner,
1502 testLoader=defaultTestLoader):
Antoine Pitroue7bd8682009-01-09 19:29:16 +00001503 if isinstance(module, str):
Fred Drake02538202001-03-21 18:09:46 +00001504 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +00001505 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +00001506 self.module = getattr(self.module, part)
1507 else:
1508 self.module = module
1509 if argv is None:
1510 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001511 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +00001512 self.defaultTest = defaultTest
1513 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001514 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +00001515 self.progName = os.path.basename(argv[0])
1516 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +00001517 self.runTests()
1518
1519 def usageExit(self, msg=None):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001520 if msg:
1521 print(msg)
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001522 print(self.USAGE % self.__dict__)
Fred Drake02538202001-03-21 18:09:46 +00001523 sys.exit(2)
1524
1525 def parseArgs(self, argv):
1526 import getopt
Benjamin Peterson5254c042009-03-23 22:25:03 +00001527 long_opts = ['help','verbose','quiet']
Fred Drake02538202001-03-21 18:09:46 +00001528 try:
Benjamin Peterson5254c042009-03-23 22:25:03 +00001529 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
Fred Drake02538202001-03-21 18:09:46 +00001530 for opt, value in options:
1531 if opt in ('-h','-H','--help'):
1532 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001533 if opt in ('-q','--quiet'):
1534 self.verbosity = 0
1535 if opt in ('-v','--verbose'):
1536 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +00001537 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001538 self.test = self.testLoader.loadTestsFromModule(self.module)
1539 return
Fred Drake02538202001-03-21 18:09:46 +00001540 if len(args) > 0:
1541 self.testNames = args
1542 else:
1543 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001544 self.createTests()
Guido van Rossumb940e112007-01-10 16:19:56 +00001545 except getopt.error as msg:
Fred Drake02538202001-03-21 18:09:46 +00001546 self.usageExit(msg)
1547
1548 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001549 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1550 self.module)
Fred Drake02538202001-03-21 18:09:46 +00001551
1552 def runTests(self):
Guido van Rossum13257902007-06-07 23:15:56 +00001553 if isinstance(self.testRunner, type):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001554 try:
1555 testRunner = self.testRunner(verbosity=self.verbosity)
1556 except TypeError:
1557 # didn't accept the verbosity argument
1558 testRunner = self.testRunner()
1559 else:
1560 # it is assumed to be a TestRunner instance
1561 testRunner = self.testRunner
1562 result = testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +00001563 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +00001564
1565main = TestProgram
1566
1567
1568##############################################################################
1569# Executing this module from the command line
1570##############################################################################
1571
1572if __name__ == "__main__":
1573 main(module=None)