blob: 9718e8636c394ff2aff38a1bc873dbd9246b7605 [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.
337 self.__type_equality_funcs = {}
338 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 """
357 self.__type_equality_funcs[typeobj] = function
358
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):
519 return self.__type_equality_funcs.get(type(first),
520 self._baseAssertEqual)
521 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
579 def __deprecate(original_func):
580 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
Gregory P. Smith65ff0052009-03-31 19:59:14 +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__()
Fred Drake02538202001-03-21 18:09:46 +00001055 self.__setUpFunc = setUp
1056 self.__tearDownFunc = tearDown
1057 self.__testFunc = testFunc
1058 self.__description = description
1059
1060 def setUp(self):
1061 if self.__setUpFunc is not None:
1062 self.__setUpFunc()
1063
1064 def tearDown(self):
1065 if self.__tearDownFunc is not None:
1066 self.__tearDownFunc()
1067
1068 def runTest(self):
1069 self.__testFunc()
1070
1071 def id(self):
1072 return self.__testFunc.__name__
1073
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
1078 return self.__setUpFunc == other.__setUpFunc and \
1079 self.__tearDownFunc == other.__tearDownFunc and \
1080 self.__testFunc == other.__testFunc and \
1081 self.__description == other.__description
1082
1083 def __ne__(self, other):
1084 return not self == other
1085
1086 def __hash__(self):
Collin Winter9453e5d2007-03-09 23:30:39 +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):
Steve Purcelldc391a62002-08-09 09:46:23 +00001094 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
Fred Drake02538202001-03-21 18:09:46 +00001095
1096 def shortDescription(self):
1097 if self.__description is not None: return self.__description
1098 doc = self.__testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +00001099 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +00001100
1101
1102
1103##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001104# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +00001105##############################################################################
1106
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001107class TestLoader(object):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001108 """
1109 This class is responsible for loading tests according to various criteria
1110 and returning them wrapped in a TestSuite
Fred Drake02538202001-03-21 18:09:46 +00001111 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001112 testMethodPrefix = 'test'
1113 sortTestMethodsUsing = cmp
1114 suiteClass = TestSuite
Benjamin Peterson692428e2009-03-23 21:50:21 +00001115 classSuiteClass = ClassTestSuite
Fred Drake02538202001-03-21 18:09:46 +00001116
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001117 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001118 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +00001119 if issubclass(testCaseClass, TestSuite):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001120 raise TypeError("Test cases should not be derived from TestSuite." \
1121 " Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +00001122 testCaseNames = self.getTestCaseNames(testCaseClass)
1123 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1124 testCaseNames = ['runTest']
Benjamin Peterson692428e2009-03-23 21:50:21 +00001125 suite = self.classSuiteClass(map(testCaseClass, testCaseNames),
1126 testCaseClass)
1127 return suite
Fred Drake02538202001-03-21 18:09:46 +00001128
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001129 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +00001130 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001131 tests = []
1132 for name in dir(module):
1133 obj = getattr(module, name)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001134 if isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001135 tests.append(self.loadTestsFromTestCase(obj))
1136 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +00001137
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001138 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001139 """Return a suite of all tests cases given a string specifier.
1140
1141 The name may resolve either to a module, a test case class, a
1142 test method within a test case class, or a callable object which
1143 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +00001144
Steve Purcell15d89272001-04-12 09:05:01 +00001145 The method optionally resolves the names relative to a given module.
1146 """
Steve Purcell7e743842003-09-22 11:08:12 +00001147 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001148 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +00001149 parts_copy = parts[:]
1150 while parts_copy:
1151 try:
1152 module = __import__('.'.join(parts_copy))
1153 break
1154 except ImportError:
1155 del parts_copy[-1]
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001156 if not parts_copy:
1157 raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +00001158 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001159 obj = module
1160 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +00001161 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +00001162
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001163 if isinstance(obj, types.ModuleType):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001164 return self.loadTestsFromModule(obj)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001165 elif isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001166 return self.loadTestsFromTestCase(obj)
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001167 elif (isinstance(obj, types.UnboundMethodType) and
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001168 isinstance(parent, type) and
Georg Brandl15c5ce92007-03-07 09:09:40 +00001169 issubclass(parent, TestCase)):
1170 return TestSuite([parent(obj.__name__)])
Steve Purcell397b45d2003-10-26 10:41:03 +00001171 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +00001172 return obj
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001173 elif hasattr(obj, '__call__'):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001174 test = obj()
Georg Brandl15c5ce92007-03-07 09:09:40 +00001175 if isinstance(test, TestSuite):
1176 return test
1177 elif isinstance(test, TestCase):
1178 return TestSuite([test])
1179 else:
1180 raise TypeError("calling %s returned %s, not a test" %
1181 (obj, test))
Fred Drake02538202001-03-21 18:09:46 +00001182 else:
Georg Brandl15c5ce92007-03-07 09:09:40 +00001183 raise TypeError("don't know how to make test from: %s" % obj)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001184
1185 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001186 """Return a suite of all tests cases found using the given sequence
1187 of string specifiers. See 'loadTestsFromName()'.
1188 """
Steve Purcell7e743842003-09-22 11:08:12 +00001189 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001190 return self.suiteClass(suites)
1191
1192 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001193 """Return a sorted sequence of method names found within testCaseClass
1194 """
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001195 def isTestMethod(attrname, testCaseClass=testCaseClass,
1196 prefix=self.testMethodPrefix):
1197 return attrname.startswith(prefix) and \
1198 hasattr(getattr(testCaseClass, attrname), '__call__')
Steve Purcell7e743842003-09-22 11:08:12 +00001199 testFnNames = filter(isTestMethod, dir(testCaseClass))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001200 if self.sortTestMethodsUsing:
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001201 testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001202 return testFnNames
1203
1204
1205
1206defaultTestLoader = TestLoader()
1207
1208
1209##############################################################################
1210# Patches for old functions: these functions should be considered obsolete
1211##############################################################################
1212
1213def _makeLoader(prefix, sortUsing, suiteClass=None):
1214 loader = TestLoader()
1215 loader.sortTestMethodsUsing = sortUsing
1216 loader.testMethodPrefix = prefix
1217 if suiteClass: loader.suiteClass = suiteClass
1218 return loader
1219
1220def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
1221 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1222
1223def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1224 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
1225
1226def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1227 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +00001228
1229
1230##############################################################################
1231# Text UI
1232##############################################################################
1233
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001234class _WritelnDecorator(object):
Fred Drake02538202001-03-21 18:09:46 +00001235 """Used to decorate file-like objects with a handy 'writeln' method"""
1236 def __init__(self,stream):
1237 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +00001238
1239 def __getattr__(self, attr):
1240 return getattr(self.stream,attr)
1241
Raymond Hettinger91dd19d2003-09-13 02:58:00 +00001242 def writeln(self, arg=None):
Benjamin Petersond0cdb2d2009-03-24 23:07:07 +00001243 if arg:
1244 self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001245 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +00001246
Fred Drake02538202001-03-21 18:09:46 +00001247
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001248class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +00001249 """A test result class that can print formatted text results to a stream.
1250
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001251 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +00001252 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001253 separator1 = '=' * 70
1254 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +00001255
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001256 def __init__(self, stream, descriptions, verbosity):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001257 super(_TextTestResult, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001258 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001259 self.showAll = verbosity > 1
1260 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +00001261 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001262
1263 def getDescription(self, test):
1264 if self.descriptions:
1265 return test.shortDescription() or str(test)
1266 else:
1267 return str(test)
1268
Fred Drake02538202001-03-21 18:09:46 +00001269 def startTest(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001270 super(_TextTestResult, self).startTest(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001271 if self.showAll:
1272 self.stream.write(self.getDescription(test))
1273 self.stream.write(" ... ")
Georg Brandld0632402008-05-11 15:17:41 +00001274 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001275
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001276 def addSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001277 super(_TextTestResult, self).addSuccess(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001278 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001279 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001280 elif self.dots:
1281 self.stream.write('.')
Georg Brandld0632402008-05-11 15:17:41 +00001282 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001283
1284 def addError(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001285 super(_TextTestResult, self).addError(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001286 if self.showAll:
1287 self.stream.writeln("ERROR")
1288 elif self.dots:
1289 self.stream.write('E')
Georg Brandld0632402008-05-11 15:17:41 +00001290 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001291
1292 def addFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001293 super(_TextTestResult, self).addFailure(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001294 if self.showAll:
1295 self.stream.writeln("FAIL")
1296 elif self.dots:
1297 self.stream.write('F')
Georg Brandld0632402008-05-11 15:17:41 +00001298 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001299
Benjamin Peterson692428e2009-03-23 21:50:21 +00001300 def addSkip(self, test, reason):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001301 super(_TextTestResult, self).addSkip(test, reason)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001302 if self.showAll:
1303 self.stream.writeln("skipped {0!r}".format(reason))
1304 elif self.dots:
1305 self.stream.write("s")
1306 self.stream.flush()
1307
1308 def addExpectedFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001309 super(_TextTestResult, self).addExpectedFailure(test, err)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001310 if self.showAll:
1311 self.stream.writeln("expected failure")
1312 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001313 self.stream.write("x")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001314 self.stream.flush()
1315
1316 def addUnexpectedSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001317 super(_TextTestResult, self).addUnexpectedSuccess(test)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001318 if self.showAll:
1319 self.stream.writeln("unexpected success")
1320 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001321 self.stream.write("u")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001322 self.stream.flush()
1323
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001324 def printErrors(self):
1325 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001326 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001327 self.printErrorList('ERROR', self.errors)
1328 self.printErrorList('FAIL', self.failures)
1329
1330 def printErrorList(self, flavour, errors):
1331 for test, err in errors:
1332 self.stream.writeln(self.separator1)
1333 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1334 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +00001335 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +00001336
1337
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001338class TextTestRunner(object):
Fred Drake02538202001-03-21 18:09:46 +00001339 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +00001340
Fred Drake02538202001-03-21 18:09:46 +00001341 It prints out the names of tests as they are run, errors as they
1342 occur, and a summary of the results at the end of the test run.
1343 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001344 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +00001345 self.stream = _WritelnDecorator(stream)
1346 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001347 self.verbosity = verbosity
1348
1349 def _makeResult(self):
1350 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +00001351
1352 def run(self, test):
1353 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001354 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +00001355 startTime = time.time()
1356 test(result)
1357 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +00001358 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001359 result.printErrors()
1360 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +00001361 run = result.testsRun
1362 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +00001363 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +00001364 self.stream.writeln()
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001365 results = map(len, (result.expectedFailures,
1366 result.unexpectedSuccesses,
Benjamin Peterson692428e2009-03-23 21:50:21 +00001367 result.skipped))
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001368 expectedFails, unexpectedSuccesses, skipped = results
Benjamin Peterson692428e2009-03-23 21:50:21 +00001369 infos = []
Fred Drake02538202001-03-21 18:09:46 +00001370 if not result.wasSuccessful():
Benjamin Peterson692428e2009-03-23 21:50:21 +00001371 self.stream.write("FAILED")
Fred Drake02538202001-03-21 18:09:46 +00001372 failed, errored = map(len, (result.failures, result.errors))
1373 if failed:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001374 infos.append("failures=%d" % failed)
Fred Drake02538202001-03-21 18:09:46 +00001375 if errored:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001376 infos.append("errors=%d" % errored)
Fred Drake02538202001-03-21 18:09:46 +00001377 else:
Benjamin Petersona473f002009-03-24 22:56:32 +00001378 self.stream.write("OK")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001379 if skipped:
1380 infos.append("skipped=%d" % skipped)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001381 if expectedFails:
1382 infos.append("expected failures=%d" % expectedFails)
1383 if unexpectedSuccesses:
1384 infos.append("unexpected successes=%d" % unexpectedSuccesses)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001385 if infos:
1386 self.stream.writeln(" (%s)" % (", ".join(infos),))
Benjamin Petersona473f002009-03-24 22:56:32 +00001387 else:
1388 self.stream.write("\n")
Fred Drake02538202001-03-21 18:09:46 +00001389 return result
Tim Petersa19a1682001-03-29 04:36:09 +00001390
Fred Drake02538202001-03-21 18:09:46 +00001391
Fred Drake02538202001-03-21 18:09:46 +00001392
1393##############################################################################
1394# Facilities for running tests from the command line
1395##############################################################################
1396
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001397class TestProgram(object):
Fred Drake02538202001-03-21 18:09:46 +00001398 """A command-line program that runs a set of tests; this is primarily
1399 for making test modules conveniently executable.
1400 """
1401 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +00001402Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001403
1404Options:
1405 -h, --help Show this message
1406 -v, --verbose Verbose output
1407 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +00001408
1409Examples:
1410 %(progName)s - run default set of tests
1411 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001412 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1413 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +00001414 in MyTestCase
1415"""
1416 def __init__(self, module='__main__', defaultTest=None,
Georg Brandld0a96252007-03-07 09:21:06 +00001417 argv=None, testRunner=TextTestRunner,
1418 testLoader=defaultTestLoader):
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001419 if isinstance(module, basestring):
Fred Drake02538202001-03-21 18:09:46 +00001420 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +00001421 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +00001422 self.module = getattr(self.module, part)
1423 else:
1424 self.module = module
1425 if argv is None:
1426 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001427 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +00001428 self.defaultTest = defaultTest
1429 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001430 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +00001431 self.progName = os.path.basename(argv[0])
1432 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +00001433 self.runTests()
1434
1435 def usageExit(self, msg=None):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001436 if msg:
1437 print msg
Fred Drake02538202001-03-21 18:09:46 +00001438 print self.USAGE % self.__dict__
1439 sys.exit(2)
1440
1441 def parseArgs(self, argv):
1442 import getopt
Benjamin Peterson692428e2009-03-23 21:50:21 +00001443 long_opts = ['help','verbose','quiet']
Fred Drake02538202001-03-21 18:09:46 +00001444 try:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001445 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
Fred Drake02538202001-03-21 18:09:46 +00001446 for opt, value in options:
1447 if opt in ('-h','-H','--help'):
1448 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001449 if opt in ('-q','--quiet'):
1450 self.verbosity = 0
1451 if opt in ('-v','--verbose'):
1452 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +00001453 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001454 self.test = self.testLoader.loadTestsFromModule(self.module)
1455 return
Fred Drake02538202001-03-21 18:09:46 +00001456 if len(args) > 0:
1457 self.testNames = args
1458 else:
1459 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001460 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +00001461 except getopt.error, msg:
1462 self.usageExit(msg)
1463
1464 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001465 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1466 self.module)
Fred Drake02538202001-03-21 18:09:46 +00001467
1468 def runTests(self):
Georg Brandld0a96252007-03-07 09:21:06 +00001469 if isinstance(self.testRunner, (type, types.ClassType)):
1470 try:
1471 testRunner = self.testRunner(verbosity=self.verbosity)
1472 except TypeError:
1473 # didn't accept the verbosity argument
1474 testRunner = self.testRunner()
1475 else:
1476 # it is assumed to be a TestRunner instance
1477 testRunner = self.testRunner
1478 result = testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +00001479 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +00001480
1481main = TestProgram
1482
1483
1484##############################################################################
1485# Executing this module from the command line
1486##############################################################################
1487
1488if __name__ == "__main__":
1489 main(module=None)