blob: 70645fbce5db8a2c39d7b2200b612163601acadf [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__
74 if type(clsinfo) in (types.TupleType, types.ListType):
75 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:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000204 self.__testMethodName = methodName
205 testMethod = getattr(self, methodName)
206 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 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +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):
Steve Purcelldc391a62002-08-09 09:46:23 +0000236 return "%s.%s" % (_strclass(self.__class__), self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000237
238 def __str__(self):
Jeremy Hylton22dae282002-08-13 20:43:46 +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>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +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)
Steve Purcell5ddd1a82001-03-22 08:45:36 +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:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +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:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +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:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +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:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +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
Steve Purcell7e743842003-09-22 11:08:12 +0000280 __call__ = run
281
Fred Drake02538202001-03-21 18:09:46 +0000282 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000283 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000284 self.setUp()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000285 getattr(self, self.__testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000286 self.tearDown()
287
Steve Purcell15d89272001-04-12 09:05:01 +0000288 def __exc_info(self):
289 """Return a version of sys.exc_info() with the traceback frame
290 minimised; usually the top level of the traceback frame is not
291 needed.
Fred Drake02538202001-03-21 18:09:46 +0000292 """
Steve Purcell15d89272001-04-12 09:05:01 +0000293 exctype, excvalue, tb = sys.exc_info()
294 if sys.platform[:4] == 'java': ## tracebacks look different in Jython
295 return (exctype, excvalue, tb)
Steve Purcellb8d5f242003-12-06 13:03:13 +0000296 return (exctype, excvalue, tb)
Fred Drake02538202001-03-21 18:09:46 +0000297
Steve Purcell15d89272001-04-12 09:05:01 +0000298 def fail(self, msg=None):
299 """Fail immediately, with the given message."""
300 raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000301
302 def failIf(self, expr, msg=None):
303 "Fail the test if the expression is true."
Steve Purcell15d89272001-04-12 09:05:01 +0000304 if expr: raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000305
Steve Purcell15d89272001-04-12 09:05:01 +0000306 def failUnless(self, expr, msg=None):
307 """Fail the test unless the expression is true."""
308 if not expr: raise self.failureException, msg
309
310 def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
311 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000312 by callableObj when invoked with arguments args and keyword
313 arguments kwargs. If a different type of exception is
314 thrown, it will not be caught, and the test case will be
315 deemed to have suffered an error, exactly as for an
316 unexpected exception.
317 """
318 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000319 callableObj(*args, **kwargs)
Fred Drake02538202001-03-21 18:09:46 +0000320 except excClass:
321 return
322 else:
323 if hasattr(excClass,'__name__'): excName = excClass.__name__
324 else: excName = str(excClass)
Steve Purcell7e743842003-09-22 11:08:12 +0000325 raise self.failureException, "%s not raised" % excName
Fred Drake02538202001-03-21 18:09:46 +0000326
Steve Purcell15d89272001-04-12 09:05:01 +0000327 def failUnlessEqual(self, first, second, msg=None):
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000328 """Fail if the two objects are unequal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000329 operator.
330 """
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000331 if not first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000332 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000333 (msg or '%r != %r' % (first, second))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000334
Steve Purcell15d89272001-04-12 09:05:01 +0000335 def failIfEqual(self, first, second, msg=None):
336 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000337 operator.
338 """
Steve Purcell15d89272001-04-12 09:05:01 +0000339 if first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000340 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000341 (msg or '%r == %r' % (first, second))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000342
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000343 def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
344 """Fail if the two objects are unequal as determined by their
345 difference rounded to the given number of decimal places
346 (default 7) and comparing to zero.
347
Steve Purcell397b45d2003-10-26 10:41:03 +0000348 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000349 as significant digits (measured from the most signficant digit).
350 """
351 if round(second-first, places) != 0:
352 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000353 (msg or '%r != %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000354
355 def failIfAlmostEqual(self, first, second, places=7, msg=None):
356 """Fail if the two objects are equal as determined by their
357 difference rounded to the given number of decimal places
358 (default 7) and comparing to zero.
359
Steve Purcellcca34912003-10-26 16:38:16 +0000360 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000361 as significant digits (measured from the most signficant digit).
362 """
363 if round(second-first, places) == 0:
364 raise self.failureException, \
Walter Dörwald70a6b492004-02-12 17:35:32 +0000365 (msg or '%r == %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000366
Steve Purcell7e743842003-09-22 11:08:12 +0000367 # Synonyms for assertion methods
368
Steve Purcell15d89272001-04-12 09:05:01 +0000369 assertEqual = assertEquals = failUnlessEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000370
Steve Purcell15d89272001-04-12 09:05:01 +0000371 assertNotEqual = assertNotEquals = failIfEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000372
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000373 assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
374
375 assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
376
Steve Purcell15d89272001-04-12 09:05:01 +0000377 assertRaises = failUnlessRaises
378
Steve Purcell7e743842003-09-22 11:08:12 +0000379 assert_ = assertTrue = failUnless
380
381 assertFalse = failIf
Steve Purcell15d89272001-04-12 09:05:01 +0000382
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000383
Fred Drake02538202001-03-21 18:09:46 +0000384
385class TestSuite:
386 """A test suite is a composite test consisting of a number of TestCases.
387
388 For use, create an instance of TestSuite, then add test case instances.
389 When all tests have been added, the suite can be passed to a test
390 runner, such as TextTestRunner. It will run the individual test cases
391 in the order in which they were added, aggregating the results. When
392 subclassing, do not forget to call the base class constructor.
393 """
394 def __init__(self, tests=()):
395 self._tests = []
396 self.addTests(tests)
397
398 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000399 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +0000400
401 __str__ = __repr__
402
Jim Fultonfafd8742004-08-28 15:22:12 +0000403 def __iter__(self):
404 return iter(self._tests)
405
Fred Drake02538202001-03-21 18:09:46 +0000406 def countTestCases(self):
407 cases = 0
408 for test in self._tests:
Steve Purcell7e743842003-09-22 11:08:12 +0000409 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +0000410 return cases
411
412 def addTest(self, test):
413 self._tests.append(test)
414
415 def addTests(self, tests):
416 for test in tests:
417 self.addTest(test)
418
419 def run(self, result):
420 return self(result)
421
422 def __call__(self, result):
423 for test in self._tests:
424 if result.shouldStop:
425 break
426 test(result)
427 return result
428
429 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000430 """Run the tests without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000431 for test in self._tests: test.debug()
Fred Drake02538202001-03-21 18:09:46 +0000432
433
434class FunctionTestCase(TestCase):
435 """A test case that wraps a test function.
436
437 This is useful for slipping pre-existing test functions into the
438 PyUnit framework. Optionally, set-up and tidy-up functions can be
439 supplied. As with TestCase, the tidy-up ('tearDown') function will
440 always be called if the set-up ('setUp') function ran successfully.
441 """
442
443 def __init__(self, testFunc, setUp=None, tearDown=None,
444 description=None):
445 TestCase.__init__(self)
446 self.__setUpFunc = setUp
447 self.__tearDownFunc = tearDown
448 self.__testFunc = testFunc
449 self.__description = description
450
451 def setUp(self):
452 if self.__setUpFunc is not None:
453 self.__setUpFunc()
454
455 def tearDown(self):
456 if self.__tearDownFunc is not None:
457 self.__tearDownFunc()
458
459 def runTest(self):
460 self.__testFunc()
461
462 def id(self):
463 return self.__testFunc.__name__
464
465 def __str__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000466 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +0000467
468 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000469 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
Fred Drake02538202001-03-21 18:09:46 +0000470
471 def shortDescription(self):
472 if self.__description is not None: return self.__description
473 doc = self.__testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +0000474 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +0000475
476
477
478##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000479# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +0000480##############################################################################
481
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000482class TestLoader:
483 """This class is responsible for loading tests according to various
484 criteria and returning them wrapped in a Test
Fred Drake02538202001-03-21 18:09:46 +0000485 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000486 testMethodPrefix = 'test'
487 sortTestMethodsUsing = cmp
488 suiteClass = TestSuite
Fred Drake02538202001-03-21 18:09:46 +0000489
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000490 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000491 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +0000492 if issubclass(testCaseClass, TestSuite):
493 raise TypeError("Test cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +0000494 testCaseNames = self.getTestCaseNames(testCaseClass)
495 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
496 testCaseNames = ['runTest']
497 return self.suiteClass(map(testCaseClass, testCaseNames))
Fred Drake02538202001-03-21 18:09:46 +0000498
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000499 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +0000500 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000501 tests = []
502 for name in dir(module):
503 obj = getattr(module, name)
Guido van Rossum67911372002-09-30 19:25:56 +0000504 if (isinstance(obj, (type, types.ClassType)) and
505 issubclass(obj, TestCase)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000506 tests.append(self.loadTestsFromTestCase(obj))
507 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +0000508
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000509 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000510 """Return a suite of all tests cases given a string specifier.
511
512 The name may resolve either to a module, a test case class, a
513 test method within a test case class, or a callable object which
514 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +0000515
Steve Purcell15d89272001-04-12 09:05:01 +0000516 The method optionally resolves the names relative to a given module.
517 """
Steve Purcell7e743842003-09-22 11:08:12 +0000518 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000519 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +0000520 parts_copy = parts[:]
521 while parts_copy:
522 try:
523 module = __import__('.'.join(parts_copy))
524 break
525 except ImportError:
526 del parts_copy[-1]
527 if not parts_copy: raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +0000528 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000529 obj = module
530 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +0000531 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +0000532
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000533 if type(obj) == types.ModuleType:
534 return self.loadTestsFromModule(obj)
Guido van Rossum67911372002-09-30 19:25:56 +0000535 elif (isinstance(obj, (type, types.ClassType)) and
Steve Purcell397b45d2003-10-26 10:41:03 +0000536 issubclass(obj, TestCase)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000537 return self.loadTestsFromTestCase(obj)
538 elif type(obj) == types.UnboundMethodType:
Steve Purcell7e743842003-09-22 11:08:12 +0000539 return parent(obj.__name__)
Steve Purcell397b45d2003-10-26 10:41:03 +0000540 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +0000541 return obj
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000542 elif callable(obj):
543 test = obj()
Steve Purcell397b45d2003-10-26 10:41:03 +0000544 if not isinstance(test, (TestCase, TestSuite)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000545 raise ValueError, \
Steve Purcell4bc80852001-05-10 01:28:40 +0000546 "calling %s returned %s, not a test" % (obj,test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000547 return test
Fred Drake02538202001-03-21 18:09:46 +0000548 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000549 raise ValueError, "don't know how to make test from: %s" % obj
550
551 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000552 """Return a suite of all tests cases found using the given sequence
553 of string specifiers. See 'loadTestsFromName()'.
554 """
Steve Purcell7e743842003-09-22 11:08:12 +0000555 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000556 return self.suiteClass(suites)
557
558 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000559 """Return a sorted sequence of method names found within testCaseClass
560 """
Steve Purcell7e743842003-09-22 11:08:12 +0000561 def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix):
Steve Purcell31982752003-09-23 08:41:53 +0000562 return attrname.startswith(prefix) and callable(getattr(testCaseClass, attrname))
Steve Purcell7e743842003-09-22 11:08:12 +0000563 testFnNames = filter(isTestMethod, dir(testCaseClass))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000564 for baseclass in testCaseClass.__bases__:
565 for testFnName in self.getTestCaseNames(baseclass):
566 if testFnName not in testFnNames: # handle overridden methods
567 testFnNames.append(testFnName)
568 if self.sortTestMethodsUsing:
569 testFnNames.sort(self.sortTestMethodsUsing)
570 return testFnNames
571
572
573
574defaultTestLoader = TestLoader()
575
576
577##############################################################################
578# Patches for old functions: these functions should be considered obsolete
579##############################################################################
580
581def _makeLoader(prefix, sortUsing, suiteClass=None):
582 loader = TestLoader()
583 loader.sortTestMethodsUsing = sortUsing
584 loader.testMethodPrefix = prefix
585 if suiteClass: loader.suiteClass = suiteClass
586 return loader
587
588def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
589 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
590
591def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
592 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
593
594def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
595 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +0000596
597
598##############################################################################
599# Text UI
600##############################################################################
601
602class _WritelnDecorator:
603 """Used to decorate file-like objects with a handy 'writeln' method"""
604 def __init__(self,stream):
605 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +0000606
607 def __getattr__(self, attr):
608 return getattr(self.stream,attr)
609
Raymond Hettinger91dd19d2003-09-13 02:58:00 +0000610 def writeln(self, arg=None):
611 if arg: self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000612 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +0000613
Fred Drake02538202001-03-21 18:09:46 +0000614
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000615class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +0000616 """A test result class that can print formatted text results to a stream.
617
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000618 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +0000619 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000620 separator1 = '=' * 70
621 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +0000622
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000623 def __init__(self, stream, descriptions, verbosity):
Fred Drake02538202001-03-21 18:09:46 +0000624 TestResult.__init__(self)
625 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000626 self.showAll = verbosity > 1
627 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +0000628 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000629
630 def getDescription(self, test):
631 if self.descriptions:
632 return test.shortDescription() or str(test)
633 else:
634 return str(test)
635
Fred Drake02538202001-03-21 18:09:46 +0000636 def startTest(self, test):
637 TestResult.startTest(self, test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000638 if self.showAll:
639 self.stream.write(self.getDescription(test))
640 self.stream.write(" ... ")
Fred Drake02538202001-03-21 18:09:46 +0000641
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000642 def addSuccess(self, test):
643 TestResult.addSuccess(self, test)
644 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000645 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000646 elif self.dots:
647 self.stream.write('.')
Fred Drake02538202001-03-21 18:09:46 +0000648
649 def addError(self, test, err):
650 TestResult.addError(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000651 if self.showAll:
652 self.stream.writeln("ERROR")
653 elif self.dots:
654 self.stream.write('E')
Fred Drake02538202001-03-21 18:09:46 +0000655
656 def addFailure(self, test, err):
657 TestResult.addFailure(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000658 if self.showAll:
659 self.stream.writeln("FAIL")
660 elif self.dots:
661 self.stream.write('F')
Fred Drake02538202001-03-21 18:09:46 +0000662
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000663 def printErrors(self):
664 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000665 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000666 self.printErrorList('ERROR', self.errors)
667 self.printErrorList('FAIL', self.failures)
668
669 def printErrorList(self, flavour, errors):
670 for test, err in errors:
671 self.stream.writeln(self.separator1)
672 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
673 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +0000674 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +0000675
676
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000677class TextTestRunner:
Fred Drake02538202001-03-21 18:09:46 +0000678 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +0000679
Fred Drake02538202001-03-21 18:09:46 +0000680 It prints out the names of tests as they are run, errors as they
681 occur, and a summary of the results at the end of the test run.
682 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000683 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +0000684 self.stream = _WritelnDecorator(stream)
685 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000686 self.verbosity = verbosity
687
688 def _makeResult(self):
689 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000690
691 def run(self, test):
692 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000693 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +0000694 startTime = time.time()
695 test(result)
696 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +0000697 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000698 result.printErrors()
699 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +0000700 run = result.testsRun
701 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +0000702 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +0000703 self.stream.writeln()
704 if not result.wasSuccessful():
705 self.stream.write("FAILED (")
706 failed, errored = map(len, (result.failures, result.errors))
707 if failed:
708 self.stream.write("failures=%d" % failed)
709 if errored:
710 if failed: self.stream.write(", ")
711 self.stream.write("errors=%d" % errored)
712 self.stream.writeln(")")
713 else:
714 self.stream.writeln("OK")
715 return result
Tim Petersa19a1682001-03-29 04:36:09 +0000716
Fred Drake02538202001-03-21 18:09:46 +0000717
Fred Drake02538202001-03-21 18:09:46 +0000718
719##############################################################################
720# Facilities for running tests from the command line
721##############################################################################
722
723class TestProgram:
724 """A command-line program that runs a set of tests; this is primarily
725 for making test modules conveniently executable.
726 """
727 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +0000728Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000729
730Options:
731 -h, --help Show this message
732 -v, --verbose Verbose output
733 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +0000734
735Examples:
736 %(progName)s - run default set of tests
737 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000738 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
739 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +0000740 in MyTestCase
741"""
742 def __init__(self, module='__main__', defaultTest=None,
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000743 argv=None, testRunner=None, testLoader=defaultTestLoader):
Fred Drake02538202001-03-21 18:09:46 +0000744 if type(module) == type(''):
745 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +0000746 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +0000747 self.module = getattr(self.module, part)
748 else:
749 self.module = module
750 if argv is None:
751 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000752 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +0000753 self.defaultTest = defaultTest
754 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000755 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +0000756 self.progName = os.path.basename(argv[0])
757 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +0000758 self.runTests()
759
760 def usageExit(self, msg=None):
761 if msg: print msg
762 print self.USAGE % self.__dict__
763 sys.exit(2)
764
765 def parseArgs(self, argv):
766 import getopt
767 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000768 options, args = getopt.getopt(argv[1:], 'hHvq',
769 ['help','verbose','quiet'])
Fred Drake02538202001-03-21 18:09:46 +0000770 for opt, value in options:
771 if opt in ('-h','-H','--help'):
772 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000773 if opt in ('-q','--quiet'):
774 self.verbosity = 0
775 if opt in ('-v','--verbose'):
776 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +0000777 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000778 self.test = self.testLoader.loadTestsFromModule(self.module)
779 return
Fred Drake02538202001-03-21 18:09:46 +0000780 if len(args) > 0:
781 self.testNames = args
782 else:
783 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000784 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +0000785 except getopt.error, msg:
786 self.usageExit(msg)
787
788 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000789 self.test = self.testLoader.loadTestsFromNames(self.testNames,
790 self.module)
Fred Drake02538202001-03-21 18:09:46 +0000791
792 def runTests(self):
793 if self.testRunner is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000794 self.testRunner = TextTestRunner(verbosity=self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000795 result = self.testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +0000796 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +0000797
798main = TestProgram
799
800
801##############################################################################
802# Executing this module from the command line
803##############################################################################
804
805if __name__ == "__main__":
806 main(module=None)