blob: 043b9a848a4f824e02504b66f0157c57571552dd [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 Purcelldc391a62002-08-09 09:46:23 +000049__version__ = "#Revision: 1.46 $"[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##############################################################################
Steve Purcelld75e7e42003-09-15 11:01:21 +000059# Exported classes and functions
60##############################################################################
61__all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
62 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
63
64# Expose obsolete functions for backwards compatability
65__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
66
67
68##############################################################################
Fred Drake02538202001-03-21 18:09:46 +000069# Test framework core
70##############################################################################
71
Steve Purcell824574d2002-08-08 13:38:02 +000072# All classes defined herein are 'new-style' classes, allowing use of 'super()'
73__metaclass__ = type
74
Steve Purcelldc391a62002-08-09 09:46:23 +000075def _strclass(cls):
76 return "%s.%s" % (cls.__module__, cls.__name__)
77
Fred Drake02538202001-03-21 18:09:46 +000078class TestResult:
79 """Holder for test result information.
80
81 Test results are automatically managed by the TestCase and TestSuite
82 classes, and do not need to be explicitly manipulated by writers of tests.
83
84 Each instance holds the total number of tests run, and collections of
85 failures and errors that occurred among those test runs. The collections
Steve Purcell7b065702001-09-06 08:24:40 +000086 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
Fred Drake656f9ec2001-09-06 19:13:14 +000087 formatted traceback of the error that occurred.
Fred Drake02538202001-03-21 18:09:46 +000088 """
89 def __init__(self):
90 self.failures = []
91 self.errors = []
92 self.testsRun = 0
93 self.shouldStop = 0
94
95 def startTest(self, test):
96 "Called when the given test is about to be run"
97 self.testsRun = self.testsRun + 1
98
99 def stopTest(self, test):
100 "Called when the given test has been run"
101 pass
102
103 def addError(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000104 """Called when an error has occurred. 'err' is a tuple of values as
105 returned by sys.exc_info().
106 """
107 self.errors.append((test, self._exc_info_to_string(err)))
Fred Drake02538202001-03-21 18:09:46 +0000108
109 def addFailure(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000110 """Called when an error has occurred. 'err' is a tuple of values as
111 returned by sys.exc_info()."""
112 self.failures.append((test, self._exc_info_to_string(err)))
Fred Drake02538202001-03-21 18:09:46 +0000113
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000114 def addSuccess(self, test):
115 "Called when a test has completed successfully"
116 pass
117
Fred Drake02538202001-03-21 18:09:46 +0000118 def wasSuccessful(self):
119 "Tells whether or not this result was a success"
120 return len(self.failures) == len(self.errors) == 0
121
122 def stop(self):
123 "Indicates that the tests should be aborted"
124 self.shouldStop = 1
Tim Petersa19a1682001-03-29 04:36:09 +0000125
Steve Purcell7b065702001-09-06 08:24:40 +0000126 def _exc_info_to_string(self, err):
127 """Converts a sys.exc_info()-style tuple of values into a string."""
Guido van Rossum68468eb2003-02-27 20:14:51 +0000128 return string.join(traceback.format_exception(*err), '')
Steve Purcell7b065702001-09-06 08:24:40 +0000129
Fred Drake02538202001-03-21 18:09:46 +0000130 def __repr__(self):
131 return "<%s run=%i errors=%i failures=%i>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +0000132 (_strclass(self.__class__), self.testsRun, len(self.errors),
Fred Drake02538202001-03-21 18:09:46 +0000133 len(self.failures))
134
135
136class TestCase:
137 """A class whose instances are single test cases.
138
Fred Drake02538202001-03-21 18:09:46 +0000139 By default, the test code itself should be placed in a method named
140 'runTest'.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000141
Tim Petersa19a1682001-03-29 04:36:09 +0000142 If the fixture may be used for many test cases, create as
Fred Drake02538202001-03-21 18:09:46 +0000143 many test methods as are needed. When instantiating such a TestCase
144 subclass, specify in the constructor arguments the name of the test method
145 that the instance is to execute.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000146
Tim Petersa19a1682001-03-29 04:36:09 +0000147 Test authors should subclass TestCase for their own tests. Construction
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000148 and deconstruction of the test's environment ('fixture') can be
149 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
150
151 If it is necessary to override the __init__ method, the base class
152 __init__ method must always be called. It is important that subclasses
153 should not change the signature of their __init__ method, since instances
154 of the classes are instantiated automatically by parts of the framework
155 in order to be run.
Fred Drake02538202001-03-21 18:09:46 +0000156 """
Steve Purcell15d89272001-04-12 09:05:01 +0000157
158 # This attribute determines which exception will be raised when
159 # the instance's assertion methods fail; test methods raising this
160 # exception will be deemed to have 'failed' rather than 'errored'
161
162 failureException = AssertionError
163
Fred Drake02538202001-03-21 18:09:46 +0000164 def __init__(self, methodName='runTest'):
165 """Create an instance of the class that will use the named test
166 method when executed. Raises a ValueError if the instance does
167 not have a method with the specified name.
168 """
169 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000170 self.__testMethodName = methodName
171 testMethod = getattr(self, methodName)
172 self.__testMethodDoc = testMethod.__doc__
Fred Drake02538202001-03-21 18:09:46 +0000173 except AttributeError:
174 raise ValueError, "no such test method in %s: %s" % \
175 (self.__class__, methodName)
176
177 def setUp(self):
178 "Hook method for setting up the test fixture before exercising it."
179 pass
180
181 def tearDown(self):
182 "Hook method for deconstructing the test fixture after testing it."
183 pass
184
185 def countTestCases(self):
186 return 1
187
188 def defaultTestResult(self):
189 return TestResult()
190
191 def shortDescription(self):
192 """Returns a one-line description of the test, or None if no
193 description has been provided.
194
195 The default implementation of this method returns the first line of
196 the specified test method's docstring.
197 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000198 doc = self.__testMethodDoc
Fred Drake02538202001-03-21 18:09:46 +0000199 return doc and string.strip(string.split(doc, "\n")[0]) or None
200
201 def id(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000202 return "%s.%s" % (_strclass(self.__class__), self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000203
204 def __str__(self):
Jeremy Hylton22dae282002-08-13 20:43:46 +0000205 return "%s (%s)" % (self.__testMethodName, _strclass(self.__class__))
Fred Drake02538202001-03-21 18:09:46 +0000206
207 def __repr__(self):
208 return "<%s testMethod=%s>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +0000209 (_strclass(self.__class__), self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000210
211 def run(self, result=None):
212 return self(result)
213
214 def __call__(self, result=None):
215 if result is None: result = self.defaultTestResult()
216 result.startTest(self)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000217 testMethod = getattr(self, self.__testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000218 try:
219 try:
220 self.setUp()
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000221 except KeyboardInterrupt:
222 raise
Fred Drake02538202001-03-21 18:09:46 +0000223 except:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000224 result.addError(self, self.__exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000225 return
226
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000227 ok = 0
Fred Drake02538202001-03-21 18:09:46 +0000228 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000229 testMethod()
230 ok = 1
Skip Montanaroae5c37b2003-07-13 15:18:12 +0000231 except self.failureException:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000232 result.addFailure(self, self.__exc_info())
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000233 except KeyboardInterrupt:
234 raise
Fred Drake02538202001-03-21 18:09:46 +0000235 except:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000236 result.addError(self, self.__exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000237
238 try:
239 self.tearDown()
Guido van Rossum202dd1e2001-12-07 03:39:34 +0000240 except KeyboardInterrupt:
241 raise
Fred Drake02538202001-03-21 18:09:46 +0000242 except:
Jeremy Hyltonefef5da2001-10-22 18:14:15 +0000243 result.addError(self, self.__exc_info())
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000244 ok = 0
245 if ok: result.addSuccess(self)
Fred Drake02538202001-03-21 18:09:46 +0000246 finally:
247 result.stopTest(self)
248
249 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000250 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000251 self.setUp()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000252 getattr(self, self.__testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000253 self.tearDown()
254
Steve Purcell15d89272001-04-12 09:05:01 +0000255 def __exc_info(self):
256 """Return a version of sys.exc_info() with the traceback frame
257 minimised; usually the top level of the traceback frame is not
258 needed.
Fred Drake02538202001-03-21 18:09:46 +0000259 """
Steve Purcell15d89272001-04-12 09:05:01 +0000260 exctype, excvalue, tb = sys.exc_info()
261 if sys.platform[:4] == 'java': ## tracebacks look different in Jython
262 return (exctype, excvalue, tb)
263 newtb = tb.tb_next
264 if newtb is None:
265 return (exctype, excvalue, tb)
266 return (exctype, excvalue, newtb)
Fred Drake02538202001-03-21 18:09:46 +0000267
Steve Purcell15d89272001-04-12 09:05:01 +0000268 def fail(self, msg=None):
269 """Fail immediately, with the given message."""
270 raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000271
272 def failIf(self, expr, msg=None):
273 "Fail the test if the expression is true."
Steve Purcell15d89272001-04-12 09:05:01 +0000274 if expr: raise self.failureException, msg
Fred Drake02538202001-03-21 18:09:46 +0000275
Steve Purcell15d89272001-04-12 09:05:01 +0000276 def failUnless(self, expr, msg=None):
277 """Fail the test unless the expression is true."""
278 if not expr: raise self.failureException, msg
279
280 def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
281 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000282 by callableObj when invoked with arguments args and keyword
283 arguments kwargs. If a different type of exception is
284 thrown, it will not be caught, and the test case will be
285 deemed to have suffered an error, exactly as for an
286 unexpected exception.
287 """
288 try:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000289 callableObj(*args, **kwargs)
Fred Drake02538202001-03-21 18:09:46 +0000290 except excClass:
291 return
292 else:
293 if hasattr(excClass,'__name__'): excName = excClass.__name__
294 else: excName = str(excClass)
Steve Purcell15d89272001-04-12 09:05:01 +0000295 raise self.failureException, excName
Fred Drake02538202001-03-21 18:09:46 +0000296
Steve Purcell15d89272001-04-12 09:05:01 +0000297 def failUnlessEqual(self, first, second, msg=None):
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000298 """Fail if the two objects are unequal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000299 operator.
300 """
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000301 if not first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000302 raise self.failureException, \
303 (msg or '%s != %s' % (`first`, `second`))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000304
Steve Purcell15d89272001-04-12 09:05:01 +0000305 def failIfEqual(self, first, second, msg=None):
306 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000307 operator.
308 """
Steve Purcell15d89272001-04-12 09:05:01 +0000309 if first == second:
Steve Purcellca9aaf32001-12-17 10:13:17 +0000310 raise self.failureException, \
311 (msg or '%s == %s' % (`first`, `second`))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000312
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000313 def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
314 """Fail if the two objects are unequal as determined by their
315 difference rounded to the given number of decimal places
316 (default 7) and comparing to zero.
317
318 Note that decimal places (from zero) is usually not the same
319 as significant digits (measured from the most signficant digit).
320 """
321 if round(second-first, places) != 0:
322 raise self.failureException, \
323 (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
324
325 def failIfAlmostEqual(self, first, second, places=7, msg=None):
326 """Fail if the two objects are equal as determined by their
327 difference rounded to the given number of decimal places
328 (default 7) and comparing to zero.
329
330 Note that decimal places (from zero) is usually not the same
331 as significant digits (measured from the most signficant digit).
332 """
333 if round(second-first, places) == 0:
334 raise self.failureException, \
335 (msg or '%s == %s within %s places' % (`first`, `second`, `places`))
336
Steve Purcell15d89272001-04-12 09:05:01 +0000337 assertEqual = assertEquals = failUnlessEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000338
Steve Purcell15d89272001-04-12 09:05:01 +0000339 assertNotEqual = assertNotEquals = failIfEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000340
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000341 assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
342
343 assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
344
Steve Purcell15d89272001-04-12 09:05:01 +0000345 assertRaises = failUnlessRaises
346
347 assert_ = failUnless
348
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000349
Fred Drake02538202001-03-21 18:09:46 +0000350
351class TestSuite:
352 """A test suite is a composite test consisting of a number of TestCases.
353
354 For use, create an instance of TestSuite, then add test case instances.
355 When all tests have been added, the suite can be passed to a test
356 runner, such as TextTestRunner. It will run the individual test cases
357 in the order in which they were added, aggregating the results. When
358 subclassing, do not forget to call the base class constructor.
359 """
360 def __init__(self, tests=()):
361 self._tests = []
362 self.addTests(tests)
363
364 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000365 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +0000366
367 __str__ = __repr__
368
369 def countTestCases(self):
370 cases = 0
371 for test in self._tests:
372 cases = cases + test.countTestCases()
373 return cases
374
375 def addTest(self, test):
376 self._tests.append(test)
377
378 def addTests(self, tests):
379 for test in tests:
380 self.addTest(test)
381
382 def run(self, result):
383 return self(result)
384
385 def __call__(self, result):
386 for test in self._tests:
387 if result.shouldStop:
388 break
389 test(result)
390 return result
391
392 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000393 """Run the tests without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000394 for test in self._tests: test.debug()
Fred Drake02538202001-03-21 18:09:46 +0000395
396
397class FunctionTestCase(TestCase):
398 """A test case that wraps a test function.
399
400 This is useful for slipping pre-existing test functions into the
401 PyUnit framework. Optionally, set-up and tidy-up functions can be
402 supplied. As with TestCase, the tidy-up ('tearDown') function will
403 always be called if the set-up ('setUp') function ran successfully.
404 """
405
406 def __init__(self, testFunc, setUp=None, tearDown=None,
407 description=None):
408 TestCase.__init__(self)
409 self.__setUpFunc = setUp
410 self.__tearDownFunc = tearDown
411 self.__testFunc = testFunc
412 self.__description = description
413
414 def setUp(self):
415 if self.__setUpFunc is not None:
416 self.__setUpFunc()
417
418 def tearDown(self):
419 if self.__tearDownFunc is not None:
420 self.__tearDownFunc()
421
422 def runTest(self):
423 self.__testFunc()
424
425 def id(self):
426 return self.__testFunc.__name__
427
428 def __str__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000429 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +0000430
431 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000432 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
Fred Drake02538202001-03-21 18:09:46 +0000433
434 def shortDescription(self):
435 if self.__description is not None: return self.__description
436 doc = self.__testFunc.__doc__
437 return doc and string.strip(string.split(doc, "\n")[0]) or None
438
439
440
441##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000442# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +0000443##############################################################################
444
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000445class TestLoader:
446 """This class is responsible for loading tests according to various
447 criteria and returning them wrapped in a Test
Fred Drake02538202001-03-21 18:09:46 +0000448 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000449 testMethodPrefix = 'test'
450 sortTestMethodsUsing = cmp
451 suiteClass = TestSuite
Fred Drake02538202001-03-21 18:09:46 +0000452
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000453 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000454 """Return a suite of all tests cases contained in testCaseClass"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000455 return self.suiteClass(map(testCaseClass,
456 self.getTestCaseNames(testCaseClass)))
Fred Drake02538202001-03-21 18:09:46 +0000457
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000458 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +0000459 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000460 tests = []
461 for name in dir(module):
462 obj = getattr(module, name)
Guido van Rossum67911372002-09-30 19:25:56 +0000463 if (isinstance(obj, (type, types.ClassType)) and
464 issubclass(obj, TestCase)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000465 tests.append(self.loadTestsFromTestCase(obj))
466 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +0000467
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000468 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000469 """Return a suite of all tests cases given a string specifier.
470
471 The name may resolve either to a module, a test case class, a
472 test method within a test case class, or a callable object which
473 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +0000474
Steve Purcell15d89272001-04-12 09:05:01 +0000475 The method optionally resolves the names relative to a given module.
476 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000477 parts = string.split(name, '.')
478 if module is None:
479 if not parts:
480 raise ValueError, "incomplete test name: %s" % name
481 else:
Steve Purcell17a781b2001-04-09 15:37:31 +0000482 parts_copy = parts[:]
483 while parts_copy:
484 try:
485 module = __import__(string.join(parts_copy,'.'))
486 break
487 except ImportError:
488 del parts_copy[-1]
489 if not parts_copy: raise
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000490 parts = parts[1:]
491 obj = module
492 for part in parts:
493 obj = getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +0000494
Steve Purcelle00dde22001-08-08 07:57:26 +0000495 import unittest
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000496 if type(obj) == types.ModuleType:
497 return self.loadTestsFromModule(obj)
Guido van Rossum67911372002-09-30 19:25:56 +0000498 elif (isinstance(obj, (type, types.ClassType)) and
499 issubclass(obj, unittest.TestCase)):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000500 return self.loadTestsFromTestCase(obj)
501 elif type(obj) == types.UnboundMethodType:
502 return obj.im_class(obj.__name__)
503 elif callable(obj):
504 test = obj()
Steve Purcelle00dde22001-08-08 07:57:26 +0000505 if not isinstance(test, unittest.TestCase) and \
506 not isinstance(test, unittest.TestSuite):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000507 raise ValueError, \
Steve Purcell4bc80852001-05-10 01:28:40 +0000508 "calling %s returned %s, not a test" % (obj,test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000509 return test
Fred Drake02538202001-03-21 18:09:46 +0000510 else:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000511 raise ValueError, "don't know how to make test from: %s" % obj
512
513 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000514 """Return a suite of all tests cases found using the given sequence
515 of string specifiers. See 'loadTestsFromName()'.
516 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000517 suites = []
518 for name in names:
519 suites.append(self.loadTestsFromName(name, module))
520 return self.suiteClass(suites)
521
522 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +0000523 """Return a sorted sequence of method names found within testCaseClass
524 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000525 testFnNames = filter(lambda n,p=self.testMethodPrefix: n[:len(p)] == p,
526 dir(testCaseClass))
527 for baseclass in testCaseClass.__bases__:
528 for testFnName in self.getTestCaseNames(baseclass):
529 if testFnName not in testFnNames: # handle overridden methods
530 testFnNames.append(testFnName)
531 if self.sortTestMethodsUsing:
532 testFnNames.sort(self.sortTestMethodsUsing)
533 return testFnNames
534
535
536
537defaultTestLoader = TestLoader()
538
539
540##############################################################################
541# Patches for old functions: these functions should be considered obsolete
542##############################################################################
543
544def _makeLoader(prefix, sortUsing, suiteClass=None):
545 loader = TestLoader()
546 loader.sortTestMethodsUsing = sortUsing
547 loader.testMethodPrefix = prefix
548 if suiteClass: loader.suiteClass = suiteClass
549 return loader
550
551def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
552 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
553
554def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
555 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
556
557def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
558 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +0000559
560
561##############################################################################
562# Text UI
563##############################################################################
564
565class _WritelnDecorator:
566 """Used to decorate file-like objects with a handy 'writeln' method"""
567 def __init__(self,stream):
568 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +0000569
570 def __getattr__(self, attr):
571 return getattr(self.stream,attr)
572
Raymond Hettinger91dd19d2003-09-13 02:58:00 +0000573 def writeln(self, arg=None):
574 if arg: self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000575 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +0000576
Fred Drake02538202001-03-21 18:09:46 +0000577
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000578class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +0000579 """A test result class that can print formatted text results to a stream.
580
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000581 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +0000582 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000583 separator1 = '=' * 70
584 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +0000585
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000586 def __init__(self, stream, descriptions, verbosity):
Fred Drake02538202001-03-21 18:09:46 +0000587 TestResult.__init__(self)
588 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000589 self.showAll = verbosity > 1
590 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +0000591 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000592
593 def getDescription(self, test):
594 if self.descriptions:
595 return test.shortDescription() or str(test)
596 else:
597 return str(test)
598
Fred Drake02538202001-03-21 18:09:46 +0000599 def startTest(self, test):
600 TestResult.startTest(self, test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000601 if self.showAll:
602 self.stream.write(self.getDescription(test))
603 self.stream.write(" ... ")
Fred Drake02538202001-03-21 18:09:46 +0000604
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000605 def addSuccess(self, test):
606 TestResult.addSuccess(self, test)
607 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000608 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000609 elif self.dots:
610 self.stream.write('.')
Fred Drake02538202001-03-21 18:09:46 +0000611
612 def addError(self, test, err):
613 TestResult.addError(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000614 if self.showAll:
615 self.stream.writeln("ERROR")
616 elif self.dots:
617 self.stream.write('E')
Fred Drake02538202001-03-21 18:09:46 +0000618
619 def addFailure(self, test, err):
620 TestResult.addFailure(self, test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000621 if self.showAll:
622 self.stream.writeln("FAIL")
623 elif self.dots:
624 self.stream.write('F')
Fred Drake02538202001-03-21 18:09:46 +0000625
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000626 def printErrors(self):
627 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +0000628 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000629 self.printErrorList('ERROR', self.errors)
630 self.printErrorList('FAIL', self.failures)
631
632 def printErrorList(self, flavour, errors):
633 for test, err in errors:
634 self.stream.writeln(self.separator1)
635 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
636 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +0000637 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +0000638
639
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000640class TextTestRunner:
Fred Drake02538202001-03-21 18:09:46 +0000641 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +0000642
Fred Drake02538202001-03-21 18:09:46 +0000643 It prints out the names of tests as they are run, errors as they
644 occur, and a summary of the results at the end of the test run.
645 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000646 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +0000647 self.stream = _WritelnDecorator(stream)
648 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000649 self.verbosity = verbosity
650
651 def _makeResult(self):
652 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000653
654 def run(self, test):
655 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000656 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +0000657 startTime = time.time()
658 test(result)
659 stopTime = time.time()
660 timeTaken = float(stopTime - startTime)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000661 result.printErrors()
662 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +0000663 run = result.testsRun
664 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +0000665 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +0000666 self.stream.writeln()
667 if not result.wasSuccessful():
668 self.stream.write("FAILED (")
669 failed, errored = map(len, (result.failures, result.errors))
670 if failed:
671 self.stream.write("failures=%d" % failed)
672 if errored:
673 if failed: self.stream.write(", ")
674 self.stream.write("errors=%d" % errored)
675 self.stream.writeln(")")
676 else:
677 self.stream.writeln("OK")
678 return result
Tim Petersa19a1682001-03-29 04:36:09 +0000679
Fred Drake02538202001-03-21 18:09:46 +0000680
Fred Drake02538202001-03-21 18:09:46 +0000681
682##############################################################################
683# Facilities for running tests from the command line
684##############################################################################
685
686class TestProgram:
687 """A command-line program that runs a set of tests; this is primarily
688 for making test modules conveniently executable.
689 """
690 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +0000691Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000692
693Options:
694 -h, --help Show this message
695 -v, --verbose Verbose output
696 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +0000697
698Examples:
699 %(progName)s - run default set of tests
700 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000701 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
702 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +0000703 in MyTestCase
704"""
705 def __init__(self, module='__main__', defaultTest=None,
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000706 argv=None, testRunner=None, testLoader=defaultTestLoader):
Fred Drake02538202001-03-21 18:09:46 +0000707 if type(module) == type(''):
708 self.module = __import__(module)
709 for part in string.split(module,'.')[1:]:
710 self.module = getattr(self.module, part)
711 else:
712 self.module = module
713 if argv is None:
714 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000715 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +0000716 self.defaultTest = defaultTest
717 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000718 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +0000719 self.progName = os.path.basename(argv[0])
720 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +0000721 self.runTests()
722
723 def usageExit(self, msg=None):
724 if msg: print msg
725 print self.USAGE % self.__dict__
726 sys.exit(2)
727
728 def parseArgs(self, argv):
729 import getopt
730 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000731 options, args = getopt.getopt(argv[1:], 'hHvq',
732 ['help','verbose','quiet'])
Fred Drake02538202001-03-21 18:09:46 +0000733 for opt, value in options:
734 if opt in ('-h','-H','--help'):
735 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000736 if opt in ('-q','--quiet'):
737 self.verbosity = 0
738 if opt in ('-v','--verbose'):
739 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +0000740 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000741 self.test = self.testLoader.loadTestsFromModule(self.module)
742 return
Fred Drake02538202001-03-21 18:09:46 +0000743 if len(args) > 0:
744 self.testNames = args
745 else:
746 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000747 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +0000748 except getopt.error, msg:
749 self.usageExit(msg)
750
751 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000752 self.test = self.testLoader.loadTestsFromNames(self.testNames,
753 self.module)
Fred Drake02538202001-03-21 18:09:46 +0000754
755 def runTests(self):
756 if self.testRunner is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000757 self.testRunner = TextTestRunner(verbosity=self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +0000758 result = self.testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +0000759 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +0000760
761main = TestProgram
762
763
764##############################################################################
765# Executing this module from the command line
766##############################################################################
767
768if __name__ == "__main__":
769 main(module=None)