blob: cd91c2c5b189711954303b28661ad1248cbc2968 [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*'
17 self.assertEquals((1 + 2), 3)
18 self.assertEquals(0 + 1, 1)
Steve Purcell7b065702001-09-06 08:24:40 +000019 def testMultiply(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +000020 self.assertEquals((0 * 10), 0)
21 self.assertEquals((5 * 8), 40)
22
23 if __name__ == '__main__':
24 unittest.main()
25
26Further information is available in the bundled documentation, and from
27
28 http://pyunit.sourceforge.net/
29
Steve Purcell7e743842003-09-22 11:08:12 +000030Copyright (c) 1999-2003 Steve Purcell
Fred Drake02538202001-03-21 18:09:46 +000031This module is free software, and you may redistribute it and/or modify
32it under the same terms as Python itself, so long as this copyright message
33and disclaimer are retained in their original form.
34
35IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
36SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
37THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
38DAMAGE.
39
40THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
41LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
42PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
43AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
44SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Steve Purcell5ddd1a82001-03-22 08:45:36 +000045'''
Fred Drake02538202001-03-21 18:09:46 +000046
Steve Purcell5ddd1a82001-03-22 08:45:36 +000047__author__ = "Steve Purcell"
48__email__ = "stephen_purcell at yahoo dot com"
Steve Purcellb8d5f242003-12-06 13:03:13 +000049__version__ = "#Revision: 1.63 $"[11:-2]
Fred Drake02538202001-03-21 18:09:46 +000050
51import time
52import sys
53import traceback
Fred Drake02538202001-03-21 18:09:46 +000054import os
Steve Purcell5ddd1a82001-03-22 08:45:36 +000055import types
Fred Drake02538202001-03-21 18:09:46 +000056
57##############################################################################
Steve Purcelld75e7e42003-09-15 11:01:21 +000058# Exported classes and functions
59##############################################################################
60__all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
61 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
62
Steve Purcell7e743842003-09-22 11:08:12 +000063# Expose obsolete functions for backwards compatibility
Steve Purcelld75e7e42003-09-15 11:01:21 +000064__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
65
66
67##############################################################################
Steve Purcell7e743842003-09-22 11:08:12 +000068# Backward compatibility
69##############################################################################
70if sys.version_info[:2] < (2, 2):
71 False, True = 0, 1
72 def isinstance(obj, clsinfo):
73 import __builtin__
Raymond Hettingerf7153662005-02-07 14:16:21 +000074 if type(clsinfo) in (tuple, list):
Steve Purcell7e743842003-09-22 11:08:12 +000075 for cls in clsinfo:
76 if cls is type: cls = types.ClassType
77 if __builtin__.isinstance(obj, cls):
78 return 1
79 return 0
80 else: return __builtin__.isinstance(obj, clsinfo)
81
82
83##############################################################################
Fred Drake02538202001-03-21 18:09:46 +000084# Test framework core
85##############################################################################
86
Steve Purcell824574d2002-08-08 13:38:02 +000087# All classes defined herein are 'new-style' classes, allowing use of 'super()'
88__metaclass__ = type
89
Steve Purcelldc391a62002-08-09 09:46:23 +000090def _strclass(cls):
91 return "%s.%s" % (cls.__module__, cls.__name__)
92
Steve Purcellb8d5f242003-12-06 13:03:13 +000093__unittest = 1
94
Fred Drake02538202001-03-21 18:09:46 +000095class TestResult:
96 """Holder for test result information.
97
98 Test results are automatically managed by the TestCase and TestSuite
99 classes, and do not need to be explicitly manipulated by writers of tests.
100
101 Each instance holds the total number of tests run, and collections of
102 failures and errors that occurred among those test runs. The collections
Steve Purcell7b065702001-09-06 08:24:40 +0000103 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
Fred Drake656f9ec2001-09-06 19:13:14 +0000104 formatted traceback of the error that occurred.
Fred Drake02538202001-03-21 18:09:46 +0000105 """
106 def __init__(self):
107 self.failures = []
108 self.errors = []
109 self.testsRun = 0
110 self.shouldStop = 0
111
112 def startTest(self, test):
113 "Called when the given test is about to be run"
114 self.testsRun = self.testsRun + 1
115
116 def stopTest(self, test):
117 "Called when the given test has been run"
118 pass
119
120 def addError(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000121 """Called when an error has occurred. 'err' is a tuple of values as
122 returned by sys.exc_info().
123 """
Steve Purcellb8d5f242003-12-06 13:03:13 +0000124 self.errors.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000125
126 def addFailure(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000127 """Called when an error has occurred. 'err' is a tuple of values as
128 returned by sys.exc_info()."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000129 self.failures.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000130
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000131 def addSuccess(self, test):
132 "Called when a test has completed successfully"
133 pass
134
Fred Drake02538202001-03-21 18:09:46 +0000135 def wasSuccessful(self):
136 "Tells whether or not this result was a success"
137 return len(self.failures) == len(self.errors) == 0
138
139 def stop(self):
140 "Indicates that the tests should be aborted"
Steve Purcell7e743842003-09-22 11:08:12 +0000141 self.shouldStop = True
Tim Petersa19a1682001-03-29 04:36:09 +0000142
Steve Purcellb8d5f242003-12-06 13:03:13 +0000143 def _exc_info_to_string(self, err, test):
Steve Purcell7b065702001-09-06 08:24:40 +0000144 """Converts a sys.exc_info()-style tuple of values into a string."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000145 exctype, value, tb = err
146 # Skip test runner traceback levels
147 while tb and self._is_relevant_tb_level(tb):
148 tb = tb.tb_next
149 if exctype is test.failureException:
150 # Skip assert*() traceback levels
151 length = self._count_relevant_tb_levels(tb)
152 return ''.join(traceback.format_exception(exctype, value, tb, length))
153 return ''.join(traceback.format_exception(exctype, value, tb))
154
155 def _is_relevant_tb_level(self, tb):
156 return tb.tb_frame.f_globals.has_key('__unittest')
157
158 def _count_relevant_tb_levels(self, tb):
159 length = 0
160 while tb and not self._is_relevant_tb_level(tb):
161 length += 1
162 tb = tb.tb_next
163 return length
Steve Purcell7b065702001-09-06 08:24:40 +0000164
Fred Drake02538202001-03-21 18:09:46 +0000165 def __repr__(self):
166 return "<%s run=%i errors=%i failures=%i>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +0000167 (_strclass(self.__class__), self.testsRun, len(self.errors),
Fred Drake02538202001-03-21 18:09:46 +0000168 len(self.failures))
169
Fred Drake02538202001-03-21 18:09:46 +0000170class TestCase:
171 """A class whose instances are single test cases.
172
Fred Drake02538202001-03-21 18:09:46 +0000173 By default, the test code itself should be placed in a method named
174 'runTest'.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000175
Tim Petersa19a1682001-03-29 04:36:09 +0000176 If the fixture may be used for many test cases, create as
Fred Drake02538202001-03-21 18:09:46 +0000177 many test methods as are needed. When instantiating such a TestCase
178 subclass, specify in the constructor arguments the name of the test method
179 that the instance is to execute.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000180
Tim Petersa19a1682001-03-29 04:36:09 +0000181 Test authors should subclass TestCase for their own tests. Construction
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000182 and deconstruction of the test's environment ('fixture') can be
183 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
184
185 If it is necessary to override the __init__ method, the base class
186 __init__ method must always be called. It is important that subclasses
187 should not change the signature of their __init__ method, since instances
188 of the classes are instantiated automatically by parts of the framework
189 in order to be run.
Fred Drake02538202001-03-21 18:09:46 +0000190 """
Steve Purcell15d89272001-04-12 09:05:01 +0000191
192 # This attribute determines which exception will be raised when
193 # the instance's assertion methods fail; test methods raising this
194 # exception will be deemed to have 'failed' rather than 'errored'
195
196 failureException = AssertionError
197
Fred Drake02538202001-03-21 18:09:46 +0000198 def __init__(self, methodName='runTest'):
199 """Create an instance of the class that will use the named test
200 method when executed. Raises a ValueError if the instance does
201 not have a method with the specified name.
202 """
203 try:
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000204 self._testMethodName = methodName
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000205 testMethod = getattr(self, methodName)
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000206 self._testMethodDoc = testMethod.__doc__
Fred Drake02538202001-03-21 18:09:46 +0000207 except AttributeError:
208 raise ValueError, "no such test method in %s: %s" % \
209 (self.__class__, methodName)
210
211 def setUp(self):
212 "Hook method for setting up the test fixture before exercising it."
213 pass
214
215 def tearDown(self):
216 "Hook method for deconstructing the test fixture after testing it."
217 pass
218
219 def countTestCases(self):
220 return 1
221
222 def defaultTestResult(self):
223 return TestResult()
224
225 def shortDescription(self):
226 """Returns a one-line description of the test, or None if no
227 description has been provided.
228
229 The default implementation of this method returns the first line of
230 the specified test method's docstring.
231 """
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000232 doc = self._testMethodDoc
Steve Purcell7e743842003-09-22 11:08:12 +0000233 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +0000234
235 def id(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000236 return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000237
238 def __str__(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000239 return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
Fred Drake02538202001-03-21 18:09:46 +0000240
241 def __repr__(self):
242 return "<%s testMethod=%s>" % \
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000243 (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000244
245 def run(self, result=None):
Fred Drake02538202001-03-21 18:09:46 +0000246 if result is None: result = self.defaultTestResult()
247 result.startTest(self)
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000248 testMethod = getattr(self, self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000249 try:
250 try:
251 self.setUp()
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000252 except KeyboardInterrupt:
253 raise
Fred Drake02538202001-03-21 18:09:46 +0000254 except:
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000255 result.addError(self, self._exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000256 return
257
Steve Purcell7e743842003-09-22 11:08:12 +0000258 ok = False
Fred Drake02538202001-03-21 18:09:46 +0000259 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000260 testMethod()
Steve Purcell7e743842003-09-22 11:08:12 +0000261 ok = True
Skip Montanaroae5c37b2003-07-13 15:18:12 +0000262 except self.failureException:
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000263 result.addFailure(self, self._exc_info())
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000264 except KeyboardInterrupt:
265 raise
Fred Drake02538202001-03-21 18:09:46 +0000266 except:
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000267 result.addError(self, self._exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000268
269 try:
270 self.tearDown()
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000271 except KeyboardInterrupt:
272 raise
Fred Drake02538202001-03-21 18:09:46 +0000273 except:
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000274 result.addError(self, self._exc_info())
Steve Purcell7e743842003-09-22 11:08:12 +0000275 ok = False
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000276 if ok: result.addSuccess(self)
Fred Drake02538202001-03-21 18:09:46 +0000277 finally:
278 result.stopTest(self)
279
Raymond Hettinger664347b2004-12-04 21:21:53 +0000280 def __call__(self, *args, **kwds):
281 return self.run(*args, **kwds)
Steve Purcell7e743842003-09-22 11:08:12 +0000282
Fred Drake02538202001-03-21 18:09:46 +0000283 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000284 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000285 self.setUp()
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000286 getattr(self, self._testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000287 self.tearDown()
288
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000289 def _exc_info(self):
Steve Purcell15d89272001-04-12 09:05:01 +0000290 """Return a version of sys.exc_info() with the traceback frame
291 minimised; usually the top level of the traceback frame is not
292 needed.
Fred Drake02538202001-03-21 18:09:46 +0000293 """
Steve Purcell15d89272001-04-12 09:05:01 +0000294 exctype, excvalue, tb = sys.exc_info()
295 if sys.platform[:4] == 'java': ## tracebacks look different in Jython
296 return (exctype, excvalue, tb)
Steve Purcellb8d5f242003-12-06 13:03:13 +0000297 return (exctype, excvalue, tb)
Fred Drake02538202001-03-21 18:09:46 +0000298
Steve Purcell15d89272001-04-12 09:05:01 +0000299 def fail(self, msg=None):
300 """Fail immediately, with the given message."""
301 raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000302
303 def failIf(self, expr, msg=None):
304 "Fail the test if the expression is true."
Steve Purcell15d89272001-04-12 09:05:01 +0000305 if expr: raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000306
Steve Purcell15d89272001-04-12 09:05:01 +0000307 def failUnless(self, expr, msg=None):
308 """Fail the test unless the expression is true."""
309 if not expr: raise self.failureException, msg
310
311 def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
312 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000313 by callableObj when invoked with arguments args and keyword
314 arguments kwargs. If a different type of exception is
315 thrown, it will not be caught, and the test case will be
316 deemed to have suffered an error, exactly as for an
317 unexpected exception.
318 """
319 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000320 callableObj(*args, **kwargs)
Fred Drake02538202001-03-21 18:09:46 +0000321 except excClass:
322 return
323 else:
324 if hasattr(excClass,'__name__'): excName = excClass.__name__
325 else: excName = str(excClass)
Steve Purcell7e743842003-09-22 11:08:12 +0000326 raise self.failureException, "%s not raised" % excName
Fred Drake02538202001-03-21 18:09:46 +0000327
Steve Purcell15d89272001-04-12 09:05:01 +0000328 def failUnlessEqual(self, first, second, msg=None):
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000329 """Fail if the two objects are unequal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000330 operator.
331 """
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000332 if not first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000333 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000334 (msg or '%r != %r' % (first, second))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000335
Steve Purcell15d89272001-04-12 09:05:01 +0000336 def failIfEqual(self, first, second, msg=None):
337 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000338 operator.
339 """
Steve Purcell15d89272001-04-12 09:05:01 +0000340 if first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000341 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000342 (msg or '%r == %r' % (first, second))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000343
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000344 def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
345 """Fail if the two objects are unequal as determined by their
346 difference rounded to the given number of decimal places
347 (default 7) and comparing to zero.
348
Steve Purcell397b45d2003-10-26 10:41:03 +0000349 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000350 as significant digits (measured from the most signficant digit).
351 """
352 if round(second-first, places) != 0:
353 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000354 (msg or '%r != %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000355
356 def failIfAlmostEqual(self, first, second, places=7, msg=None):
357 """Fail if the two objects are equal as determined by their
358 difference rounded to the given number of decimal places
359 (default 7) and comparing to zero.
360
Steve Purcellcca34912003-10-26 16:38:16 +0000361 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000362 as significant digits (measured from the most signficant digit).
363 """
364 if round(second-first, places) == 0:
365 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000366 (msg or '%r == %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000367
Steve Purcell7e743842003-09-22 11:08:12 +0000368 # Synonyms for assertion methods
369
Steve Purcell15d89272001-04-12 09:05:01 +0000370 assertEqual = assertEquals = failUnlessEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000371
Steve Purcell15d89272001-04-12 09:05:01 +0000372 assertNotEqual = assertNotEquals = failIfEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000373
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000374 assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
375
376 assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
377
Steve Purcell15d89272001-04-12 09:05:01 +0000378 assertRaises = failUnlessRaises
379
Steve Purcell7e743842003-09-22 11:08:12 +0000380 assert_ = assertTrue = failUnless
381
382 assertFalse = failIf
Steve Purcell15d89272001-04-12 09:05:01 +0000383
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000384
Fred Drake02538202001-03-21 18:09:46 +0000385
386class TestSuite:
387 """A test suite is a composite test consisting of a number of TestCases.
388
389 For use, create an instance of TestSuite, then add test case instances.
390 When all tests have been added, the suite can be passed to a test
391 runner, such as TextTestRunner. It will run the individual test cases
392 in the order in which they were added, aggregating the results. When
393 subclassing, do not forget to call the base class constructor.
394 """
395 def __init__(self, tests=()):
396 self._tests = []
397 self.addTests(tests)
398
399 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000400 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +0000401
402 __str__ = __repr__
403
Jim Fultonfafd8742004-08-28 15:22:12 +0000404 def __iter__(self):
405 return iter(self._tests)
406
Fred Drake02538202001-03-21 18:09:46 +0000407 def countTestCases(self):
408 cases = 0
409 for test in self._tests:
Steve Purcell7e743842003-09-22 11:08:12 +0000410 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +0000411 return cases
412
413 def addTest(self, test):
Georg Brandld480b332007-03-07 11:55:25 +0000414 # sanity checks
415 if not callable(test):
416 raise TypeError("the test to add must be callable")
417 if (isinstance(test, (type, types.ClassType)) and
418 issubclass(test, (TestCase, TestSuite))):
419 raise TypeError("TestCases and TestSuites must be instantiated "
420 "before passing them to addTest()")
Fred Drake02538202001-03-21 18:09:46 +0000421 self._tests.append(test)
422
423 def addTests(self, tests):
Georg Brandld480b332007-03-07 11:55:25 +0000424 if isinstance(tests, basestring):
425 raise TypeError("tests must be an iterable of tests, not a string")
Fred Drake02538202001-03-21 18:09:46 +0000426 for test in tests:
427 self.addTest(test)
428
429 def run(self, result):
Fred Drake02538202001-03-21 18:09:46 +0000430 for test in self._tests:
431 if result.shouldStop:
432 break
433 test(result)
434 return result
435
Raymond Hettinger664347b2004-12-04 21:21:53 +0000436 def __call__(self, *args, **kwds):
437 return self.run(*args, **kwds)
438
Fred Drake02538202001-03-21 18:09:46 +0000439 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000440 """Run the tests without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000441 for test in self._tests: test.debug()
Fred Drake02538202001-03-21 18:09:46 +0000442
443
444class FunctionTestCase(TestCase):
445 """A test case that wraps a test function.
446
447 This is useful for slipping pre-existing test functions into the
448 PyUnit framework. Optionally, set-up and tidy-up functions can be
449 supplied. As with TestCase, the tidy-up ('tearDown') function will
450 always be called if the set-up ('setUp') function ran successfully.
451 """
452
453 def __init__(self, testFunc, setUp=None, tearDown=None,
454 description=None):
455 TestCase.__init__(self)
456 self.__setUpFunc = setUp
457 self.__tearDownFunc = tearDown
458 self.__testFunc = testFunc
459 self.__description = description
460
461 def setUp(self):
462 if self.__setUpFunc is not None:
463 self.__setUpFunc()
464
465 def tearDown(self):
466 if self.__tearDownFunc is not None:
467 self.__tearDownFunc()
468
469 def runTest(self):
470 self.__testFunc()
471
472 def id(self):
473 return self.__testFunc.__name__
474
475 def __str__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000476 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +0000477
478 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000479 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
Fred Drake02538202001-03-21 18:09:46 +0000480
481 def shortDescription(self):
482 if self.__description is not None: return self.__description
483 doc = self.__testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +0000484 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +0000485
486
487
488##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000489# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +0000490##############################################################################
491
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000492class TestLoader:
493 """This class is responsible for loading tests according to various
494 criteria and returning them wrapped in a Test
Fred Drake02538202001-03-21 18:09:46 +0000495 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000496 testMethodPrefix = 'test'
497 sortTestMethodsUsing = cmp
498 suiteClass = TestSuite
Fred Drake02538202001-03-21 18:09:46 +0000499
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000500 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000501 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +0000502 if issubclass(testCaseClass, TestSuite):
503 raise TypeError("Test cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +0000504 testCaseNames = self.getTestCaseNames(testCaseClass)
505 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
506 testCaseNames = ['runTest']
507 return self.suiteClass(map(testCaseClass, testCaseNames))
Fred Drake02538202001-03-21 18:09:46 +0000508
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000509 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +0000510 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000511 tests = []
512 for name in dir(module):
513 obj = getattr(module, name)
Guido van Rossum67911372002-09-30 19:25:56 +0000514 if (isinstance(obj, (type, types.ClassType)) and
515 issubclass(obj, TestCase)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000516 tests.append(self.loadTestsFromTestCase(obj))
517 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +0000518
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000519 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000520 """Return a suite of all tests cases given a string specifier.
521
522 The name may resolve either to a module, a test case class, a
523 test method within a test case class, or a callable object which
524 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +0000525
Steve Purcell15d89272001-04-12 09:05:01 +0000526 The method optionally resolves the names relative to a given module.
527 """
Steve Purcell7e743842003-09-22 11:08:12 +0000528 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000529 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +0000530 parts_copy = parts[:]
531 while parts_copy:
532 try:
533 module = __import__('.'.join(parts_copy))
534 break
535 except ImportError:
536 del parts_copy[-1]
537 if not parts_copy: raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +0000538 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000539 obj = module
540 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +0000541 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +0000542
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000543 if type(obj) == types.ModuleType:
544 return self.loadTestsFromModule(obj)
Guido van Rossum67911372002-09-30 19:25:56 +0000545 elif (isinstance(obj, (type, types.ClassType)) and
Steve Purcell397b45d2003-10-26 10:41:03 +0000546 issubclass(obj, TestCase)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000547 return self.loadTestsFromTestCase(obj)
548 elif type(obj) == types.UnboundMethodType:
Steve Purcell7e743842003-09-22 11:08:12 +0000549 return parent(obj.__name__)
Steve Purcell397b45d2003-10-26 10:41:03 +0000550 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +0000551 return obj
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000552 elif callable(obj):
553 test = obj()
Steve Purcell397b45d2003-10-26 10:41:03 +0000554 if not isinstance(test, (TestCase, TestSuite)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000555 raise ValueError, \
Steve Purcell4bc80852001-05-10 01:28:40 +0000556 "calling %s returned %s, not a test" % (obj,test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000557 return test
Fred Drake02538202001-03-21 18:09:46 +0000558 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000559 raise ValueError, "don't know how to make test from: %s" % obj
560
561 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000562 """Return a suite of all tests cases found using the given sequence
563 of string specifiers. See 'loadTestsFromName()'.
564 """
Steve Purcell7e743842003-09-22 11:08:12 +0000565 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000566 return self.suiteClass(suites)
567
568 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000569 """Return a sorted sequence of method names found within testCaseClass
570 """
Steve Purcell7e743842003-09-22 11:08:12 +0000571 def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix):
Steve Purcell31982752003-09-23 08:41:53 +0000572 return attrname.startswith(prefix) and callable(getattr(testCaseClass, attrname))
Steve Purcell7e743842003-09-22 11:08:12 +0000573 testFnNames = filter(isTestMethod, dir(testCaseClass))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000574 for baseclass in testCaseClass.__bases__:
575 for testFnName in self.getTestCaseNames(baseclass):
576 if testFnName not in testFnNames: # handle overridden methods
577 testFnNames.append(testFnName)
578 if self.sortTestMethodsUsing:
579 testFnNames.sort(self.sortTestMethodsUsing)
580 return testFnNames
581
582
583
584defaultTestLoader = TestLoader()
585
586
587##############################################################################
588# Patches for old functions: these functions should be considered obsolete
589##############################################################################
590
591def _makeLoader(prefix, sortUsing, suiteClass=None):
592 loader = TestLoader()
593 loader.sortTestMethodsUsing = sortUsing
594 loader.testMethodPrefix = prefix
595 if suiteClass: loader.suiteClass = suiteClass
596 return loader
597
598def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
599 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
600
601def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
602 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
603
604def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
605 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +0000606
607
608##############################################################################
609# Text UI
610##############################################################################
611
612class _WritelnDecorator:
613 """Used to decorate file-like objects with a handy 'writeln' method"""
614 def __init__(self,stream):
615 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +0000616
617 def __getattr__(self, attr):
618 return getattr(self.stream,attr)
619
Raymond Hettinger91dd19d2003-09-13 02:58:00 +0000620 def writeln(self, arg=None):
621 if arg: self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000622 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +0000623
Fred Drake02538202001-03-21 18:09:46 +0000624
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000625class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +0000626 """A test result class that can print formatted text results to a stream.
627
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000628 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +0000629 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000630 separator1 = '=' * 70
631 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +0000632
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000633 def __init__(self, stream, descriptions, verbosity):
Fred Drake02538202001-03-21 18:09:46 +0000634 TestResult.__init__(self)
635 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000636 self.showAll = verbosity > 1
637 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +0000638 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000639
640 def getDescription(self, test):
641 if self.descriptions:
642 return test.shortDescription() or str(test)
643 else:
644 return str(test)
645
Fred Drake02538202001-03-21 18:09:46 +0000646 def startTest(self, test):
647 TestResult.startTest(self, test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000648 if self.showAll:
649 self.stream.write(self.getDescription(test))
650 self.stream.write(" ... ")
Fred Drake02538202001-03-21 18:09:46 +0000651
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000652 def addSuccess(self, test):
653 TestResult.addSuccess(self, test)
654 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000655 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000656 elif self.dots:
657 self.stream.write('.')
Fred Drake02538202001-03-21 18:09:46 +0000658
659 def addError(self, test, err):
660 TestResult.addError(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000661 if self.showAll:
662 self.stream.writeln("ERROR")
663 elif self.dots:
664 self.stream.write('E')
Fred Drake02538202001-03-21 18:09:46 +0000665
666 def addFailure(self, test, err):
667 TestResult.addFailure(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000668 if self.showAll:
669 self.stream.writeln("FAIL")
670 elif self.dots:
671 self.stream.write('F')
Fred Drake02538202001-03-21 18:09:46 +0000672
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000673 def printErrors(self):
674 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000675 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000676 self.printErrorList('ERROR', self.errors)
677 self.printErrorList('FAIL', self.failures)
678
679 def printErrorList(self, flavour, errors):
680 for test, err in errors:
681 self.stream.writeln(self.separator1)
682 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
683 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +0000684 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +0000685
686
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000687class TextTestRunner:
Fred Drake02538202001-03-21 18:09:46 +0000688 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +0000689
Fred Drake02538202001-03-21 18:09:46 +0000690 It prints out the names of tests as they are run, errors as they
691 occur, and a summary of the results at the end of the test run.
692 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000693 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +0000694 self.stream = _WritelnDecorator(stream)
695 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000696 self.verbosity = verbosity
697
698 def _makeResult(self):
699 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000700
701 def run(self, test):
702 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000703 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +0000704 startTime = time.time()
705 test(result)
706 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +0000707 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000708 result.printErrors()
709 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +0000710 run = result.testsRun
711 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +0000712 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +0000713 self.stream.writeln()
714 if not result.wasSuccessful():
715 self.stream.write("FAILED (")
716 failed, errored = map(len, (result.failures, result.errors))
717 if failed:
718 self.stream.write("failures=%d" % failed)
719 if errored:
720 if failed: self.stream.write(", ")
721 self.stream.write("errors=%d" % errored)
722 self.stream.writeln(")")
723 else:
724 self.stream.writeln("OK")
725 return result
Tim Petersa19a1682001-03-29 04:36:09 +0000726
Fred Drake02538202001-03-21 18:09:46 +0000727
Fred Drake02538202001-03-21 18:09:46 +0000728
729##############################################################################
730# Facilities for running tests from the command line
731##############################################################################
732
733class TestProgram:
734 """A command-line program that runs a set of tests; this is primarily
735 for making test modules conveniently executable.
736 """
737 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +0000738Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000739
740Options:
741 -h, --help Show this message
742 -v, --verbose Verbose output
743 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +0000744
745Examples:
746 %(progName)s - run default set of tests
747 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000748 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
749 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +0000750 in MyTestCase
751"""
752 def __init__(self, module='__main__', defaultTest=None,
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000753 argv=None, testRunner=None, testLoader=defaultTestLoader):
Fred Drake02538202001-03-21 18:09:46 +0000754 if type(module) == type(''):
755 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +0000756 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +0000757 self.module = getattr(self.module, part)
758 else:
759 self.module = module
760 if argv is None:
761 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000762 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +0000763 self.defaultTest = defaultTest
764 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000765 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +0000766 self.progName = os.path.basename(argv[0])
767 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +0000768 self.runTests()
769
770 def usageExit(self, msg=None):
771 if msg: print msg
772 print self.USAGE % self.__dict__
773 sys.exit(2)
774
775 def parseArgs(self, argv):
776 import getopt
777 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000778 options, args = getopt.getopt(argv[1:], 'hHvq',
779 ['help','verbose','quiet'])
Fred Drake02538202001-03-21 18:09:46 +0000780 for opt, value in options:
781 if opt in ('-h','-H','--help'):
782 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000783 if opt in ('-q','--quiet'):
784 self.verbosity = 0
785 if opt in ('-v','--verbose'):
786 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +0000787 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000788 self.test = self.testLoader.loadTestsFromModule(self.module)
789 return
Fred Drake02538202001-03-21 18:09:46 +0000790 if len(args) > 0:
791 self.testNames = args
792 else:
793 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000794 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +0000795 except getopt.error, msg:
796 self.usageExit(msg)
797
798 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000799 self.test = self.testLoader.loadTestsFromNames(self.testNames,
800 self.module)
Fred Drake02538202001-03-21 18:09:46 +0000801
802 def runTests(self):
803 if self.testRunner is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000804 self.testRunner = TextTestRunner(verbosity=self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000805 result = self.testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +0000806 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +0000807
808main = TestProgram
809
810
811##############################################################################
812# Executing this module from the command line
813##############################################################################
814
815if __name__ == "__main__":
816 main(module=None)