blob: 0b7cea4d5be83b7249868c2e5d729a396b069e52 [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
Benjamin Petersonf47ed4a2009-04-11 20:45:40 +0000810 def assertIs(self, expr1, expr2, msg=None):
811 """Just like self.assertTrue(a is b), but with a nicer default message."""
812 if expr1 is not expr2:
813 standardMsg = '%r is not %r' % (expr1, expr2)
814 self.fail(self._formatMessage(msg, standardMsg))
815
816 def assertIsNot(self, expr1, expr2, msg=None):
817 """Just like self.assertTrue(a is not b), but with a nicer default message."""
818 if expr1 is expr2:
819 standardMsg = 'unexpectedly identical: %r' % (expr1,)
820 self.fail(self._formatMessage(msg, standardMsg))
821
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000822 def assertDictEqual(self, d1, d2, msg=None):
823 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
824 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
825
826 if d1 != d2:
827 standardMsg = ('\n' + '\n'.join(difflib.ndiff(
828 pprint.pformat(d1).splitlines(),
829 pprint.pformat(d2).splitlines())))
830 self.fail(self._formatMessage(msg, standardMsg))
831
832 def assertDictContainsSubset(self, expected, actual, msg=None):
833 """Checks whether actual is a superset of expected."""
834 missing = []
835 mismatched = []
836 for key, value in expected.items():
837 if key not in actual:
838 missing.append(key)
839 elif value != actual[key]:
840 mismatched.append('%s, expected: %s, actual: %s' % (key, value, actual[key]))
841
842 if not (missing or mismatched):
843 return
844
845 standardMsg = ''
846 if missing:
847 standardMsg = 'Missing: %r' % ','.join(missing)
848 if mismatched:
849 if standardMsg:
850 standardMsg += '; '
851 standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
852
853 self.fail(self._formatMessage(msg, standardMsg))
854
855 def assertSameElements(self, expected_seq, actual_seq, msg=None):
856 """An unordered sequence specific comparison.
857
858 Raises with an error message listing which elements of expected_seq
859 are missing from actual_seq and vice versa if any.
860 """
861 try:
862 expected = set(expected_seq)
863 actual = set(actual_seq)
864 missing = list(expected.difference(actual))
865 unexpected = list(actual.difference(expected))
866 missing.sort()
867 unexpected.sort()
868 except TypeError:
869 # Fall back to slower list-compare if any of the objects are
870 # not hashable.
871 expected = list(expected_seq)
872 actual = list(actual_seq)
Michael Foorda5809c82009-04-04 18:55:09 +0000873 try:
874 expected.sort()
875 actual.sort()
876 except TypeError:
877 missing, unexpected = _UnorderableListDifference(expected, actual)
878 else:
879 missing, unexpected = _SortedListDifference(expected, actual)
Benjamin Peterson7fe73a12009-04-04 16:35:46 +0000880 errors = []
881 if missing:
882 errors.append('Expected, but missing:\n %r' % missing)
883 if unexpected:
884 errors.append('Unexpected, but present:\n %r' % unexpected)
885 if errors:
886 standardMsg = '\n'.join(errors)
887 self.fail(self._formatMessage(msg, standardMsg))
888
889 def assertMultiLineEqual(self, first, second, msg=None):
890 """Assert that two multi-line strings are equal."""
891 self.assert_(isinstance(first, str), (
892 'First argument is not a string'))
893 self.assert_(isinstance(second, str), (
894 'Second argument is not a string'))
895
896 if first != second:
897 standardMsg = '\n' + ''.join(difflib.ndiff(first.splitlines(True), second.splitlines(True)))
898 self.fail(self._formatMessage(msg, standardMsg))
899
900 def assertLess(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 less than %r' % (a, b)
904 self.fail(self._formatMessage(msg, standardMsg))
905
906 def assertLessEqual(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 less than or equal to %r' % (a, b)
910 self.fail(self._formatMessage(msg, standardMsg))
911
912 def assertGreater(self, a, b, msg=None):
913 """Just like self.assertTrue(a > b), but with a nicer default message."""
914 if not a > b:
915 standardMsg = '%r not greater than %r' % (a, b)
916 self.fail(self._formatMessage(msg, standardMsg))
917
918 def assertGreaterEqual(self, a, b, msg=None):
919 """Just like self.assertTrue(a >= b), but with a nicer default message."""
920 if not a >= b:
921 standardMsg = '%r not greater than or equal to %r' % (a, b)
922 self.fail(self._formatMessage(msg, standardMsg))
923
924 def assertIsNone(self, obj, msg=None):
925 """Same as self.assertTrue(obj is None), with a nicer default message."""
926 if obj is not None:
927 standardMsg = '%r is not None' % obj
928 self.fail(self._formatMessage(msg, standardMsg))
929
930 def assertIsNotNone(self, obj, msg=None):
931 """Included for symmetry with assertIsNone."""
932 if obj is None:
933 standardMsg = 'unexpectedly None'
934 self.fail(self._formatMessage(msg, standardMsg))
935
936 def assertRaisesRegexp(self, expected_exception, expected_regexp,
937 callable_obj=None, *args, **kwargs):
938 """Asserts that the message in a raised exception matches a regexp.
939
940 Args:
941 expected_exception: Exception class expected to be raised.
942 expected_regexp: Regexp (re pattern object or string) expected
943 to be found in error message.
944 callable_obj: Function to be called.
945 args: Extra args.
946 kwargs: Extra kwargs.
947 """
948 context = _AssertRaisesContext(expected_exception, self, callable_obj,
949 expected_regexp)
950 if callable_obj is None:
951 return context
952 with context:
953 callable_obj(*args, **kwargs)
954
955 def assertRegexpMatches(self, text, expected_regex, msg=None):
956 if isinstance(expected_regex, (str, bytes)):
957 expected_regex = re.compile(expected_regex)
958 if not expected_regex.search(text):
959 msg = msg or "Regexp didn't match"
960 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
961 raise self.failureException(msg)
962
963
964def _SortedListDifference(expected, actual):
965 """Finds elements in only one or the other of two, sorted input lists.
966
967 Returns a two-element tuple of lists. The first list contains those
968 elements in the "expected" list but not in the "actual" list, and the
969 second contains those elements in the "actual" list but not in the
970 "expected" list. Duplicate elements in either input list are ignored.
971 """
972 i = j = 0
973 missing = []
974 unexpected = []
975 while True:
976 try:
977 e = expected[i]
978 a = actual[j]
979 if e < a:
980 missing.append(e)
981 i += 1
982 while expected[i] == e:
983 i += 1
984 elif e > a:
985 unexpected.append(a)
986 j += 1
987 while actual[j] == a:
988 j += 1
989 else:
990 i += 1
991 try:
992 while expected[i] == e:
993 i += 1
994 finally:
995 j += 1
996 while actual[j] == a:
997 j += 1
998 except IndexError:
999 missing.extend(expected[i:])
1000 unexpected.extend(actual[j:])
1001 break
1002 return missing, unexpected
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001003
Michael Foorda5809c82009-04-04 18:55:09 +00001004def _UnorderableListDifference(expected, actual):
1005 """Same behavior as _SortedListDifference but
1006 for lists of unorderable items (like dicts).
1007
1008 As it does a linear search per item (remove) it
1009 has O(n*n) performance."""
1010 missing = []
1011 while expected:
1012 item = expected.pop()
1013 try:
1014 actual.remove(item)
1015 except ValueError:
1016 missing.append(item)
1017
1018 # anything left in actual is unexpected
1019 return missing, actual
Fred Drake02538202001-03-21 18:09:46 +00001020
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001021class TestSuite(object):
Fred Drake02538202001-03-21 18:09:46 +00001022 """A test suite is a composite test consisting of a number of TestCases.
1023
1024 For use, create an instance of TestSuite, then add test case instances.
1025 When all tests have been added, the suite can be passed to a test
1026 runner, such as TextTestRunner. It will run the individual test cases
1027 in the order in which they were added, aggregating the results. When
1028 subclassing, do not forget to call the base class constructor.
1029 """
1030 def __init__(self, tests=()):
1031 self._tests = []
1032 self.addTests(tests)
1033
1034 def __repr__(self):
Benjamin Petersonf47ed4a2009-04-11 20:45:40 +00001035 return "<%s tests=%s>" % (_strclass(self.__class__), list(self))
Fred Drake02538202001-03-21 18:09:46 +00001036
Guido van Rossumd8faa362007-04-27 19:54:29 +00001037 def __eq__(self, other):
Benjamin Peterson5254c042009-03-23 22:25:03 +00001038 if not isinstance(other, self.__class__):
1039 return NotImplemented
Guido van Rossumd8faa362007-04-27 19:54:29 +00001040 return self._tests == other._tests
1041
1042 def __ne__(self, other):
1043 return not self == other
1044
Jim Fultonfafd8742004-08-28 15:22:12 +00001045 def __iter__(self):
1046 return iter(self._tests)
1047
Fred Drake02538202001-03-21 18:09:46 +00001048 def countTestCases(self):
1049 cases = 0
Benjamin Petersonf47ed4a2009-04-11 20:45:40 +00001050 for test in self:
Steve Purcell7e743842003-09-22 11:08:12 +00001051 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +00001052 return cases
1053
1054 def addTest(self, test):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001055 # sanity checks
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001056 if not hasattr(test, '__call__'):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001057 raise TypeError("the test to add must be callable")
Guido van Rossum13257902007-06-07 23:15:56 +00001058 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001059 raise TypeError("TestCases and TestSuites must be instantiated "
1060 "before passing them to addTest()")
Fred Drake02538202001-03-21 18:09:46 +00001061 self._tests.append(test)
1062
1063 def addTests(self, tests):
Guido van Rossum3172c5d2007-10-16 18:12:55 +00001064 if isinstance(tests, str):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001065 raise TypeError("tests must be an iterable of tests, not a string")
Fred Drake02538202001-03-21 18:09:46 +00001066 for test in tests:
1067 self.addTest(test)
1068
1069 def run(self, result):
Benjamin Petersonf47ed4a2009-04-11 20:45:40 +00001070 for test in self:
Fred Drake02538202001-03-21 18:09:46 +00001071 if result.shouldStop:
1072 break
1073 test(result)
1074 return result
1075
Raymond Hettinger664347b2004-12-04 21:21:53 +00001076 def __call__(self, *args, **kwds):
1077 return self.run(*args, **kwds)
1078
Fred Drake02538202001-03-21 18:09:46 +00001079 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001080 """Run the tests without collecting errors in a TestResult"""
Benjamin Petersonf47ed4a2009-04-11 20:45:40 +00001081 for test in self:
Benjamin Peterson52baa292009-03-24 00:56:30 +00001082 test.debug()
Fred Drake02538202001-03-21 18:09:46 +00001083
1084
Benjamin Peterson5254c042009-03-23 22:25:03 +00001085class ClassTestSuite(TestSuite):
1086 """
1087 Suite of tests derived from a single TestCase class.
1088 """
1089
1090 def __init__(self, tests, class_collected_from):
1091 super(ClassTestSuite, self).__init__(tests)
1092 self.collected_from = class_collected_from
1093
1094 def id(self):
1095 module = getattr(self.collected_from, "__module__", None)
1096 if module is not None:
1097 return "{0}.{1}".format(module, self.collected_from.__name__)
1098 return self.collected_from.__name__
1099
1100 def run(self, result):
1101 if getattr(self.collected_from, "__unittest_skip__", False):
1102 # ClassTestSuite result pretends to be a TestCase enough to be
1103 # reported.
1104 result.startTest(self)
1105 try:
1106 result.addSkip(self, self.collected_from.__unittest_skip_why__)
1107 finally:
1108 result.stopTest(self)
1109 else:
1110 result = super(ClassTestSuite, self).run(result)
1111 return result
1112
1113 shortDescription = id
1114
1115
Fred Drake02538202001-03-21 18:09:46 +00001116class FunctionTestCase(TestCase):
1117 """A test case that wraps a test function.
1118
1119 This is useful for slipping pre-existing test functions into the
Guido van Rossumd8faa362007-04-27 19:54:29 +00001120 unittest framework. Optionally, set-up and tidy-up functions can be
Fred Drake02538202001-03-21 18:09:46 +00001121 supplied. As with TestCase, the tidy-up ('tearDown') function will
1122 always be called if the set-up ('setUp') function ran successfully.
1123 """
1124
Benjamin Peterson52baa292009-03-24 00:56:30 +00001125 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1126 super(FunctionTestCase, self).__init__()
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001127 self._setUpFunc = setUp
1128 self._tearDownFunc = tearDown
1129 self._testFunc = testFunc
1130 self._description = description
Fred Drake02538202001-03-21 18:09:46 +00001131
1132 def setUp(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001133 if self._setUpFunc is not None:
1134 self._setUpFunc()
Fred Drake02538202001-03-21 18:09:46 +00001135
1136 def tearDown(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001137 if self._tearDownFunc is not None:
1138 self._tearDownFunc()
Fred Drake02538202001-03-21 18:09:46 +00001139
1140 def runTest(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001141 self._testFunc()
Fred Drake02538202001-03-21 18:09:46 +00001142
1143 def id(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001144 return self._testFunc.__name__
Fred Drake02538202001-03-21 18:09:46 +00001145
Guido van Rossumd8faa362007-04-27 19:54:29 +00001146 def __eq__(self, other):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001147 if not isinstance(other, self.__class__):
1148 return NotImplemented
Guido van Rossumd8faa362007-04-27 19:54:29 +00001149
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001150 return self._setUpFunc == other._setUpFunc and \
1151 self._tearDownFunc == other._tearDownFunc and \
1152 self._testFunc == other._testFunc and \
1153 self._description == other._description
Guido van Rossumd8faa362007-04-27 19:54:29 +00001154
1155 def __ne__(self, other):
1156 return not self == other
1157
1158 def __hash__(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001159 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1160 self._testFunc, self._description))
Guido van Rossumd8faa362007-04-27 19:54:29 +00001161
Fred Drake02538202001-03-21 18:09:46 +00001162 def __str__(self):
Collin Winterce36ad82007-08-30 01:19:48 +00001163 return "%s (%s)" % (_strclass(self.__class__),
1164 self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +00001165
1166 def __repr__(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001167 return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc)
Fred Drake02538202001-03-21 18:09:46 +00001168
1169 def shortDescription(self):
Benjamin Peterson7fe73a12009-04-04 16:35:46 +00001170 if self._description is not None:
1171 return self._description
1172 doc = self._testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +00001173 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +00001174
1175
1176
1177##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001178# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +00001179##############################################################################
1180
Raymond Hettingerd4cb56d2008-01-30 02:55:10 +00001181def CmpToKey(mycmp):
1182 'Convert a cmp= function into a key= function'
1183 class K(object):
1184 def __init__(self, obj, *args):
1185 self.obj = obj
1186 def __lt__(self, other):
1187 return mycmp(self.obj, other.obj) == -1
1188 return K
1189
Mark Dickinsona56c4672009-01-27 18:17:45 +00001190def three_way_cmp(x, y):
1191 """Return -1 if x < y, 0 if x == y and 1 if x > y"""
1192 return (x > y) - (x < y)
1193
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001194class TestLoader(object):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001195 """
1196 This class is responsible for loading tests according to various criteria
1197 and returning them wrapped in a TestSuite
Fred Drake02538202001-03-21 18:09:46 +00001198 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001199 testMethodPrefix = 'test'
Mark Dickinsona56c4672009-01-27 18:17:45 +00001200 sortTestMethodsUsing = staticmethod(three_way_cmp)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001201 suiteClass = TestSuite
Benjamin Peterson5254c042009-03-23 22:25:03 +00001202 classSuiteClass = ClassTestSuite
Fred Drake02538202001-03-21 18:09:46 +00001203
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001204 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001205 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +00001206 if issubclass(testCaseClass, TestSuite):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001207 raise TypeError("Test cases should not be derived from TestSuite." \
1208 " Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +00001209 testCaseNames = self.getTestCaseNames(testCaseClass)
1210 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1211 testCaseNames = ['runTest']
Benjamin Peterson5254c042009-03-23 22:25:03 +00001212 suite = self.classSuiteClass(map(testCaseClass, testCaseNames),
1213 testCaseClass)
1214 return suite
Fred Drake02538202001-03-21 18:09:46 +00001215
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001216 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +00001217 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001218 tests = []
1219 for name in dir(module):
1220 obj = getattr(module, name)
Guido van Rossum13257902007-06-07 23:15:56 +00001221 if isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001222 tests.append(self.loadTestsFromTestCase(obj))
1223 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +00001224
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001225 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001226 """Return a suite of all tests cases given a string specifier.
1227
1228 The name may resolve either to a module, a test case class, a
1229 test method within a test case class, or a callable object which
1230 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +00001231
Steve Purcell15d89272001-04-12 09:05:01 +00001232 The method optionally resolves the names relative to a given module.
1233 """
Steve Purcell7e743842003-09-22 11:08:12 +00001234 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001235 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +00001236 parts_copy = parts[:]
1237 while parts_copy:
1238 try:
1239 module = __import__('.'.join(parts_copy))
1240 break
1241 except ImportError:
1242 del parts_copy[-1]
Benjamin Peterson52baa292009-03-24 00:56:30 +00001243 if not parts_copy:
1244 raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +00001245 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001246 obj = module
1247 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +00001248 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +00001249
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001250 if isinstance(obj, types.ModuleType):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001251 return self.loadTestsFromModule(obj)
Guido van Rossum13257902007-06-07 23:15:56 +00001252 elif isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001253 return self.loadTestsFromTestCase(obj)
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001254 elif (isinstance(obj, types.FunctionType) and
Guido van Rossum13257902007-06-07 23:15:56 +00001255 isinstance(parent, type) and
Guido van Rossumd8faa362007-04-27 19:54:29 +00001256 issubclass(parent, TestCase)):
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001257 name = obj.__name__
1258 inst = parent(name)
1259 # static methods follow a different path
Christian Heimes4975a1f2007-11-26 10:14:51 +00001260 if not isinstance(getattr(inst, name), types.FunctionType):
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001261 return TestSuite([inst])
Steve Purcell397b45d2003-10-26 10:41:03 +00001262 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +00001263 return obj
Christian Heimes4a22b5d2007-11-25 09:39:14 +00001264
1265 if hasattr(obj, '__call__'):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001266 test = obj()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001267 if isinstance(test, TestSuite):
1268 return test
1269 elif isinstance(test, TestCase):
1270 return TestSuite([test])
1271 else:
1272 raise TypeError("calling %s returned %s, not a test" %
1273 (obj, test))
Fred Drake02538202001-03-21 18:09:46 +00001274 else:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001275 raise TypeError("don't know how to make test from: %s" % obj)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001276
1277 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001278 """Return a suite of all tests cases found using the given sequence
1279 of string specifiers. See 'loadTestsFromName()'.
1280 """
Steve Purcell7e743842003-09-22 11:08:12 +00001281 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001282 return self.suiteClass(suites)
1283
1284 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001285 """Return a sorted sequence of method names found within testCaseClass
1286 """
Collin Winterce36ad82007-08-30 01:19:48 +00001287 def isTestMethod(attrname, testCaseClass=testCaseClass,
1288 prefix=self.testMethodPrefix):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001289 return attrname.startswith(prefix) and \
1290 hasattr(getattr(testCaseClass, attrname), '__call__')
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001291 testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001292 if self.sortTestMethodsUsing:
Raymond Hettingerd4cb56d2008-01-30 02:55:10 +00001293 testFnNames.sort(key=CmpToKey(self.sortTestMethodsUsing))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001294 return testFnNames
1295
1296
1297
1298defaultTestLoader = TestLoader()
1299
1300
1301##############################################################################
1302# Patches for old functions: these functions should be considered obsolete
1303##############################################################################
1304
1305def _makeLoader(prefix, sortUsing, suiteClass=None):
1306 loader = TestLoader()
1307 loader.sortTestMethodsUsing = sortUsing
1308 loader.testMethodPrefix = prefix
1309 if suiteClass: loader.suiteClass = suiteClass
1310 return loader
1311
Mark Dickinsonc429a832009-01-27 20:27:05 +00001312def getTestCaseNames(testCaseClass, prefix, sortUsing=three_way_cmp):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001313 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1314
Mark Dickinsonc429a832009-01-27 20:27:05 +00001315def makeSuite(testCaseClass, prefix='test', sortUsing=three_way_cmp,
1316 suiteClass=TestSuite):
1317 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(
1318 testCaseClass)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001319
Mark Dickinsonc429a832009-01-27 20:27:05 +00001320def findTestCases(module, prefix='test', sortUsing=three_way_cmp,
1321 suiteClass=TestSuite):
1322 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(
1323 module)
Fred Drake02538202001-03-21 18:09:46 +00001324
1325
1326##############################################################################
1327# Text UI
1328##############################################################################
1329
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001330class _WritelnDecorator(object):
Fred Drake02538202001-03-21 18:09:46 +00001331 """Used to decorate file-like objects with a handy 'writeln' method"""
1332 def __init__(self,stream):
1333 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +00001334
1335 def __getattr__(self, attr):
1336 return getattr(self.stream,attr)
1337
Raymond Hettinger91dd19d2003-09-13 02:58:00 +00001338 def writeln(self, arg=None):
Benjamin Petersone549ead2009-03-28 21:42:05 +00001339 if arg:
1340 self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001341 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +00001342
Fred Drake02538202001-03-21 18:09:46 +00001343
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001344class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +00001345 """A test result class that can print formatted text results to a stream.
1346
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001347 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +00001348 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001349 separator1 = '=' * 70
1350 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +00001351
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001352 def __init__(self, stream, descriptions, verbosity):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001353 super(_TextTestResult, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001354 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001355 self.showAll = verbosity > 1
1356 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +00001357 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001358
1359 def getDescription(self, test):
1360 if self.descriptions:
1361 return test.shortDescription() or str(test)
1362 else:
1363 return str(test)
1364
Fred Drake02538202001-03-21 18:09:46 +00001365 def startTest(self, test):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001366 super(_TextTestResult, self).startTest(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001367 if self.showAll:
1368 self.stream.write(self.getDescription(test))
1369 self.stream.write(" ... ")
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001370 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001371
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001372 def addSuccess(self, test):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001373 super(_TextTestResult, self).addSuccess(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001374 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001375 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001376 elif self.dots:
1377 self.stream.write('.')
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001378 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001379
1380 def addError(self, test, err):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001381 super(_TextTestResult, self).addError(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001382 if self.showAll:
1383 self.stream.writeln("ERROR")
1384 elif self.dots:
1385 self.stream.write('E')
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001386 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001387
1388 def addFailure(self, test, err):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001389 super(_TextTestResult, self).addFailure(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001390 if self.showAll:
1391 self.stream.writeln("FAIL")
1392 elif self.dots:
1393 self.stream.write('F')
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +00001394 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001395
Benjamin Peterson5254c042009-03-23 22:25:03 +00001396 def addSkip(self, test, reason):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001397 super(_TextTestResult, self).addSkip(test, reason)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001398 if self.showAll:
1399 self.stream.writeln("skipped {0!r}".format(reason))
1400 elif self.dots:
1401 self.stream.write("s")
1402 self.stream.flush()
1403
1404 def addExpectedFailure(self, test, err):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001405 super(_TextTestResult, self).addExpectedFailure(test, err)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001406 if self.showAll:
1407 self.stream.writeln("expected failure")
1408 elif self.dots:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001409 self.stream.write("x")
Benjamin Peterson5254c042009-03-23 22:25:03 +00001410 self.stream.flush()
1411
1412 def addUnexpectedSuccess(self, test):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001413 super(_TextTestResult, self).addUnexpectedSuccess(test)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001414 if self.showAll:
1415 self.stream.writeln("unexpected success")
1416 elif self.dots:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001417 self.stream.write("u")
Benjamin Peterson5254c042009-03-23 22:25:03 +00001418 self.stream.flush()
1419
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001420 def printErrors(self):
1421 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001422 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001423 self.printErrorList('ERROR', self.errors)
1424 self.printErrorList('FAIL', self.failures)
1425
1426 def printErrorList(self, flavour, errors):
1427 for test, err in errors:
1428 self.stream.writeln(self.separator1)
1429 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1430 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +00001431 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +00001432
1433
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001434class TextTestRunner(object):
Fred Drake02538202001-03-21 18:09:46 +00001435 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +00001436
Fred Drake02538202001-03-21 18:09:46 +00001437 It prints out the names of tests as they are run, errors as they
1438 occur, and a summary of the results at the end of the test run.
1439 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001440 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +00001441 self.stream = _WritelnDecorator(stream)
1442 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001443 self.verbosity = verbosity
1444
1445 def _makeResult(self):
1446 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +00001447
1448 def run(self, test):
1449 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001450 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +00001451 startTime = time.time()
1452 test(result)
1453 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +00001454 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001455 result.printErrors()
1456 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +00001457 run = result.testsRun
1458 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +00001459 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +00001460 self.stream.writeln()
Benjamin Peterson52baa292009-03-24 00:56:30 +00001461 results = map(len, (result.expectedFailures,
1462 result.unexpectedSuccesses,
Benjamin Peterson5254c042009-03-23 22:25:03 +00001463 result.skipped))
Benjamin Peterson52baa292009-03-24 00:56:30 +00001464 expectedFails, unexpectedSuccesses, skipped = results
Benjamin Peterson5254c042009-03-23 22:25:03 +00001465 infos = []
Fred Drake02538202001-03-21 18:09:46 +00001466 if not result.wasSuccessful():
Benjamin Peterson5254c042009-03-23 22:25:03 +00001467 self.stream.write("FAILED")
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001468 failed, errored = len(result.failures), len(result.errors)
Fred Drake02538202001-03-21 18:09:46 +00001469 if failed:
Benjamin Peterson5254c042009-03-23 22:25:03 +00001470 infos.append("failures=%d" % failed)
Fred Drake02538202001-03-21 18:09:46 +00001471 if errored:
Benjamin Peterson5254c042009-03-23 22:25:03 +00001472 infos.append("errors=%d" % errored)
Fred Drake02538202001-03-21 18:09:46 +00001473 else:
Benjamin Petersone549ead2009-03-28 21:42:05 +00001474 self.stream.write("OK")
Benjamin Peterson5254c042009-03-23 22:25:03 +00001475 if skipped:
1476 infos.append("skipped=%d" % skipped)
Benjamin Peterson52baa292009-03-24 00:56:30 +00001477 if expectedFails:
1478 infos.append("expected failures=%d" % expectedFails)
1479 if unexpectedSuccesses:
1480 infos.append("unexpected successes=%d" % unexpectedSuccesses)
Benjamin Peterson5254c042009-03-23 22:25:03 +00001481 if infos:
1482 self.stream.writeln(" (%s)" % (", ".join(infos),))
Benjamin Petersone549ead2009-03-28 21:42:05 +00001483 else:
1484 self.stream.write("\n")
Fred Drake02538202001-03-21 18:09:46 +00001485 return result
Tim Petersa19a1682001-03-29 04:36:09 +00001486
Fred Drake02538202001-03-21 18:09:46 +00001487
Fred Drake02538202001-03-21 18:09:46 +00001488
1489##############################################################################
1490# Facilities for running tests from the command line
1491##############################################################################
1492
Benjamin Peterson1467ac82009-01-09 03:42:38 +00001493class TestProgram(object):
Fred Drake02538202001-03-21 18:09:46 +00001494 """A command-line program that runs a set of tests; this is primarily
1495 for making test modules conveniently executable.
1496 """
1497 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +00001498Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001499
1500Options:
1501 -h, --help Show this message
1502 -v, --verbose Verbose output
1503 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +00001504
1505Examples:
1506 %(progName)s - run default set of tests
1507 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001508 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1509 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +00001510 in MyTestCase
1511"""
1512 def __init__(self, module='__main__', defaultTest=None,
Guido van Rossumd8faa362007-04-27 19:54:29 +00001513 argv=None, testRunner=TextTestRunner,
1514 testLoader=defaultTestLoader):
Antoine Pitroue7bd8682009-01-09 19:29:16 +00001515 if isinstance(module, str):
Fred Drake02538202001-03-21 18:09:46 +00001516 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +00001517 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +00001518 self.module = getattr(self.module, part)
1519 else:
1520 self.module = module
1521 if argv is None:
1522 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001523 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +00001524 self.defaultTest = defaultTest
1525 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001526 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +00001527 self.progName = os.path.basename(argv[0])
1528 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +00001529 self.runTests()
1530
1531 def usageExit(self, msg=None):
Benjamin Peterson52baa292009-03-24 00:56:30 +00001532 if msg:
1533 print(msg)
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001534 print(self.USAGE % self.__dict__)
Fred Drake02538202001-03-21 18:09:46 +00001535 sys.exit(2)
1536
1537 def parseArgs(self, argv):
1538 import getopt
Benjamin Peterson5254c042009-03-23 22:25:03 +00001539 long_opts = ['help','verbose','quiet']
Fred Drake02538202001-03-21 18:09:46 +00001540 try:
Benjamin Peterson5254c042009-03-23 22:25:03 +00001541 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
Fred Drake02538202001-03-21 18:09:46 +00001542 for opt, value in options:
1543 if opt in ('-h','-H','--help'):
1544 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001545 if opt in ('-q','--quiet'):
1546 self.verbosity = 0
1547 if opt in ('-v','--verbose'):
1548 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +00001549 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001550 self.test = self.testLoader.loadTestsFromModule(self.module)
1551 return
Fred Drake02538202001-03-21 18:09:46 +00001552 if len(args) > 0:
1553 self.testNames = args
1554 else:
1555 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001556 self.createTests()
Guido van Rossumb940e112007-01-10 16:19:56 +00001557 except getopt.error as msg:
Fred Drake02538202001-03-21 18:09:46 +00001558 self.usageExit(msg)
1559
1560 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001561 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1562 self.module)
Fred Drake02538202001-03-21 18:09:46 +00001563
1564 def runTests(self):
Guido van Rossum13257902007-06-07 23:15:56 +00001565 if isinstance(self.testRunner, type):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001566 try:
1567 testRunner = self.testRunner(verbosity=self.verbosity)
1568 except TypeError:
1569 # didn't accept the verbosity argument
1570 testRunner = self.testRunner()
1571 else:
1572 # it is assumed to be a TestRunner instance
1573 testRunner = self.testRunner
1574 result = testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +00001575 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +00001576
1577main = TestProgram
1578
1579
1580##############################################################################
1581# Executing this module from the command line
1582##############################################################################
1583
1584if __name__ == "__main__":
1585 main(module=None)