blob: ae751af10e3ff93a2db6c1c2222e6dc486828565 [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
Fred Drake02538202001-03-21 18:09:46 +000030Copyright (c) 1999, 2000, 2001 Steve Purcell
31This 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 Purcell824574d2002-08-08 13:38:02 +000049__version__ = "#Revision: 1.45 $"[11:-2]
Fred Drake02538202001-03-21 18:09:46 +000050
51import time
52import sys
53import traceback
54import string
55import os
Steve Purcell5ddd1a82001-03-22 08:45:36 +000056import types
Fred Drake02538202001-03-21 18:09:46 +000057
58##############################################################################
59# Test framework core
60##############################################################################
61
Steve Purcell824574d2002-08-08 13:38:02 +000062# All classes defined herein are 'new-style' classes, allowing use of 'super()'
63__metaclass__ = type
64
Fred Drake02538202001-03-21 18:09:46 +000065class TestResult:
66 """Holder for test result information.
67
68 Test results are automatically managed by the TestCase and TestSuite
69 classes, and do not need to be explicitly manipulated by writers of tests.
70
71 Each instance holds the total number of tests run, and collections of
72 failures and errors that occurred among those test runs. The collections
Steve Purcell7b065702001-09-06 08:24:40 +000073 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
Fred Drake656f9ec2001-09-06 19:13:14 +000074 formatted traceback of the error that occurred.
Fred Drake02538202001-03-21 18:09:46 +000075 """
76 def __init__(self):
77 self.failures = []
78 self.errors = []
79 self.testsRun = 0
80 self.shouldStop = 0
81
82 def startTest(self, test):
83 "Called when the given test is about to be run"
84 self.testsRun = self.testsRun + 1
85
86 def stopTest(self, test):
87 "Called when the given test has been run"
88 pass
89
90 def addError(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +000091 """Called when an error has occurred. 'err' is a tuple of values as
92 returned by sys.exc_info().
93 """
94 self.errors.append((test, self._exc_info_to_string(err)))
Fred Drake02538202001-03-21 18:09:46 +000095
96 def addFailure(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +000097 """Called when an error has occurred. 'err' is a tuple of values as
98 returned by sys.exc_info()."""
99 self.failures.append((test, self._exc_info_to_string(err)))
Fred Drake02538202001-03-21 18:09:46 +0000100
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000101 def addSuccess(self, test):
102 "Called when a test has completed successfully"
103 pass
104
Fred Drake02538202001-03-21 18:09:46 +0000105 def wasSuccessful(self):
106 "Tells whether or not this result was a success"
107 return len(self.failures) == len(self.errors) == 0
108
109 def stop(self):
110 "Indicates that the tests should be aborted"
111 self.shouldStop = 1
Tim Petersa19a1682001-03-29 04:36:09 +0000112
Steve Purcell7b065702001-09-06 08:24:40 +0000113 def _exc_info_to_string(self, err):
114 """Converts a sys.exc_info()-style tuple of values into a string."""
115 return string.join(apply(traceback.format_exception, err), '')
116
Fred Drake02538202001-03-21 18:09:46 +0000117 def __repr__(self):
118 return "<%s run=%i errors=%i failures=%i>" % \
119 (self.__class__, self.testsRun, len(self.errors),
120 len(self.failures))
121
122
123class TestCase:
124 """A class whose instances are single test cases.
125
Fred Drake02538202001-03-21 18:09:46 +0000126 By default, the test code itself should be placed in a method named
127 'runTest'.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000128
Tim Petersa19a1682001-03-29 04:36:09 +0000129 If the fixture may be used for many test cases, create as
Fred Drake02538202001-03-21 18:09:46 +0000130 many test methods as are needed. When instantiating such a TestCase
131 subclass, specify in the constructor arguments the name of the test method
132 that the instance is to execute.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000133
Tim Petersa19a1682001-03-29 04:36:09 +0000134 Test authors should subclass TestCase for their own tests. Construction
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000135 and deconstruction of the test's environment ('fixture') can be
136 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
137
138 If it is necessary to override the __init__ method, the base class
139 __init__ method must always be called. It is important that subclasses
140 should not change the signature of their __init__ method, since instances
141 of the classes are instantiated automatically by parts of the framework
142 in order to be run.
Fred Drake02538202001-03-21 18:09:46 +0000143 """
Steve Purcell15d89272001-04-12 09:05:01 +0000144
145 # This attribute determines which exception will be raised when
146 # the instance's assertion methods fail; test methods raising this
147 # exception will be deemed to have 'failed' rather than 'errored'
148
149 failureException = AssertionError
150
Fred Drake02538202001-03-21 18:09:46 +0000151 def __init__(self, methodName='runTest'):
152 """Create an instance of the class that will use the named test
153 method when executed. Raises a ValueError if the instance does
154 not have a method with the specified name.
155 """
156 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000157 self.__testMethodName = methodName
158 testMethod = getattr(self, methodName)
159 self.__testMethodDoc = testMethod.__doc__
Fred Drake02538202001-03-21 18:09:46 +0000160 except AttributeError:
161 raise ValueError, "no such test method in %s: %s" % \
162 (self.__class__, methodName)
163
164 def setUp(self):
165 "Hook method for setting up the test fixture before exercising it."
166 pass
167
168 def tearDown(self):
169 "Hook method for deconstructing the test fixture after testing it."
170 pass
171
172 def countTestCases(self):
173 return 1
174
175 def defaultTestResult(self):
176 return TestResult()
177
178 def shortDescription(self):
179 """Returns a one-line description of the test, or None if no
180 description has been provided.
181
182 The default implementation of this method returns the first line of
183 the specified test method's docstring.
184 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000185 doc = self.__testMethodDoc
Fred Drake02538202001-03-21 18:09:46 +0000186 return doc and string.strip(string.split(doc, "\n")[0]) or None
187
188 def id(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000189 return "%s.%s" % (self.__class__, self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000190
191 def __str__(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000192 return "%s (%s)" % (self.__testMethodName, self.__class__)
Fred Drake02538202001-03-21 18:09:46 +0000193
194 def __repr__(self):
195 return "<%s testMethod=%s>" % \
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000196 (self.__class__, self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000197
198 def run(self, result=None):
199 return self(result)
200
201 def __call__(self, result=None):
202 if result is None: result = self.defaultTestResult()
203 result.startTest(self)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000204 testMethod = getattr(self, self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000205 try:
206 try:
207 self.setUp()
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000208 except KeyboardInterrupt:
209 raise
Fred Drake02538202001-03-21 18:09:46 +0000210 except:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000211 result.addError(self, self.__exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000212 return
213
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000214 ok = 0
Fred Drake02538202001-03-21 18:09:46 +0000215 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000216 testMethod()
217 ok = 1
Steve Purcell15d89272001-04-12 09:05:01 +0000218 except self.failureException, e:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000219 result.addFailure(self, self.__exc_info())
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000220 except KeyboardInterrupt:
221 raise
Fred Drake02538202001-03-21 18:09:46 +0000222 except:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000223 result.addError(self, self.__exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000224
225 try:
226 self.tearDown()
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000227 except KeyboardInterrupt:
228 raise
Fred Drake02538202001-03-21 18:09:46 +0000229 except:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000230 result.addError(self, self.__exc_info())
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000231 ok = 0
232 if ok: result.addSuccess(self)
Fred Drake02538202001-03-21 18:09:46 +0000233 finally:
234 result.stopTest(self)
235
236 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000237 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000238 self.setUp()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000239 getattr(self, self.__testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000240 self.tearDown()
241
Steve Purcell15d89272001-04-12 09:05:01 +0000242 def __exc_info(self):
243 """Return a version of sys.exc_info() with the traceback frame
244 minimised; usually the top level of the traceback frame is not
245 needed.
Fred Drake02538202001-03-21 18:09:46 +0000246 """
Steve Purcell15d89272001-04-12 09:05:01 +0000247 exctype, excvalue, tb = sys.exc_info()
248 if sys.platform[:4] == 'java': ## tracebacks look different in Jython
249 return (exctype, excvalue, tb)
250 newtb = tb.tb_next
251 if newtb is None:
252 return (exctype, excvalue, tb)
253 return (exctype, excvalue, newtb)
Fred Drake02538202001-03-21 18:09:46 +0000254
Steve Purcell15d89272001-04-12 09:05:01 +0000255 def fail(self, msg=None):
256 """Fail immediately, with the given message."""
257 raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000258
259 def failIf(self, expr, msg=None):
260 "Fail the test if the expression is true."
Steve Purcell15d89272001-04-12 09:05:01 +0000261 if expr: raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000262
Steve Purcell15d89272001-04-12 09:05:01 +0000263 def failUnless(self, expr, msg=None):
264 """Fail the test unless the expression is true."""
265 if not expr: raise self.failureException, msg
266
267 def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
268 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000269 by callableObj when invoked with arguments args and keyword
270 arguments kwargs. If a different type of exception is
271 thrown, it will not be caught, and the test case will be
272 deemed to have suffered an error, exactly as for an
273 unexpected exception.
274 """
275 try:
276 apply(callableObj, args, kwargs)
277 except excClass:
278 return
279 else:
280 if hasattr(excClass,'__name__'): excName = excClass.__name__
281 else: excName = str(excClass)
Steve Purcell15d89272001-04-12 09:05:01 +0000282 raise self.failureException, excName
Fred Drake02538202001-03-21 18:09:46 +0000283
Steve Purcell15d89272001-04-12 09:05:01 +0000284 def failUnlessEqual(self, first, second, msg=None):
285 """Fail if the two objects are unequal as determined by the '!='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000286 operator.
287 """
Steve Purcell15d89272001-04-12 09:05:01 +0000288 if first != second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000289 raise self.failureException, \
290 (msg or '%s != %s' % (`first`, `second`))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000291
Steve Purcell15d89272001-04-12 09:05:01 +0000292 def failIfEqual(self, first, second, msg=None):
293 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000294 operator.
295 """
Steve Purcell15d89272001-04-12 09:05:01 +0000296 if first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000297 raise self.failureException, \
298 (msg or '%s == %s' % (`first`, `second`))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000299
Steve Purcell15d89272001-04-12 09:05:01 +0000300 assertEqual = assertEquals = failUnlessEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000301
Steve Purcell15d89272001-04-12 09:05:01 +0000302 assertNotEqual = assertNotEquals = failIfEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000303
Steve Purcell15d89272001-04-12 09:05:01 +0000304 assertRaises = failUnlessRaises
305
306 assert_ = failUnless
307
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000308
Fred Drake02538202001-03-21 18:09:46 +0000309
310class TestSuite:
311 """A test suite is a composite test consisting of a number of TestCases.
312
313 For use, create an instance of TestSuite, then add test case instances.
314 When all tests have been added, the suite can be passed to a test
315 runner, such as TextTestRunner. It will run the individual test cases
316 in the order in which they were added, aggregating the results. When
317 subclassing, do not forget to call the base class constructor.
318 """
319 def __init__(self, tests=()):
320 self._tests = []
321 self.addTests(tests)
322
323 def __repr__(self):
324 return "<%s tests=%s>" % (self.__class__, self._tests)
325
326 __str__ = __repr__
327
328 def countTestCases(self):
329 cases = 0
330 for test in self._tests:
331 cases = cases + test.countTestCases()
332 return cases
333
334 def addTest(self, test):
335 self._tests.append(test)
336
337 def addTests(self, tests):
338 for test in tests:
339 self.addTest(test)
340
341 def run(self, result):
342 return self(result)
343
344 def __call__(self, result):
345 for test in self._tests:
346 if result.shouldStop:
347 break
348 test(result)
349 return result
350
351 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000352 """Run the tests without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000353 for test in self._tests: test.debug()
Fred Drake02538202001-03-21 18:09:46 +0000354
355
356class FunctionTestCase(TestCase):
357 """A test case that wraps a test function.
358
359 This is useful for slipping pre-existing test functions into the
360 PyUnit framework. Optionally, set-up and tidy-up functions can be
361 supplied. As with TestCase, the tidy-up ('tearDown') function will
362 always be called if the set-up ('setUp') function ran successfully.
363 """
364
365 def __init__(self, testFunc, setUp=None, tearDown=None,
366 description=None):
367 TestCase.__init__(self)
368 self.__setUpFunc = setUp
369 self.__tearDownFunc = tearDown
370 self.__testFunc = testFunc
371 self.__description = description
372
373 def setUp(self):
374 if self.__setUpFunc is not None:
375 self.__setUpFunc()
376
377 def tearDown(self):
378 if self.__tearDownFunc is not None:
379 self.__tearDownFunc()
380
381 def runTest(self):
382 self.__testFunc()
383
384 def id(self):
385 return self.__testFunc.__name__
386
387 def __str__(self):
388 return "%s (%s)" % (self.__class__, self.__testFunc.__name__)
389
390 def __repr__(self):
391 return "<%s testFunc=%s>" % (self.__class__, self.__testFunc)
392
393 def shortDescription(self):
394 if self.__description is not None: return self.__description
395 doc = self.__testFunc.__doc__
396 return doc and string.strip(string.split(doc, "\n")[0]) or None
397
398
399
400##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000401# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +0000402##############################################################################
403
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000404class TestLoader:
405 """This class is responsible for loading tests according to various
406 criteria and returning them wrapped in a Test
Fred Drake02538202001-03-21 18:09:46 +0000407 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000408 testMethodPrefix = 'test'
409 sortTestMethodsUsing = cmp
410 suiteClass = TestSuite
Fred Drake02538202001-03-21 18:09:46 +0000411
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000412 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000413 """Return a suite of all tests cases contained in testCaseClass"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000414 return self.suiteClass(map(testCaseClass,
415 self.getTestCaseNames(testCaseClass)))
Fred Drake02538202001-03-21 18:09:46 +0000416
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000417 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +0000418 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000419 tests = []
420 for name in dir(module):
421 obj = getattr(module, name)
422 if type(obj) == types.ClassType and issubclass(obj, TestCase):
423 tests.append(self.loadTestsFromTestCase(obj))
424 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +0000425
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000426 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000427 """Return a suite of all tests cases given a string specifier.
428
429 The name may resolve either to a module, a test case class, a
430 test method within a test case class, or a callable object which
431 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +0000432
Steve Purcell15d89272001-04-12 09:05:01 +0000433 The method optionally resolves the names relative to a given module.
434 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000435 parts = string.split(name, '.')
436 if module is None:
437 if not parts:
438 raise ValueError, "incomplete test name: %s" % name
439 else:
Steve Purcell17a781b2001-04-09 15:37:31 +0000440 parts_copy = parts[:]
441 while parts_copy:
442 try:
443 module = __import__(string.join(parts_copy,'.'))
444 break
445 except ImportError:
446 del parts_copy[-1]
447 if not parts_copy: raise
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000448 parts = parts[1:]
449 obj = module
450 for part in parts:
451 obj = getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +0000452
Steve Purcelle00dde22001-08-08 07:57:26 +0000453 import unittest
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000454 if type(obj) == types.ModuleType:
455 return self.loadTestsFromModule(obj)
Steve Purcelle00dde22001-08-08 07:57:26 +0000456 elif type(obj) == types.ClassType and issubclass(obj, unittest.TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000457 return self.loadTestsFromTestCase(obj)
458 elif type(obj) == types.UnboundMethodType:
459 return obj.im_class(obj.__name__)
460 elif callable(obj):
461 test = obj()
Steve Purcelle00dde22001-08-08 07:57:26 +0000462 if not isinstance(test, unittest.TestCase) and \
463 not isinstance(test, unittest.TestSuite):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000464 raise ValueError, \
Steve Purcell4bc80852001-05-10 01:28:40 +0000465 "calling %s returned %s, not a test" % (obj,test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000466 return test
Fred Drake02538202001-03-21 18:09:46 +0000467 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000468 raise ValueError, "don't know how to make test from: %s" % obj
469
470 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000471 """Return a suite of all tests cases found using the given sequence
472 of string specifiers. See 'loadTestsFromName()'.
473 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000474 suites = []
475 for name in names:
476 suites.append(self.loadTestsFromName(name, module))
477 return self.suiteClass(suites)
478
479 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000480 """Return a sorted sequence of method names found within testCaseClass
481 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000482 testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
483 dir(testCaseClass))
484 for baseclass in testCaseClass.__bases__:
485 for testFnName in self.getTestCaseNames(baseclass):
486 if testFnName not in testFnNames: # handle overridden methods
487 testFnNames.append(testFnName)
488 if self.sortTestMethodsUsing:
489 testFnNames.sort(self.sortTestMethodsUsing)
490 return testFnNames
491
492
493
494defaultTestLoader = TestLoader()
495
496
497##############################################################################
498# Patches for old functions: these functions should be considered obsolete
499##############################################################################
500
501def _makeLoader(prefix, sortUsing, suiteClass=None):
502 loader = TestLoader()
503 loader.sortTestMethodsUsing = sortUsing
504 loader.testMethodPrefix = prefix
505 if suiteClass: loader.suiteClass = suiteClass
506 return loader
507
508def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
509 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
510
511def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
512 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
513
514def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
515 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +0000516
517
518##############################################################################
519# Text UI
520##############################################################################
521
522class _WritelnDecorator:
523 """Used to decorate file-like objects with a handy 'writeln' method"""
524 def __init__(self,stream):
525 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +0000526
527 def __getattr__(self, attr):
528 return getattr(self.stream,attr)
529
530 def writeln(self, *args):
531 if args: apply(self.write, args)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000532 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +0000533
Fred Drake02538202001-03-21 18:09:46 +0000534
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000535class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +0000536 """A test result class that can print formatted text results to a stream.
537
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000538 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +0000539 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000540 separator1 = '=' * 70
541 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +0000542
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000543 def __init__(self, stream, descriptions, verbosity):
Fred Drake02538202001-03-21 18:09:46 +0000544 TestResult.__init__(self)
545 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000546 self.showAll = verbosity > 1
547 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +0000548 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000549
550 def getDescription(self, test):
551 if self.descriptions:
552 return test.shortDescription() or str(test)
553 else:
554 return str(test)
555
Fred Drake02538202001-03-21 18:09:46 +0000556 def startTest(self, test):
557 TestResult.startTest(self, test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000558 if self.showAll:
559 self.stream.write(self.getDescription(test))
560 self.stream.write(" ... ")
Fred Drake02538202001-03-21 18:09:46 +0000561
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000562 def addSuccess(self, test):
563 TestResult.addSuccess(self, test)
564 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000565 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000566 elif self.dots:
567 self.stream.write('.')
Fred Drake02538202001-03-21 18:09:46 +0000568
569 def addError(self, test, err):
570 TestResult.addError(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000571 if self.showAll:
572 self.stream.writeln("ERROR")
573 elif self.dots:
574 self.stream.write('E')
Fred Drake02538202001-03-21 18:09:46 +0000575
576 def addFailure(self, test, err):
577 TestResult.addFailure(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000578 if self.showAll:
579 self.stream.writeln("FAIL")
580 elif self.dots:
581 self.stream.write('F')
Fred Drake02538202001-03-21 18:09:46 +0000582
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000583 def printErrors(self):
584 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000585 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000586 self.printErrorList('ERROR', self.errors)
587 self.printErrorList('FAIL', self.failures)
588
589 def printErrorList(self, flavour, errors):
590 for test, err in errors:
591 self.stream.writeln(self.separator1)
592 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
593 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +0000594 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +0000595
596
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000597class TextTestRunner:
Fred Drake02538202001-03-21 18:09:46 +0000598 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +0000599
Fred Drake02538202001-03-21 18:09:46 +0000600 It prints out the names of tests as they are run, errors as they
601 occur, and a summary of the results at the end of the test run.
602 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000603 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +0000604 self.stream = _WritelnDecorator(stream)
605 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000606 self.verbosity = verbosity
607
608 def _makeResult(self):
609 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000610
611 def run(self, test):
612 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000613 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +0000614 startTime = time.time()
615 test(result)
616 stopTime = time.time()
617 timeTaken = float(stopTime - startTime)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000618 result.printErrors()
619 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +0000620 run = result.testsRun
621 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +0000622 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +0000623 self.stream.writeln()
624 if not result.wasSuccessful():
625 self.stream.write("FAILED (")
626 failed, errored = map(len, (result.failures, result.errors))
627 if failed:
628 self.stream.write("failures=%d" % failed)
629 if errored:
630 if failed: self.stream.write(", ")
631 self.stream.write("errors=%d" % errored)
632 self.stream.writeln(")")
633 else:
634 self.stream.writeln("OK")
635 return result
Tim Petersa19a1682001-03-29 04:36:09 +0000636
Fred Drake02538202001-03-21 18:09:46 +0000637
Fred Drake02538202001-03-21 18:09:46 +0000638
639##############################################################################
640# Facilities for running tests from the command line
641##############################################################################
642
643class TestProgram:
644 """A command-line program that runs a set of tests; this is primarily
645 for making test modules conveniently executable.
646 """
647 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +0000648Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000649
650Options:
651 -h, --help Show this message
652 -v, --verbose Verbose output
653 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +0000654
655Examples:
656 %(progName)s - run default set of tests
657 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000658 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
659 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +0000660 in MyTestCase
661"""
662 def __init__(self, module='__main__', defaultTest=None,
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000663 argv=None, testRunner=None, testLoader=defaultTestLoader):
Fred Drake02538202001-03-21 18:09:46 +0000664 if type(module) == type(''):
665 self.module = __import__(module)
666 for part in string.split(module,'.')[1:]:
667 self.module = getattr(self.module, part)
668 else:
669 self.module = module
670 if argv is None:
671 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000672 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +0000673 self.defaultTest = defaultTest
674 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000675 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +0000676 self.progName = os.path.basename(argv[0])
677 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +0000678 self.runTests()
679
680 def usageExit(self, msg=None):
681 if msg: print msg
682 print self.USAGE % self.__dict__
683 sys.exit(2)
684
685 def parseArgs(self, argv):
686 import getopt
687 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000688 options, args = getopt.getopt(argv[1:], 'hHvq',
689 ['help','verbose','quiet'])
Fred Drake02538202001-03-21 18:09:46 +0000690 for opt, value in options:
691 if opt in ('-h','-H','--help'):
692 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000693 if opt in ('-q','--quiet'):
694 self.verbosity = 0
695 if opt in ('-v','--verbose'):
696 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +0000697 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000698 self.test = self.testLoader.loadTestsFromModule(self.module)
699 return
Fred Drake02538202001-03-21 18:09:46 +0000700 if len(args) > 0:
701 self.testNames = args
702 else:
703 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000704 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +0000705 except getopt.error, msg:
706 self.usageExit(msg)
707
708 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000709 self.test = self.testLoader.loadTestsFromNames(self.testNames,
710 self.module)
Fred Drake02538202001-03-21 18:09:46 +0000711
712 def runTests(self):
713 if self.testRunner is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000714 self.testRunner = TextTestRunner(verbosity=self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000715 result = self.testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +0000716 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +0000717
718main = TestProgram
719
720
721##############################################################################
722# Executing this module from the command line
723##############################################################################
724
725if __name__ == "__main__":
726 main(module=None)