blob: c355f8fcddf08a47c392fd969f072f9a968623d2 [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*'
Gregory P. Smith28399852009-03-31 16:54:10 +000017 self.assertEqual((1 + 2), 3)
18 self.assertEqual(0 + 1, 1)
Steve Purcell7b065702001-09-06 08:24:40 +000019 def testMultiply(self):
Gregory P. Smith28399852009-03-31 16:54:10 +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 Peterson4e4de332009-03-24 00:37:12 +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 Peterson4e4de332009-03-24 00:37:12 +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
Gregory P. Smith28399852009-03-31 16:54:10 +000048import difflib
Benjamin Peterson692428e2009-03-23 21:50:21 +000049import functools
Gregory P. Smith28399852009-03-31 16:54:10 +000050import os
51import pprint
52import re
53import sys
54import time
55import traceback
56import types
Gregory P. Smith65ff0052009-03-31 19:59:14 +000057import warnings
Fred Drake02538202001-03-21 18:09:46 +000058
59##############################################################################
Steve Purcelld75e7e42003-09-15 11:01:21 +000060# Exported classes and functions
61##############################################################################
Benjamin Petersonc750d4d2009-03-24 00:39:24 +000062__all__ = ['TestResult', 'TestCase', 'TestSuite', 'ClassTestSuite',
63 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
Benjamin Peterson03715482009-03-24 01:11:37 +000064 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
Benjamin Petersonc750d4d2009-03-24 00:39:24 +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##############################################################################
Steve Purcell7e743842003-09-22 11:08:12 +000072# Backward compatibility
73##############################################################################
Steve Purcell7e743842003-09-22 11:08:12 +000074
Raymond Hettinger5930d8f2008-07-10 16:06:41 +000075def _CmpToKey(mycmp):
76 'Convert a cmp= function into a key= function'
77 class K(object):
78 def __init__(self, obj):
79 self.obj = obj
80 def __lt__(self, other):
81 return mycmp(self.obj, other.obj) == -1
82 return K
Steve Purcell7e743842003-09-22 11:08:12 +000083
84##############################################################################
Fred Drake02538202001-03-21 18:09:46 +000085# Test framework core
86##############################################################################
87
Steve Purcelldc391a62002-08-09 09:46:23 +000088def _strclass(cls):
89 return "%s.%s" % (cls.__module__, cls.__name__)
90
Benjamin Peterson692428e2009-03-23 21:50:21 +000091
92class SkipTest(Exception):
93 """
94 Raise this exception in a test to skip it.
95
96 Usually you can use TestResult.skip() or one of the skipping decorators
97 instead of raising this directly.
98 """
99 pass
100
101class _ExpectedFailure(Exception):
102 """
103 Raise this when a test is expected to fail.
104
105 This is an implementation detail.
106 """
107
108 def __init__(self, exc_info):
109 super(_ExpectedFailure, self).__init__()
110 self.exc_info = exc_info
111
112class _UnexpectedSuccess(Exception):
113 """
114 The test was supposed to fail, but it didn't!
115 """
116 pass
117
118def _id(obj):
119 return obj
120
121def skip(reason):
122 """
123 Unconditionally skip a test.
124 """
125 def decorator(test_item):
126 if isinstance(test_item, type) and issubclass(test_item, TestCase):
127 test_item.__unittest_skip__ = True
128 test_item.__unittest_skip_why__ = reason
129 return test_item
130 @functools.wraps(test_item)
131 def skip_wrapper(*args, **kwargs):
132 raise SkipTest(reason)
133 return skip_wrapper
134 return decorator
135
136def skipIf(condition, reason):
137 """
138 Skip a test if the condition is true.
139 """
140 if condition:
141 return skip(reason)
142 return _id
143
144def skipUnless(condition, reason):
145 """
146 Skip a test unless the condition is true.
147 """
148 if not condition:
149 return skip(reason)
150 return _id
151
152
153def expectedFailure(func):
154 @functools.wraps(func)
155 def wrapper(*args, **kwargs):
156 try:
157 func(*args, **kwargs)
158 except Exception:
159 raise _ExpectedFailure(sys.exc_info())
160 raise _UnexpectedSuccess
161 return wrapper
162
163
Steve Purcellb8d5f242003-12-06 13:03:13 +0000164__unittest = 1
165
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000166class TestResult(object):
Fred Drake02538202001-03-21 18:09:46 +0000167 """Holder for test result information.
168
169 Test results are automatically managed by the TestCase and TestSuite
170 classes, and do not need to be explicitly manipulated by writers of tests.
171
172 Each instance holds the total number of tests run, and collections of
173 failures and errors that occurred among those test runs. The collections
Steve Purcell7b065702001-09-06 08:24:40 +0000174 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
Fred Drake656f9ec2001-09-06 19:13:14 +0000175 formatted traceback of the error that occurred.
Fred Drake02538202001-03-21 18:09:46 +0000176 """
177 def __init__(self):
178 self.failures = []
179 self.errors = []
180 self.testsRun = 0
Benjamin Peterson692428e2009-03-23 21:50:21 +0000181 self.skipped = []
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +0000182 self.expectedFailures = []
183 self.unexpectedSuccesses = []
Georg Brandl15c5ce92007-03-07 09:09:40 +0000184 self.shouldStop = False
Fred Drake02538202001-03-21 18:09:46 +0000185
186 def startTest(self, test):
187 "Called when the given test is about to be run"
188 self.testsRun = self.testsRun + 1
189
190 def stopTest(self, test):
191 "Called when the given test has been run"
192 pass
193
194 def addError(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000195 """Called when an error has occurred. 'err' is a tuple of values as
196 returned by sys.exc_info().
197 """
Steve Purcellb8d5f242003-12-06 13:03:13 +0000198 self.errors.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000199
200 def addFailure(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000201 """Called when an error has occurred. 'err' is a tuple of values as
202 returned by sys.exc_info()."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000203 self.failures.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000204
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000205 def addSuccess(self, test):
206 "Called when a test has completed successfully"
207 pass
208
Benjamin Peterson692428e2009-03-23 21:50:21 +0000209 def addSkip(self, test, reason):
210 """Called when a test is skipped."""
211 self.skipped.append((test, reason))
212
213 def addExpectedFailure(self, test, err):
214 """Called when an expected failure/error occured."""
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +0000215 self.expectedFailures.append(
Benjamin Peterson692428e2009-03-23 21:50:21 +0000216 (test, self._exc_info_to_string(err, test)))
217
218 def addUnexpectedSuccess(self, test):
219 """Called when a test was expected to fail, but succeed."""
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +0000220 self.unexpectedSuccesses.append(test)
Benjamin Peterson692428e2009-03-23 21:50:21 +0000221
Fred Drake02538202001-03-21 18:09:46 +0000222 def wasSuccessful(self):
223 "Tells whether or not this result was a success"
224 return len(self.failures) == len(self.errors) == 0
225
226 def stop(self):
227 "Indicates that the tests should be aborted"
Steve Purcell7e743842003-09-22 11:08:12 +0000228 self.shouldStop = True
Tim Petersa19a1682001-03-29 04:36:09 +0000229
Steve Purcellb8d5f242003-12-06 13:03:13 +0000230 def _exc_info_to_string(self, err, test):
Steve Purcell7b065702001-09-06 08:24:40 +0000231 """Converts a sys.exc_info()-style tuple of values into a string."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000232 exctype, value, tb = err
233 # Skip test runner traceback levels
234 while tb and self._is_relevant_tb_level(tb):
235 tb = tb.tb_next
236 if exctype is test.failureException:
237 # Skip assert*() traceback levels
238 length = self._count_relevant_tb_levels(tb)
239 return ''.join(traceback.format_exception(exctype, value, tb, length))
240 return ''.join(traceback.format_exception(exctype, value, tb))
241
242 def _is_relevant_tb_level(self, tb):
Georg Brandl56af5fc2008-07-18 19:30:10 +0000243 return '__unittest' in tb.tb_frame.f_globals
Steve Purcellb8d5f242003-12-06 13:03:13 +0000244
245 def _count_relevant_tb_levels(self, tb):
246 length = 0
247 while tb and not self._is_relevant_tb_level(tb):
248 length += 1
249 tb = tb.tb_next
250 return length
Steve Purcell7b065702001-09-06 08:24:40 +0000251
Fred Drake02538202001-03-21 18:09:46 +0000252 def __repr__(self):
253 return "<%s run=%i errors=%i failures=%i>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +0000254 (_strclass(self.__class__), self.testsRun, len(self.errors),
Fred Drake02538202001-03-21 18:09:46 +0000255 len(self.failures))
256
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000257
Gregory P. Smith28399852009-03-31 16:54:10 +0000258class _AssertRaisesContext(object):
259 """A context manager used to implement TestCase.assertRaises* methods."""
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000260
Gregory P. Smith28399852009-03-31 16:54:10 +0000261 def __init__(self, expected, test_case, expected_regexp=None):
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000262 self.expected = expected
263 self.failureException = test_case.failureException
Gregory P. Smith28399852009-03-31 16:54:10 +0000264 self.expected_regex = expected_regexp
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000265
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000266 def __enter__(self):
267 pass
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000268
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000269 def __exit__(self, exc_type, exc_value, traceback):
270 if exc_type is None:
271 try:
272 exc_name = self.expected.__name__
273 except AttributeError:
274 exc_name = str(self.expected)
275 raise self.failureException(
276 "{0} not raised".format(exc_name))
Gregory P. Smith28399852009-03-31 16:54:10 +0000277 if not issubclass(exc_type, self.expected):
278 # let unexpexted exceptions pass through
279 return False
280 if self.expected_regex is None:
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000281 return True
Gregory P. Smith28399852009-03-31 16:54:10 +0000282
283 expected_regexp = self.expected_regex
284 if isinstance(expected_regexp, basestring):
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
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000291
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000292
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000293class TestCase(object):
Fred Drake02538202001-03-21 18:09:46 +0000294 """A class whose instances are single test cases.
295
Fred Drake02538202001-03-21 18:09:46 +0000296 By default, the test code itself should be placed in a method named
297 'runTest'.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000298
Tim Petersa19a1682001-03-29 04:36:09 +0000299 If the fixture may be used for many test cases, create as
Fred Drake02538202001-03-21 18:09:46 +0000300 many test methods as are needed. When instantiating such a TestCase
301 subclass, specify in the constructor arguments the name of the test method
302 that the instance is to execute.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000303
Tim Petersa19a1682001-03-29 04:36:09 +0000304 Test authors should subclass TestCase for their own tests. Construction
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000305 and deconstruction of the test's environment ('fixture') can be
306 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
307
308 If it is necessary to override the __init__ method, the base class
309 __init__ method must always be called. It is important that subclasses
310 should not change the signature of their __init__ method, since instances
311 of the classes are instantiated automatically by parts of the framework
312 in order to be run.
Fred Drake02538202001-03-21 18:09:46 +0000313 """
Steve Purcell15d89272001-04-12 09:05:01 +0000314
315 # This attribute determines which exception will be raised when
316 # the instance's assertion methods fail; test methods raising this
317 # exception will be deemed to have 'failed' rather than 'errored'
318
319 failureException = AssertionError
320
Fred Drake02538202001-03-21 18:09:46 +0000321 def __init__(self, methodName='runTest'):
322 """Create an instance of the class that will use the named test
323 method when executed. Raises a ValueError if the instance does
324 not have a method with the specified name.
325 """
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000326 self._testMethodName = methodName
Fred Drake02538202001-03-21 18:09:46 +0000327 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000328 testMethod = getattr(self, methodName)
Fred Drake02538202001-03-21 18:09:46 +0000329 except AttributeError:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000330 raise ValueError("no such test method in %s: %s" % \
331 (self.__class__, methodName))
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000332 self._testMethodDoc = testMethod.__doc__
Fred Drake02538202001-03-21 18:09:46 +0000333
Gregory P. Smith28399852009-03-31 16:54:10 +0000334 # Map types to custom assertEqual functions that will compare
335 # instances of said type in more detail to generate a more useful
336 # error message.
Benjamin Peterson71095ae2009-04-01 23:15:49 +0000337 self._type_equality_funcs = {}
Gregory P. Smith28399852009-03-31 16:54:10 +0000338 self.addTypeEqualityFunc(dict, self.assertDictEqual)
339 self.addTypeEqualityFunc(list, self.assertListEqual)
340 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
341 self.addTypeEqualityFunc(set, self.assertSetEqual)
342 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
343
344 def addTypeEqualityFunc(self, typeobj, function):
345 """Add a type specific assertEqual style function to compare a type.
346
347 This method is for use by TestCase subclasses that need to register
348 their own type equality functions to provide nicer error messages.
349
350 Args:
351 typeobj: The data type to call this function on when both values
352 are of the same type in assertEqual().
353 function: The callable taking two arguments and an optional
354 msg= argument that raises self.failureException with a
355 useful error message when the two arguments are not equal.
356 """
Benjamin Peterson71095ae2009-04-01 23:15:49 +0000357 self._type_equality_funcs[typeobj] = function
Gregory P. Smith28399852009-03-31 16:54:10 +0000358
Fred Drake02538202001-03-21 18:09:46 +0000359 def setUp(self):
360 "Hook method for setting up the test fixture before exercising it."
361 pass
362
363 def tearDown(self):
364 "Hook method for deconstructing the test fixture after testing it."
365 pass
366
367 def countTestCases(self):
368 return 1
369
370 def defaultTestResult(self):
371 return TestResult()
372
373 def shortDescription(self):
Gregory P. Smith28399852009-03-31 16:54:10 +0000374 """Returns both the test method name and first line of its docstring.
Fred Drake02538202001-03-21 18:09:46 +0000375
Gregory P. Smith28399852009-03-31 16:54:10 +0000376 If no docstring is given, only returns the method name.
377
378 This method overrides unittest.TestCase.shortDescription(), which
379 only returns the first line of the docstring, obscuring the name
380 of the test upon failure.
Fred Drake02538202001-03-21 18:09:46 +0000381 """
Gregory P. Smith28399852009-03-31 16:54:10 +0000382 desc = str(self)
383 doc_first_line = None
384
385 if self._testMethodDoc:
386 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
387 if doc_first_line:
388 desc = '\n'.join((desc, doc_first_line))
389 return desc
Fred Drake02538202001-03-21 18:09:46 +0000390
391 def id(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000392 return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000393
Georg Brandl15c5ce92007-03-07 09:09:40 +0000394 def __eq__(self, other):
395 if type(self) is not type(other):
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000396 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +0000397
398 return self._testMethodName == other._testMethodName
399
400 def __ne__(self, other):
401 return not self == other
402
403 def __hash__(self):
Collin Winter9453e5d2007-03-09 23:30:39 +0000404 return hash((type(self), self._testMethodName))
Georg Brandl15c5ce92007-03-07 09:09:40 +0000405
Fred Drake02538202001-03-21 18:09:46 +0000406 def __str__(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000407 return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
Fred Drake02538202001-03-21 18:09:46 +0000408
409 def __repr__(self):
410 return "<%s testMethod=%s>" % \
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000411 (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000412
413 def run(self, result=None):
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000414 if result is None:
415 result = self.defaultTestResult()
Fred Drake02538202001-03-21 18:09:46 +0000416 result.startTest(self)
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000417 testMethod = getattr(self, self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000418 try:
419 try:
420 self.setUp()
Benjamin Peterson692428e2009-03-23 21:50:21 +0000421 except SkipTest as e:
422 result.addSkip(self, str(e))
423 return
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000424 except Exception:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000425 result.addError(self, sys.exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000426 return
427
Benjamin Peterson692428e2009-03-23 21:50:21 +0000428 success = False
Fred Drake02538202001-03-21 18:09:46 +0000429 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000430 testMethod()
Skip Montanaroae5c37b2003-07-13 15:18:12 +0000431 except self.failureException:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000432 result.addFailure(self, sys.exc_info())
Benjamin Peterson692428e2009-03-23 21:50:21 +0000433 except _ExpectedFailure as e:
434 result.addExpectedFailure(self, e.exc_info)
435 except _UnexpectedSuccess:
436 result.addUnexpectedSuccess(self)
437 except SkipTest as e:
438 result.addSkip(self, str(e))
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000439 except Exception:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000440 result.addError(self, sys.exc_info())
Benjamin Peterson692428e2009-03-23 21:50:21 +0000441 else:
442 success = True
Fred Drake02538202001-03-21 18:09:46 +0000443
444 try:
445 self.tearDown()
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000446 except Exception:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000447 result.addError(self, sys.exc_info())
Benjamin Peterson692428e2009-03-23 21:50:21 +0000448 success = False
449 if success:
450 result.addSuccess(self)
Fred Drake02538202001-03-21 18:09:46 +0000451 finally:
452 result.stopTest(self)
453
Raymond Hettinger664347b2004-12-04 21:21:53 +0000454 def __call__(self, *args, **kwds):
455 return self.run(*args, **kwds)
Steve Purcell7e743842003-09-22 11:08:12 +0000456
Fred Drake02538202001-03-21 18:09:46 +0000457 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000458 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000459 self.setUp()
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000460 getattr(self, self._testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000461 self.tearDown()
462
Benjamin Peterson47d97382009-03-26 20:05:50 +0000463 def skipTest(self, reason):
Benjamin Peterson692428e2009-03-23 21:50:21 +0000464 """Skip this test."""
465 raise SkipTest(reason)
466
Steve Purcell15d89272001-04-12 09:05:01 +0000467 def fail(self, msg=None):
468 """Fail immediately, with the given message."""
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000469 raise self.failureException(msg)
Fred Drake02538202001-03-21 18:09:46 +0000470
Gregory P. Smith7558d572009-03-31 19:03:28 +0000471 def assertFalse(self, expr, msg=None):
Fred Drake02538202001-03-21 18:09:46 +0000472 "Fail the test if the expression is true."
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000473 if expr:
474 raise self.failureException(msg)
Fred Drake02538202001-03-21 18:09:46 +0000475
Gregory P. Smith7558d572009-03-31 19:03:28 +0000476 def assertTrue(self, expr, msg=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000477 """Fail the test unless the expression is true."""
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000478 if not expr:
479 raise self.failureException(msg)
Steve Purcell15d89272001-04-12 09:05:01 +0000480
Gregory P. Smith7558d572009-03-31 19:03:28 +0000481 def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
Steve Purcell15d89272001-04-12 09:05:01 +0000482 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000483 by callableObj when invoked with arguments args and keyword
484 arguments kwargs. If a different type of exception is
485 thrown, it will not be caught, and the test case will be
486 deemed to have suffered an error, exactly as for an
487 unexpected exception.
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000488
489 If called with callableObj omitted or None, will return a
490 context object used like this::
491
Gregory P. Smith7558d572009-03-31 19:03:28 +0000492 with self.assertRaises(some_error_class):
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000493 do_something()
Fred Drake02538202001-03-21 18:09:46 +0000494 """
Gregory P. Smith28399852009-03-31 16:54:10 +0000495 context = _AssertRaisesContext(excClass, self)
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000496 if callableObj is None:
497 return context
498 with context:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000499 callableObj(*args, **kwargs)
Fred Drake02538202001-03-21 18:09:46 +0000500
Gregory P. Smith28399852009-03-31 16:54:10 +0000501 def _getAssertEqualityFunc(self, first, second):
502 """Get a detailed comparison function for the types of the two args.
503
504 Returns: A callable accepting (first, second, msg=None) that will
505 raise a failure exception if first != second with a useful human
506 readable error message for those types.
507 """
508 #
509 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
510 # and vice versa. I opted for the conservative approach in case
511 # subclasses are not intended to be compared in detail to their super
512 # class instances using a type equality func. This means testing
513 # subtypes won't automagically use the detailed comparison. Callers
514 # should use their type specific assertSpamEqual method to compare
515 # subclasses if the detailed comparison is desired and appropriate.
516 # See the discussion in http://bugs.python.org/issue2578.
517 #
518 if type(first) is type(second):
Benjamin Peterson71095ae2009-04-01 23:15:49 +0000519 return self._type_equality_funcs.get(type(first),
520 self._baseAssertEqual)
Gregory P. Smith28399852009-03-31 16:54:10 +0000521 return self._baseAssertEqual
522
523 def _baseAssertEqual(self, first, second, msg=None):
524 """The default assertEqual implementation, not type specific."""
525 if not first == second:
526 raise self.failureException(msg or '%r != %r' % (first, second))
527
Gregory P. Smith7558d572009-03-31 19:03:28 +0000528 def assertEqual(self, first, second, msg=None):
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000529 """Fail if the two objects are unequal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000530 operator.
531 """
Gregory P. Smith28399852009-03-31 16:54:10 +0000532 assertion_func = self._getAssertEqualityFunc(first, second)
533 assertion_func(first, second, msg=msg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000534
Gregory P. Smith7558d572009-03-31 19:03:28 +0000535 def assertNotEqual(self, first, second, msg=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000536 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000537 operator.
538 """
Steve Purcell15d89272001-04-12 09:05:01 +0000539 if first == second:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000540 raise self.failureException(msg or '%r == %r' % (first, second))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000541
Gregory P. Smith7558d572009-03-31 19:03:28 +0000542 def assertAlmostEqual(self, first, second, places=7, msg=None):
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000543 """Fail if the two objects are unequal as determined by their
544 difference rounded to the given number of decimal places
545 (default 7) and comparing to zero.
546
Steve Purcell397b45d2003-10-26 10:41:03 +0000547 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000548 as significant digits (measured from the most signficant digit).
549 """
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000550 if round(abs(second-first), places) != 0:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000551 raise self.failureException(
552 msg or '%r != %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000553
Gregory P. Smith7558d572009-03-31 19:03:28 +0000554 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000555 """Fail if the two objects are equal as determined by their
556 difference rounded to the given number of decimal places
557 (default 7) and comparing to zero.
558
Steve Purcellcca34912003-10-26 16:38:16 +0000559 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000560 as significant digits (measured from the most signficant digit).
561 """
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000562 if round(abs(second-first), places) == 0:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000563 raise self.failureException(
564 msg or '%r == %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000565
Steve Purcell7e743842003-09-22 11:08:12 +0000566 # Synonyms for assertion methods
567
Gregory P. Smith7558d572009-03-31 19:03:28 +0000568 # The plurals are undocumented. Keep them that way to discourage use.
569 # Do not add more. Do not remove.
570 # Going through a deprecation cycle on these would annoy many people.
571 assertEquals = assertEqual
572 assertNotEquals = assertNotEqual
573 assertAlmostEquals = assertAlmostEqual
574 assertNotAlmostEquals = assertNotAlmostEqual
575 assert_ = assertTrue
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000576
Gregory P. Smith7558d572009-03-31 19:03:28 +0000577 # These fail* assertion method names are pending deprecation and will
Gregory P. Smith65ff0052009-03-31 19:59:14 +0000578 # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
Benjamin Peterson71095ae2009-04-01 23:15:49 +0000579 def _deprecate(original_func):
Gregory P. Smith65ff0052009-03-31 19:59:14 +0000580 def deprecated_func(*args, **kwargs):
581 warnings.warn(
582 'Please use {0} instead.'.format(original_func.__name__),
583 PendingDeprecationWarning, 2)
584 return original_func(*args, **kwargs)
585 return deprecated_func
Steve Purcell15d89272001-04-12 09:05:01 +0000586
Benjamin Peterson71095ae2009-04-01 23:15:49 +0000587 failUnlessEqual = _deprecate(assertEqual)
588 failIfEqual = _deprecate(assertNotEqual)
589 failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
590 failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
591 failUnless = _deprecate(assertTrue)
592 failUnlessRaises = _deprecate(assertRaises)
593 failIf = _deprecate(assertFalse)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000594
Gregory P. Smith28399852009-03-31 16:54:10 +0000595 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
596 """An equality assertion for ordered sequences (like lists and tuples).
597
598 For the purposes of this function, a valid orderd sequence type is one
599 which can be indexed, has a length, and has an equality operator.
600
601 Args:
602 seq1: The first sequence to compare.
603 seq2: The second sequence to compare.
604 seq_type: The expected datatype of the sequences, or None if no
605 datatype should be enforced.
606 msg: Optional message to use on failure instead of a list of
607 differences.
608 """
609 if seq_type != None:
610 seq_type_name = seq_type.__name__
611 if not isinstance(seq1, seq_type):
612 raise self.failureException('First sequence is not a %s: %r'
613 % (seq_type_name, seq1))
614 if not isinstance(seq2, seq_type):
615 raise self.failureException('Second sequence is not a %s: %r'
616 % (seq_type_name, seq2))
617 else:
618 seq_type_name = "sequence"
619
620 differing = None
621 try:
622 len1 = len(seq1)
623 except (TypeError, NotImplementedError):
624 differing = 'First %s has no length. Non-sequence?' % (
625 seq_type_name)
626
627 if differing is None:
628 try:
629 len2 = len(seq2)
630 except (TypeError, NotImplementedError):
631 differing = 'Second %s has no length. Non-sequence?' % (
632 seq_type_name)
633
634 if differing is None:
635 if seq1 == seq2:
636 return
637
638 for i in xrange(min(len1, len2)):
639 try:
640 item1 = seq1[i]
641 except (TypeError, IndexError, NotImplementedError):
642 differing = ('Unable to index element %d of first %s\n' %
643 (i, seq_type_name))
644 break
645
646 try:
647 item2 = seq2[i]
648 except (TypeError, IndexError, NotImplementedError):
649 differing = ('Unable to index element %d of second %s\n' %
650 (i, seq_type_name))
651 break
652
653 if item1 != item2:
654 differing = ('First differing element %d:\n%s\n%s\n' %
655 (i, item1, item2))
656 break
657 else:
658 if (len1 == len2 and seq_type is None and
659 type(seq1) != type(seq2)):
660 # The sequences are the same, but have differing types.
661 return
662 # A catch-all message for handling arbitrary user-defined
663 # sequences.
664 differing = '%ss differ:\n' % seq_type_name.capitalize()
665 if len1 > len2:
666 differing = ('First %s contains %d additional '
667 'elements.\n' % (seq_type_name, len1 - len2))
668 try:
669 differing += ('First extra element %d:\n%s\n' %
670 (len2, seq1[len2]))
671 except (TypeError, IndexError, NotImplementedError):
672 differing += ('Unable to index element %d '
673 'of first %s\n' % (len2, seq_type_name))
674 elif len1 < len2:
675 differing = ('Second %s contains %d additional '
676 'elements.\n' % (seq_type_name, len2 - len1))
677 try:
678 differing += ('First extra element %d:\n%s\n' %
679 (len1, seq2[len1]))
680 except (TypeError, IndexError, NotImplementedError):
681 differing += ('Unable to index element %d '
682 'of second %s\n' % (len1, seq_type_name))
683 if not msg:
684 msg = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(),
685 pprint.pformat(seq2).splitlines()))
686 self.fail(differing + msg)
687
688 def assertListEqual(self, list1, list2, msg=None):
689 """A list-specific equality assertion.
690
691 Args:
692 list1: The first list to compare.
693 list2: The second list to compare.
694 msg: Optional message to use on failure instead of a list of
695 differences.
696
697 """
698 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
699
700 def assertTupleEqual(self, tuple1, tuple2, msg=None):
701 """A tuple-specific equality assertion.
702
703 Args:
704 tuple1: The first tuple to compare.
705 tuple2: The second tuple to compare.
706 msg: Optional message to use on failure instead of a list of
707 differences.
708 """
709 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
710
711 def assertSetEqual(self, set1, set2, msg=None):
712 """A set-specific equality assertion.
713
714 Args:
715 set1: The first set to compare.
716 set2: The second set to compare.
717 msg: Optional message to use on failure instead of a list of
718 differences.
719
720 For more general containership equality, assertSameElements will work
721 with things other than sets. This uses ducktyping to support
722 different types of sets, and is optimized for sets specifically
723 (parameters must support a difference method).
724 """
725 try:
726 difference1 = set1.difference(set2)
727 except TypeError, e:
728 self.fail('invalid type when attempting set difference: %s' % e)
729 except AttributeError, e:
730 self.fail('first argument does not support set difference: %s' % e)
731
732 try:
733 difference2 = set2.difference(set1)
734 except TypeError, e:
735 self.fail('invalid type when attempting set difference: %s' % e)
736 except AttributeError, e:
737 self.fail('second argument does not support set difference: %s' % e)
738
739 if not (difference1 or difference2):
740 return
741
742 if msg is not None:
743 self.fail(msg)
744
745 lines = []
746 if difference1:
747 lines.append('Items in the first set but not the second:')
748 for item in difference1:
749 lines.append(repr(item))
750 if difference2:
751 lines.append('Items in the second set but not the first:')
752 for item in difference2:
753 lines.append(repr(item))
754 self.fail('\n'.join(lines))
755
756 def assertIn(self, a, b, msg=None):
757 """Just like self.assert_(a in b), but with a nicer default message."""
758 if msg is None:
759 msg = '"%s" not found in "%s"' % (a, b)
760 self.assert_(a in b, msg)
761
762 def assertNotIn(self, a, b, msg=None):
763 """Just like self.assert_(a not in b), but with a nicer default message."""
764 if msg is None:
765 msg = '"%s" unexpectedly found in "%s"' % (a, b)
766 self.assert_(a not in b, msg)
767
768 def assertDictEqual(self, d1, d2, msg=None):
769 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
770 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
771
772 if d1 != d2:
773 self.fail(msg or ('\n' + '\n'.join(difflib.ndiff(
774 pprint.pformat(d1).splitlines(),
775 pprint.pformat(d2).splitlines()))))
776
777 def assertDictContainsSubset(self, expected, actual, msg=None):
778 """Checks whether actual is a superset of expected."""
779 missing = []
780 mismatched = []
781 for key, value in expected.iteritems():
782 if key not in actual:
783 missing.append(key)
784 elif value != actual[key]:
785 mismatched.append('%s, expected: %s, actual: %s' % (key, value,
786 actual[key]))
787
788 if not (missing or mismatched):
789 return
790
791 missing_msg = mismatched_msg = ''
792 if missing:
793 missing_msg = 'Missing: %s' % ','.join(missing)
794 if mismatched:
795 mismatched_msg = 'Mismatched values: %s' % ','.join(mismatched)
796
797 if msg:
798 msg = '%s: %s; %s' % (msg, missing_msg, mismatched_msg)
799 else:
800 msg = '%s; %s' % (missing_msg, mismatched_msg)
801 self.fail(msg)
802
803 def assertSameElements(self, expected_seq, actual_seq, msg=None):
804 """An unordered sequence specific comparison.
805
806 Raises with an error message listing which elements of expected_seq
807 are missing from actual_seq and vice versa if any.
808 """
809 try:
810 expected = set(expected_seq)
811 actual = set(actual_seq)
812 missing = list(expected.difference(actual))
813 unexpected = list(actual.difference(expected))
814 missing.sort()
815 unexpected.sort()
816 except TypeError:
817 # Fall back to slower list-compare if any of the objects are
818 # not hashable.
819 expected = list(expected_seq)
820 actual = list(actual_seq)
821 expected.sort()
822 actual.sort()
823 missing, unexpected = _SortedListDifference(expected, actual)
824 errors = []
825 if missing:
826 errors.append('Expected, but missing:\n %r\n' % missing)
827 if unexpected:
828 errors.append('Unexpected, but present:\n %r\n' % unexpected)
829 if errors:
830 self.fail(msg or ''.join(errors))
831
832 def assertMultiLineEqual(self, first, second, msg=None):
833 """Assert that two multi-line strings are equal."""
834 self.assert_(isinstance(first, types.StringTypes), (
835 'First argument is not a string'))
836 self.assert_(isinstance(second, types.StringTypes), (
837 'Second argument is not a string'))
838
839 if first != second:
840 raise self.failureException(
841 msg or '\n' + ''.join(difflib.ndiff(first.splitlines(True),
842 second.splitlines(True))))
843
844 def assertLess(self, a, b, msg=None):
845 """Just like self.assert_(a < b), but with a nicer default message."""
846 if msg is None:
847 msg = '"%r" unexpectedly not less than "%r"' % (a, b)
848 self.assert_(a < b, msg)
849
850 def assertLessEqual(self, a, b, msg=None):
851 """Just like self.assert_(a <= b), but with a nicer default message."""
852 if msg is None:
853 msg = '"%r" unexpectedly not less than or equal to "%r"' % (a, b)
854 self.assert_(a <= b, msg)
855
856 def assertGreater(self, a, b, msg=None):
857 """Just like self.assert_(a > b), but with a nicer default message."""
858 if msg is None:
859 msg = '"%r" unexpectedly not greater than "%r"' % (a, b)
860 self.assert_(a > b, msg)
861
862 def assertGreaterEqual(self, a, b, msg=None):
863 """Just like self.assert_(a >= b), but with a nicer default message."""
864 if msg is None:
865 msg = '"%r" unexpectedly not greater than or equal to "%r"' % (a, b)
866 self.assert_(a >= b, msg)
867
868 def assertIsNone(self, obj, msg=None):
869 """Same as self.assert_(obj is None), with a nicer default message."""
870 if msg is None:
871 msg = '"%s" unexpectedly not None' % obj
872 self.assert_(obj is None, msg)
873
874 def assertIsNotNone(self, obj, msg='unexpectedly None'):
875 """Included for symmetry with assertIsNone."""
876 self.assert_(obj is not None, msg)
877
878 def assertRaisesRegexp(self, expected_exception, expected_regexp,
879 callable_obj=None, *args, **kwargs):
880 """Asserts that the message in a raised exception matches a regexp.
881
882 Args:
883 expected_exception: Exception class expected to be raised.
884 expected_regexp: Regexp (re pattern object or string) expected
885 to be found in error message.
886 callable_obj: Function to be called.
887 args: Extra args.
888 kwargs: Extra kwargs.
889 """
890 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
891 if callable_obj is None:
892 return context
893 with context:
894 callable_obj(*args, **kwargs)
895
896 def assertRegexpMatches(self, text, expected_regex, msg=None):
897 if isinstance(expected_regex, basestring):
898 expected_regex = re.compile(expected_regex)
899 if not expected_regex.search(text):
900 msg = msg or "Regexp didn't match"
901 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
902 raise self.failureException(msg)
903
904
905def _SortedListDifference(expected, actual):
906 """Finds elements in only one or the other of two, sorted input lists.
907
908 Returns a two-element tuple of lists. The first list contains those
909 elements in the "expected" list but not in the "actual" list, and the
910 second contains those elements in the "actual" list but not in the
911 "expected" list. Duplicate elements in either input list are ignored.
912 """
913 i = j = 0
914 missing = []
915 unexpected = []
916 while True:
917 try:
918 e = expected[i]
919 a = actual[j]
920 if e < a:
921 missing.append(e)
922 i += 1
923 while expected[i] == e:
924 i += 1
925 elif e > a:
926 unexpected.append(a)
927 j += 1
928 while actual[j] == a:
929 j += 1
930 else:
931 i += 1
932 try:
933 while expected[i] == e:
934 i += 1
935 finally:
936 j += 1
937 while actual[j] == a:
938 j += 1
939 except IndexError:
940 missing.extend(expected[i:])
941 unexpected.extend(actual[j:])
942 break
943 return missing, unexpected
944
Fred Drake02538202001-03-21 18:09:46 +0000945
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000946class TestSuite(object):
Fred Drake02538202001-03-21 18:09:46 +0000947 """A test suite is a composite test consisting of a number of TestCases.
948
949 For use, create an instance of TestSuite, then add test case instances.
950 When all tests have been added, the suite can be passed to a test
951 runner, such as TextTestRunner. It will run the individual test cases
952 in the order in which they were added, aggregating the results. When
953 subclassing, do not forget to call the base class constructor.
954 """
955 def __init__(self, tests=()):
956 self._tests = []
957 self.addTests(tests)
958
959 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000960 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +0000961
Georg Brandl15c5ce92007-03-07 09:09:40 +0000962 def __eq__(self, other):
Benjamin Peterson692428e2009-03-23 21:50:21 +0000963 if not isinstance(other, self.__class__):
964 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +0000965 return self._tests == other._tests
966
967 def __ne__(self, other):
968 return not self == other
969
Nick Coghlan48361f52008-08-11 15:45:58 +0000970 # Can't guarantee hash invariant, so flag as unhashable
971 __hash__ = None
972
Jim Fultonfafd8742004-08-28 15:22:12 +0000973 def __iter__(self):
974 return iter(self._tests)
975
Fred Drake02538202001-03-21 18:09:46 +0000976 def countTestCases(self):
977 cases = 0
978 for test in self._tests:
Steve Purcell7e743842003-09-22 11:08:12 +0000979 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +0000980 return cases
981
982 def addTest(self, test):
Georg Brandld9e50262007-03-07 11:54:49 +0000983 # sanity checks
Raymond Hettinger5930d8f2008-07-10 16:06:41 +0000984 if not hasattr(test, '__call__'):
Georg Brandld9e50262007-03-07 11:54:49 +0000985 raise TypeError("the test to add must be callable")
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000986 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
Georg Brandld9e50262007-03-07 11:54:49 +0000987 raise TypeError("TestCases and TestSuites must be instantiated "
988 "before passing them to addTest()")
Fred Drake02538202001-03-21 18:09:46 +0000989 self._tests.append(test)
990
991 def addTests(self, tests):
Georg Brandld9e50262007-03-07 11:54:49 +0000992 if isinstance(tests, basestring):
993 raise TypeError("tests must be an iterable of tests, not a string")
Fred Drake02538202001-03-21 18:09:46 +0000994 for test in tests:
995 self.addTest(test)
996
997 def run(self, result):
Fred Drake02538202001-03-21 18:09:46 +0000998 for test in self._tests:
999 if result.shouldStop:
1000 break
1001 test(result)
1002 return result
1003
Raymond Hettinger664347b2004-12-04 21:21:53 +00001004 def __call__(self, *args, **kwds):
1005 return self.run(*args, **kwds)
1006
Fred Drake02538202001-03-21 18:09:46 +00001007 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001008 """Run the tests without collecting errors in a TestResult"""
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001009 for test in self._tests:
1010 test.debug()
Fred Drake02538202001-03-21 18:09:46 +00001011
1012
Benjamin Peterson692428e2009-03-23 21:50:21 +00001013class ClassTestSuite(TestSuite):
1014 """
1015 Suite of tests derived from a single TestCase class.
1016 """
1017
1018 def __init__(self, tests, class_collected_from):
1019 super(ClassTestSuite, self).__init__(tests)
1020 self.collected_from = class_collected_from
1021
1022 def id(self):
1023 module = getattr(self.collected_from, "__module__", None)
1024 if module is not None:
1025 return "{0}.{1}".format(module, self.collected_from.__name__)
1026 return self.collected_from.__name__
1027
1028 def run(self, result):
1029 if getattr(self.collected_from, "__unittest_skip__", False):
1030 # ClassTestSuite result pretends to be a TestCase enough to be
1031 # reported.
1032 result.startTest(self)
1033 try:
1034 result.addSkip(self, self.collected_from.__unittest_skip_why__)
1035 finally:
1036 result.stopTest(self)
1037 else:
1038 result = super(ClassTestSuite, self).run(result)
1039 return result
1040
1041 shortDescription = id
1042
1043
Fred Drake02538202001-03-21 18:09:46 +00001044class FunctionTestCase(TestCase):
1045 """A test case that wraps a test function.
1046
1047 This is useful for slipping pre-existing test functions into the
Georg Brandl15c5ce92007-03-07 09:09:40 +00001048 unittest framework. Optionally, set-up and tidy-up functions can be
Fred Drake02538202001-03-21 18:09:46 +00001049 supplied. As with TestCase, the tidy-up ('tearDown') function will
1050 always be called if the set-up ('setUp') function ran successfully.
1051 """
1052
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001053 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1054 super(FunctionTestCase, self).__init__()
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001055 self._setUpFunc = setUp
1056 self._tearDownFunc = tearDown
1057 self._testFunc = testFunc
1058 self._description = description
Fred Drake02538202001-03-21 18:09:46 +00001059
1060 def setUp(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001061 if self._setUpFunc is not None:
1062 self._setUpFunc()
Fred Drake02538202001-03-21 18:09:46 +00001063
1064 def tearDown(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001065 if self._tearDownFunc is not None:
1066 self._tearDownFunc()
Fred Drake02538202001-03-21 18:09:46 +00001067
1068 def runTest(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001069 self._testFunc()
Fred Drake02538202001-03-21 18:09:46 +00001070
1071 def id(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001072 return self._testFunc.__name__
Fred Drake02538202001-03-21 18:09:46 +00001073
Georg Brandl15c5ce92007-03-07 09:09:40 +00001074 def __eq__(self, other):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001075 if not isinstance(other, self.__class__):
1076 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +00001077
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001078 return self._setUpFunc == other._setUpFunc and \
1079 self._tearDownFunc == other._tearDownFunc and \
1080 self._testFunc == other._testFunc and \
1081 self._description == other._description
Georg Brandl15c5ce92007-03-07 09:09:40 +00001082
1083 def __ne__(self, other):
1084 return not self == other
1085
1086 def __hash__(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001087 return hash((type(self), self._setUpFunc, self._tearDownFunc,
1088 self._testFunc, self._description))
Georg Brandl15c5ce92007-03-07 09:09:40 +00001089
Fred Drake02538202001-03-21 18:09:46 +00001090 def __str__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +00001091 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +00001092
1093 def __repr__(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001094 return "<%s testFunc=%s>" % (_strclass(self.__class__), self._testFunc)
Fred Drake02538202001-03-21 18:09:46 +00001095
1096 def shortDescription(self):
Benjamin Peterson71095ae2009-04-01 23:15:49 +00001097 if self._description is not None:
1098 return self._description
1099 doc = self._testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +00001100 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +00001101
1102
1103
1104##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001105# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +00001106##############################################################################
1107
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001108class TestLoader(object):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001109 """
1110 This class is responsible for loading tests according to various criteria
1111 and returning them wrapped in a TestSuite
Fred Drake02538202001-03-21 18:09:46 +00001112 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001113 testMethodPrefix = 'test'
1114 sortTestMethodsUsing = cmp
1115 suiteClass = TestSuite
Benjamin Peterson692428e2009-03-23 21:50:21 +00001116 classSuiteClass = ClassTestSuite
Fred Drake02538202001-03-21 18:09:46 +00001117
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001118 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001119 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +00001120 if issubclass(testCaseClass, TestSuite):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001121 raise TypeError("Test cases should not be derived from TestSuite." \
1122 " Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +00001123 testCaseNames = self.getTestCaseNames(testCaseClass)
1124 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1125 testCaseNames = ['runTest']
Benjamin Peterson692428e2009-03-23 21:50:21 +00001126 suite = self.classSuiteClass(map(testCaseClass, testCaseNames),
1127 testCaseClass)
1128 return suite
Fred Drake02538202001-03-21 18:09:46 +00001129
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001130 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +00001131 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001132 tests = []
1133 for name in dir(module):
1134 obj = getattr(module, name)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001135 if isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001136 tests.append(self.loadTestsFromTestCase(obj))
1137 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +00001138
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001139 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001140 """Return a suite of all tests cases given a string specifier.
1141
1142 The name may resolve either to a module, a test case class, a
1143 test method within a test case class, or a callable object which
1144 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +00001145
Steve Purcell15d89272001-04-12 09:05:01 +00001146 The method optionally resolves the names relative to a given module.
1147 """
Steve Purcell7e743842003-09-22 11:08:12 +00001148 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001149 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +00001150 parts_copy = parts[:]
1151 while parts_copy:
1152 try:
1153 module = __import__('.'.join(parts_copy))
1154 break
1155 except ImportError:
1156 del parts_copy[-1]
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001157 if not parts_copy:
1158 raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +00001159 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001160 obj = module
1161 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +00001162 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +00001163
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001164 if isinstance(obj, types.ModuleType):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001165 return self.loadTestsFromModule(obj)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001166 elif isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001167 return self.loadTestsFromTestCase(obj)
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001168 elif (isinstance(obj, types.UnboundMethodType) and
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001169 isinstance(parent, type) and
Georg Brandl15c5ce92007-03-07 09:09:40 +00001170 issubclass(parent, TestCase)):
1171 return TestSuite([parent(obj.__name__)])
Steve Purcell397b45d2003-10-26 10:41:03 +00001172 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +00001173 return obj
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001174 elif hasattr(obj, '__call__'):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001175 test = obj()
Georg Brandl15c5ce92007-03-07 09:09:40 +00001176 if isinstance(test, TestSuite):
1177 return test
1178 elif isinstance(test, TestCase):
1179 return TestSuite([test])
1180 else:
1181 raise TypeError("calling %s returned %s, not a test" %
1182 (obj, test))
Fred Drake02538202001-03-21 18:09:46 +00001183 else:
Georg Brandl15c5ce92007-03-07 09:09:40 +00001184 raise TypeError("don't know how to make test from: %s" % obj)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001185
1186 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001187 """Return a suite of all tests cases found using the given sequence
1188 of string specifiers. See 'loadTestsFromName()'.
1189 """
Steve Purcell7e743842003-09-22 11:08:12 +00001190 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001191 return self.suiteClass(suites)
1192
1193 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001194 """Return a sorted sequence of method names found within testCaseClass
1195 """
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001196 def isTestMethod(attrname, testCaseClass=testCaseClass,
1197 prefix=self.testMethodPrefix):
1198 return attrname.startswith(prefix) and \
1199 hasattr(getattr(testCaseClass, attrname), '__call__')
Steve Purcell7e743842003-09-22 11:08:12 +00001200 testFnNames = filter(isTestMethod, dir(testCaseClass))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001201 if self.sortTestMethodsUsing:
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001202 testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001203 return testFnNames
1204
1205
1206
1207defaultTestLoader = TestLoader()
1208
1209
1210##############################################################################
1211# Patches for old functions: these functions should be considered obsolete
1212##############################################################################
1213
1214def _makeLoader(prefix, sortUsing, suiteClass=None):
1215 loader = TestLoader()
1216 loader.sortTestMethodsUsing = sortUsing
1217 loader.testMethodPrefix = prefix
1218 if suiteClass: loader.suiteClass = suiteClass
1219 return loader
1220
1221def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
1222 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1223
1224def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1225 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
1226
1227def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1228 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +00001229
1230
1231##############################################################################
1232# Text UI
1233##############################################################################
1234
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001235class _WritelnDecorator(object):
Fred Drake02538202001-03-21 18:09:46 +00001236 """Used to decorate file-like objects with a handy 'writeln' method"""
1237 def __init__(self,stream):
1238 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +00001239
1240 def __getattr__(self, attr):
1241 return getattr(self.stream,attr)
1242
Raymond Hettinger91dd19d2003-09-13 02:58:00 +00001243 def writeln(self, arg=None):
Benjamin Petersond0cdb2d2009-03-24 23:07:07 +00001244 if arg:
1245 self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001246 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +00001247
Fred Drake02538202001-03-21 18:09:46 +00001248
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001249class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +00001250 """A test result class that can print formatted text results to a stream.
1251
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001252 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +00001253 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001254 separator1 = '=' * 70
1255 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +00001256
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001257 def __init__(self, stream, descriptions, verbosity):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001258 super(_TextTestResult, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001259 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001260 self.showAll = verbosity > 1
1261 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +00001262 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001263
1264 def getDescription(self, test):
1265 if self.descriptions:
1266 return test.shortDescription() or str(test)
1267 else:
1268 return str(test)
1269
Fred Drake02538202001-03-21 18:09:46 +00001270 def startTest(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001271 super(_TextTestResult, self).startTest(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001272 if self.showAll:
1273 self.stream.write(self.getDescription(test))
1274 self.stream.write(" ... ")
Georg Brandld0632402008-05-11 15:17:41 +00001275 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001276
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001277 def addSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001278 super(_TextTestResult, self).addSuccess(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001279 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001280 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001281 elif self.dots:
1282 self.stream.write('.')
Georg Brandld0632402008-05-11 15:17:41 +00001283 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001284
1285 def addError(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001286 super(_TextTestResult, self).addError(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001287 if self.showAll:
1288 self.stream.writeln("ERROR")
1289 elif self.dots:
1290 self.stream.write('E')
Georg Brandld0632402008-05-11 15:17:41 +00001291 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001292
1293 def addFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001294 super(_TextTestResult, self).addFailure(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001295 if self.showAll:
1296 self.stream.writeln("FAIL")
1297 elif self.dots:
1298 self.stream.write('F')
Georg Brandld0632402008-05-11 15:17:41 +00001299 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001300
Benjamin Peterson692428e2009-03-23 21:50:21 +00001301 def addSkip(self, test, reason):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001302 super(_TextTestResult, self).addSkip(test, reason)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001303 if self.showAll:
1304 self.stream.writeln("skipped {0!r}".format(reason))
1305 elif self.dots:
1306 self.stream.write("s")
1307 self.stream.flush()
1308
1309 def addExpectedFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001310 super(_TextTestResult, self).addExpectedFailure(test, err)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001311 if self.showAll:
1312 self.stream.writeln("expected failure")
1313 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001314 self.stream.write("x")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001315 self.stream.flush()
1316
1317 def addUnexpectedSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001318 super(_TextTestResult, self).addUnexpectedSuccess(test)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001319 if self.showAll:
1320 self.stream.writeln("unexpected success")
1321 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001322 self.stream.write("u")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001323 self.stream.flush()
1324
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001325 def printErrors(self):
1326 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001327 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001328 self.printErrorList('ERROR', self.errors)
1329 self.printErrorList('FAIL', self.failures)
1330
1331 def printErrorList(self, flavour, errors):
1332 for test, err in errors:
1333 self.stream.writeln(self.separator1)
1334 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1335 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +00001336 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +00001337
1338
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001339class TextTestRunner(object):
Fred Drake02538202001-03-21 18:09:46 +00001340 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +00001341
Fred Drake02538202001-03-21 18:09:46 +00001342 It prints out the names of tests as they are run, errors as they
1343 occur, and a summary of the results at the end of the test run.
1344 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001345 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +00001346 self.stream = _WritelnDecorator(stream)
1347 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001348 self.verbosity = verbosity
1349
1350 def _makeResult(self):
1351 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +00001352
1353 def run(self, test):
1354 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001355 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +00001356 startTime = time.time()
1357 test(result)
1358 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +00001359 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001360 result.printErrors()
1361 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +00001362 run = result.testsRun
1363 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +00001364 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +00001365 self.stream.writeln()
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001366 results = map(len, (result.expectedFailures,
1367 result.unexpectedSuccesses,
Benjamin Peterson692428e2009-03-23 21:50:21 +00001368 result.skipped))
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001369 expectedFails, unexpectedSuccesses, skipped = results
Benjamin Peterson692428e2009-03-23 21:50:21 +00001370 infos = []
Fred Drake02538202001-03-21 18:09:46 +00001371 if not result.wasSuccessful():
Benjamin Peterson692428e2009-03-23 21:50:21 +00001372 self.stream.write("FAILED")
Fred Drake02538202001-03-21 18:09:46 +00001373 failed, errored = map(len, (result.failures, result.errors))
1374 if failed:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001375 infos.append("failures=%d" % failed)
Fred Drake02538202001-03-21 18:09:46 +00001376 if errored:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001377 infos.append("errors=%d" % errored)
Fred Drake02538202001-03-21 18:09:46 +00001378 else:
Benjamin Petersona473f002009-03-24 22:56:32 +00001379 self.stream.write("OK")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001380 if skipped:
1381 infos.append("skipped=%d" % skipped)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001382 if expectedFails:
1383 infos.append("expected failures=%d" % expectedFails)
1384 if unexpectedSuccesses:
1385 infos.append("unexpected successes=%d" % unexpectedSuccesses)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001386 if infos:
1387 self.stream.writeln(" (%s)" % (", ".join(infos),))
Benjamin Petersona473f002009-03-24 22:56:32 +00001388 else:
1389 self.stream.write("\n")
Fred Drake02538202001-03-21 18:09:46 +00001390 return result
Tim Petersa19a1682001-03-29 04:36:09 +00001391
Fred Drake02538202001-03-21 18:09:46 +00001392
Fred Drake02538202001-03-21 18:09:46 +00001393
1394##############################################################################
1395# Facilities for running tests from the command line
1396##############################################################################
1397
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001398class TestProgram(object):
Fred Drake02538202001-03-21 18:09:46 +00001399 """A command-line program that runs a set of tests; this is primarily
1400 for making test modules conveniently executable.
1401 """
1402 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +00001403Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001404
1405Options:
1406 -h, --help Show this message
1407 -v, --verbose Verbose output
1408 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +00001409
1410Examples:
1411 %(progName)s - run default set of tests
1412 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001413 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1414 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +00001415 in MyTestCase
1416"""
1417 def __init__(self, module='__main__', defaultTest=None,
Georg Brandld0a96252007-03-07 09:21:06 +00001418 argv=None, testRunner=TextTestRunner,
1419 testLoader=defaultTestLoader):
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001420 if isinstance(module, basestring):
Fred Drake02538202001-03-21 18:09:46 +00001421 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +00001422 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +00001423 self.module = getattr(self.module, part)
1424 else:
1425 self.module = module
1426 if argv is None:
1427 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001428 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +00001429 self.defaultTest = defaultTest
1430 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001431 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +00001432 self.progName = os.path.basename(argv[0])
1433 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +00001434 self.runTests()
1435
1436 def usageExit(self, msg=None):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001437 if msg:
1438 print msg
Fred Drake02538202001-03-21 18:09:46 +00001439 print self.USAGE % self.__dict__
1440 sys.exit(2)
1441
1442 def parseArgs(self, argv):
1443 import getopt
Benjamin Peterson692428e2009-03-23 21:50:21 +00001444 long_opts = ['help','verbose','quiet']
Fred Drake02538202001-03-21 18:09:46 +00001445 try:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001446 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
Fred Drake02538202001-03-21 18:09:46 +00001447 for opt, value in options:
1448 if opt in ('-h','-H','--help'):
1449 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001450 if opt in ('-q','--quiet'):
1451 self.verbosity = 0
1452 if opt in ('-v','--verbose'):
1453 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +00001454 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001455 self.test = self.testLoader.loadTestsFromModule(self.module)
1456 return
Fred Drake02538202001-03-21 18:09:46 +00001457 if len(args) > 0:
1458 self.testNames = args
1459 else:
1460 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001461 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +00001462 except getopt.error, msg:
1463 self.usageExit(msg)
1464
1465 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001466 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1467 self.module)
Fred Drake02538202001-03-21 18:09:46 +00001468
1469 def runTests(self):
Georg Brandld0a96252007-03-07 09:21:06 +00001470 if isinstance(self.testRunner, (type, types.ClassType)):
1471 try:
1472 testRunner = self.testRunner(verbosity=self.verbosity)
1473 except TypeError:
1474 # didn't accept the verbosity argument
1475 testRunner = self.testRunner()
1476 else:
1477 # it is assumed to be a TestRunner instance
1478 testRunner = self.testRunner
1479 result = testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +00001480 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +00001481
1482main = TestProgram
1483
1484
1485##############################################################################
1486# Executing this module from the command line
1487##############################################################################
1488
1489if __name__ == "__main__":
1490 main(module=None)