blob: 0f2d2357f93c4f96f10b7150b909117fb7753406 [file] [log] [blame]
Fred Drake02538202001-03-21 18:09:46 +00001#!/usr/bin/env python
Steve Purcell5ddd1a82001-03-22 08:45:36 +00002'''
Fred Drake02538202001-03-21 18:09:46 +00003Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
4Smalltalk testing framework.
5
Fred Drake02538202001-03-21 18:09:46 +00006This module contains the core framework classes that form the basis of
7specific test cases and suites (TestCase, TestSuite etc.), and also a
8text-based utility class for running the tests and reporting the results
Jeremy Hyltonefef5da2001-10-22 18:14:15 +00009 (TextTestRunner).
Fred Drake02538202001-03-21 18:09:46 +000010
Steve Purcell5ddd1a82001-03-22 08:45:36 +000011Simple usage:
12
13 import unittest
14
15 class IntegerArithmenticTestCase(unittest.TestCase):
16 def testAdd(self): ## test method names begin 'test*'
Gregory P. Smith28399852009-03-31 16:54:10 +000017 self.assertEqual((1 + 2), 3)
18 self.assertEqual(0 + 1, 1)
Steve Purcell7b065702001-09-06 08:24:40 +000019 def testMultiply(self):
Gregory P. Smith28399852009-03-31 16:54:10 +000020 self.assertEqual((0 * 10), 0)
21 self.assertEqual((5 * 8), 40)
Steve Purcell5ddd1a82001-03-22 08:45:36 +000022
23 if __name__ == '__main__':
24 unittest.main()
25
26Further information is available in the bundled documentation, and from
27
Benjamin Peterson4e4de332009-03-24 00:37:12 +000028 http://docs.python.org/library/unittest.html
Steve Purcell5ddd1a82001-03-22 08:45:36 +000029
Steve Purcell7e743842003-09-22 11:08:12 +000030Copyright (c) 1999-2003 Steve Purcell
Benjamin Peterson4e4de332009-03-24 00:37:12 +000031Copyright (c) 2003-2009 Python Software Foundation
Fred Drake02538202001-03-21 18:09:46 +000032This module is free software, and you may redistribute it and/or modify
33it under the same terms as Python itself, so long as this copyright message
34and disclaimer are retained in their original form.
35
36IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
37SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
38THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
39DAMAGE.
40
41THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
42LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
44AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
45SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Steve Purcell5ddd1a82001-03-22 08:45:36 +000046'''
Fred Drake02538202001-03-21 18:09:46 +000047
Gregory P. Smith28399852009-03-31 16:54:10 +000048import difflib
Benjamin Peterson692428e2009-03-23 21:50:21 +000049import functools
Gregory P. Smith28399852009-03-31 16:54:10 +000050import os
51import pprint
52import re
53import sys
54import time
55import traceback
56import types
Fred Drake02538202001-03-21 18:09:46 +000057
58##############################################################################
Steve Purcelld75e7e42003-09-15 11:01:21 +000059# Exported classes and functions
60##############################################################################
Benjamin Petersonc750d4d2009-03-24 00:39:24 +000061__all__ = ['TestResult', 'TestCase', 'TestSuite', 'ClassTestSuite',
62 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
Benjamin Peterson03715482009-03-24 01:11:37 +000063 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
Benjamin Petersonc750d4d2009-03-24 00:39:24 +000064 'expectedFailure']
Steve Purcelld75e7e42003-09-15 11:01:21 +000065
Steve Purcell7e743842003-09-22 11:08:12 +000066# Expose obsolete functions for backwards compatibility
Steve Purcelld75e7e42003-09-15 11:01:21 +000067__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
68
69
70##############################################################################
Steve Purcell7e743842003-09-22 11:08:12 +000071# Backward compatibility
72##############################################################################
Steve Purcell7e743842003-09-22 11:08:12 +000073
Raymond Hettinger5930d8f2008-07-10 16:06:41 +000074def _CmpToKey(mycmp):
75 'Convert a cmp= function into a key= function'
76 class K(object):
77 def __init__(self, obj):
78 self.obj = obj
79 def __lt__(self, other):
80 return mycmp(self.obj, other.obj) == -1
81 return K
Steve Purcell7e743842003-09-22 11:08:12 +000082
83##############################################################################
Fred Drake02538202001-03-21 18:09:46 +000084# Test framework core
85##############################################################################
86
Steve Purcelldc391a62002-08-09 09:46:23 +000087def _strclass(cls):
88 return "%s.%s" % (cls.__module__, cls.__name__)
89
Benjamin Peterson692428e2009-03-23 21:50:21 +000090
91class SkipTest(Exception):
92 """
93 Raise this exception in a test to skip it.
94
95 Usually you can use TestResult.skip() or one of the skipping decorators
96 instead of raising this directly.
97 """
98 pass
99
100class _ExpectedFailure(Exception):
101 """
102 Raise this when a test is expected to fail.
103
104 This is an implementation detail.
105 """
106
107 def __init__(self, exc_info):
108 super(_ExpectedFailure, self).__init__()
109 self.exc_info = exc_info
110
111class _UnexpectedSuccess(Exception):
112 """
113 The test was supposed to fail, but it didn't!
114 """
115 pass
116
117def _id(obj):
118 return obj
119
120def skip(reason):
121 """
122 Unconditionally skip a test.
123 """
124 def decorator(test_item):
125 if isinstance(test_item, type) and issubclass(test_item, TestCase):
126 test_item.__unittest_skip__ = True
127 test_item.__unittest_skip_why__ = reason
128 return test_item
129 @functools.wraps(test_item)
130 def skip_wrapper(*args, **kwargs):
131 raise SkipTest(reason)
132 return skip_wrapper
133 return decorator
134
135def skipIf(condition, reason):
136 """
137 Skip a test if the condition is true.
138 """
139 if condition:
140 return skip(reason)
141 return _id
142
143def skipUnless(condition, reason):
144 """
145 Skip a test unless the condition is true.
146 """
147 if not condition:
148 return skip(reason)
149 return _id
150
151
152def expectedFailure(func):
153 @functools.wraps(func)
154 def wrapper(*args, **kwargs):
155 try:
156 func(*args, **kwargs)
157 except Exception:
158 raise _ExpectedFailure(sys.exc_info())
159 raise _UnexpectedSuccess
160 return wrapper
161
162
Steve Purcellb8d5f242003-12-06 13:03:13 +0000163__unittest = 1
164
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000165class TestResult(object):
Fred Drake02538202001-03-21 18:09:46 +0000166 """Holder for test result information.
167
168 Test results are automatically managed by the TestCase and TestSuite
169 classes, and do not need to be explicitly manipulated by writers of tests.
170
171 Each instance holds the total number of tests run, and collections of
172 failures and errors that occurred among those test runs. The collections
Steve Purcell7b065702001-09-06 08:24:40 +0000173 contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
Fred Drake656f9ec2001-09-06 19:13:14 +0000174 formatted traceback of the error that occurred.
Fred Drake02538202001-03-21 18:09:46 +0000175 """
176 def __init__(self):
177 self.failures = []
178 self.errors = []
179 self.testsRun = 0
Benjamin Peterson692428e2009-03-23 21:50:21 +0000180 self.skipped = []
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +0000181 self.expectedFailures = []
182 self.unexpectedSuccesses = []
Georg Brandl15c5ce92007-03-07 09:09:40 +0000183 self.shouldStop = False
Fred Drake02538202001-03-21 18:09:46 +0000184
185 def startTest(self, test):
186 "Called when the given test is about to be run"
187 self.testsRun = self.testsRun + 1
188
189 def stopTest(self, test):
190 "Called when the given test has been run"
191 pass
192
193 def addError(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000194 """Called when an error has occurred. 'err' is a tuple of values as
195 returned by sys.exc_info().
196 """
Steve Purcellb8d5f242003-12-06 13:03:13 +0000197 self.errors.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000198
199 def addFailure(self, test, err):
Steve Purcell7b065702001-09-06 08:24:40 +0000200 """Called when an error has occurred. 'err' is a tuple of values as
201 returned by sys.exc_info()."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000202 self.failures.append((test, self._exc_info_to_string(err, test)))
Fred Drake02538202001-03-21 18:09:46 +0000203
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000204 def addSuccess(self, test):
205 "Called when a test has completed successfully"
206 pass
207
Benjamin Peterson692428e2009-03-23 21:50:21 +0000208 def addSkip(self, test, reason):
209 """Called when a test is skipped."""
210 self.skipped.append((test, reason))
211
212 def addExpectedFailure(self, test, err):
213 """Called when an expected failure/error occured."""
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +0000214 self.expectedFailures.append(
Benjamin Peterson692428e2009-03-23 21:50:21 +0000215 (test, self._exc_info_to_string(err, test)))
216
217 def addUnexpectedSuccess(self, test):
218 """Called when a test was expected to fail, but succeed."""
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +0000219 self.unexpectedSuccesses.append(test)
Benjamin Peterson692428e2009-03-23 21:50:21 +0000220
Fred Drake02538202001-03-21 18:09:46 +0000221 def wasSuccessful(self):
222 "Tells whether or not this result was a success"
223 return len(self.failures) == len(self.errors) == 0
224
225 def stop(self):
226 "Indicates that the tests should be aborted"
Steve Purcell7e743842003-09-22 11:08:12 +0000227 self.shouldStop = True
Tim Petersa19a1682001-03-29 04:36:09 +0000228
Steve Purcellb8d5f242003-12-06 13:03:13 +0000229 def _exc_info_to_string(self, err, test):
Steve Purcell7b065702001-09-06 08:24:40 +0000230 """Converts a sys.exc_info()-style tuple of values into a string."""
Steve Purcellb8d5f242003-12-06 13:03:13 +0000231 exctype, value, tb = err
232 # Skip test runner traceback levels
233 while tb and self._is_relevant_tb_level(tb):
234 tb = tb.tb_next
235 if exctype is test.failureException:
236 # Skip assert*() traceback levels
237 length = self._count_relevant_tb_levels(tb)
238 return ''.join(traceback.format_exception(exctype, value, tb, length))
239 return ''.join(traceback.format_exception(exctype, value, tb))
240
241 def _is_relevant_tb_level(self, tb):
Georg Brandl56af5fc2008-07-18 19:30:10 +0000242 return '__unittest' in tb.tb_frame.f_globals
Steve Purcellb8d5f242003-12-06 13:03:13 +0000243
244 def _count_relevant_tb_levels(self, tb):
245 length = 0
246 while tb and not self._is_relevant_tb_level(tb):
247 length += 1
248 tb = tb.tb_next
249 return length
Steve Purcell7b065702001-09-06 08:24:40 +0000250
Fred Drake02538202001-03-21 18:09:46 +0000251 def __repr__(self):
252 return "<%s run=%i errors=%i failures=%i>" % \
Steve Purcelldc391a62002-08-09 09:46:23 +0000253 (_strclass(self.__class__), self.testsRun, len(self.errors),
Fred Drake02538202001-03-21 18:09:46 +0000254 len(self.failures))
255
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000256
Gregory P. Smith28399852009-03-31 16:54:10 +0000257class _AssertRaisesContext(object):
258 """A context manager used to implement TestCase.assertRaises* methods."""
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000259
Gregory P. Smith28399852009-03-31 16:54:10 +0000260 def __init__(self, expected, test_case, expected_regexp=None):
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000261 self.expected = expected
262 self.failureException = test_case.failureException
Gregory P. Smith28399852009-03-31 16:54:10 +0000263 self.expected_regex = expected_regexp
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000264
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000265 def __enter__(self):
266 pass
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000267
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000268 def __exit__(self, exc_type, exc_value, traceback):
269 if exc_type is None:
270 try:
271 exc_name = self.expected.__name__
272 except AttributeError:
273 exc_name = str(self.expected)
274 raise self.failureException(
275 "{0} not raised".format(exc_name))
Gregory P. Smith28399852009-03-31 16:54:10 +0000276 if not issubclass(exc_type, self.expected):
277 # let unexpexted exceptions pass through
278 return False
279 if self.expected_regex is None:
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000280 return True
Gregory P. Smith28399852009-03-31 16:54:10 +0000281
282 expected_regexp = self.expected_regex
283 if isinstance(expected_regexp, basestring):
284 expected_regexp = re.compile(expected_regexp)
285 if not expected_regexp.search(str(exc_value)):
286 raise self.failureException('"%s" does not match "%s"' %
287 (expected_regexp.pattern, str(exc_value)))
288 return True
289
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000290
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000291
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000292class TestCase(object):
Fred Drake02538202001-03-21 18:09:46 +0000293 """A class whose instances are single test cases.
294
Fred Drake02538202001-03-21 18:09:46 +0000295 By default, the test code itself should be placed in a method named
296 'runTest'.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000297
Tim Petersa19a1682001-03-29 04:36:09 +0000298 If the fixture may be used for many test cases, create as
Fred Drake02538202001-03-21 18:09:46 +0000299 many test methods as are needed. When instantiating such a TestCase
300 subclass, specify in the constructor arguments the name of the test method
301 that the instance is to execute.
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000302
Tim Petersa19a1682001-03-29 04:36:09 +0000303 Test authors should subclass TestCase for their own tests. Construction
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000304 and deconstruction of the test's environment ('fixture') can be
305 implemented by overriding the 'setUp' and 'tearDown' methods respectively.
306
307 If it is necessary to override the __init__ method, the base class
308 __init__ method must always be called. It is important that subclasses
309 should not change the signature of their __init__ method, since instances
310 of the classes are instantiated automatically by parts of the framework
311 in order to be run.
Fred Drake02538202001-03-21 18:09:46 +0000312 """
Steve Purcell15d89272001-04-12 09:05:01 +0000313
314 # This attribute determines which exception will be raised when
315 # the instance's assertion methods fail; test methods raising this
316 # exception will be deemed to have 'failed' rather than 'errored'
317
318 failureException = AssertionError
319
Fred Drake02538202001-03-21 18:09:46 +0000320 def __init__(self, methodName='runTest'):
321 """Create an instance of the class that will use the named test
322 method when executed. Raises a ValueError if the instance does
323 not have a method with the specified name.
324 """
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000325 self._testMethodName = methodName
Fred Drake02538202001-03-21 18:09:46 +0000326 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000327 testMethod = getattr(self, methodName)
Fred Drake02538202001-03-21 18:09:46 +0000328 except AttributeError:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000329 raise ValueError("no such test method in %s: %s" % \
330 (self.__class__, methodName))
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000331 self._testMethodDoc = testMethod.__doc__
Fred Drake02538202001-03-21 18:09:46 +0000332
Gregory P. Smith28399852009-03-31 16:54:10 +0000333 # Map types to custom assertEqual functions that will compare
334 # instances of said type in more detail to generate a more useful
335 # error message.
336 self.__type_equality_funcs = {}
337 self.addTypeEqualityFunc(dict, self.assertDictEqual)
338 self.addTypeEqualityFunc(list, self.assertListEqual)
339 self.addTypeEqualityFunc(tuple, self.assertTupleEqual)
340 self.addTypeEqualityFunc(set, self.assertSetEqual)
341 self.addTypeEqualityFunc(frozenset, self.assertSetEqual)
342
343 def addTypeEqualityFunc(self, typeobj, function):
344 """Add a type specific assertEqual style function to compare a type.
345
346 This method is for use by TestCase subclasses that need to register
347 their own type equality functions to provide nicer error messages.
348
349 Args:
350 typeobj: The data type to call this function on when both values
351 are of the same type in assertEqual().
352 function: The callable taking two arguments and an optional
353 msg= argument that raises self.failureException with a
354 useful error message when the two arguments are not equal.
355 """
356 self.__type_equality_funcs[typeobj] = function
357
Fred Drake02538202001-03-21 18:09:46 +0000358 def setUp(self):
359 "Hook method for setting up the test fixture before exercising it."
360 pass
361
362 def tearDown(self):
363 "Hook method for deconstructing the test fixture after testing it."
364 pass
365
366 def countTestCases(self):
367 return 1
368
369 def defaultTestResult(self):
370 return TestResult()
371
372 def shortDescription(self):
Gregory P. Smith28399852009-03-31 16:54:10 +0000373 """Returns both the test method name and first line of its docstring.
Fred Drake02538202001-03-21 18:09:46 +0000374
Gregory P. Smith28399852009-03-31 16:54:10 +0000375 If no docstring is given, only returns the method name.
376
377 This method overrides unittest.TestCase.shortDescription(), which
378 only returns the first line of the docstring, obscuring the name
379 of the test upon failure.
Fred Drake02538202001-03-21 18:09:46 +0000380 """
Gregory P. Smith28399852009-03-31 16:54:10 +0000381 desc = str(self)
382 doc_first_line = None
383
384 if self._testMethodDoc:
385 doc_first_line = self._testMethodDoc.split("\n")[0].strip()
386 if doc_first_line:
387 desc = '\n'.join((desc, doc_first_line))
388 return desc
Fred Drake02538202001-03-21 18:09:46 +0000389
390 def id(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000391 return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000392
Georg Brandl15c5ce92007-03-07 09:09:40 +0000393 def __eq__(self, other):
394 if type(self) is not type(other):
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000395 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +0000396
397 return self._testMethodName == other._testMethodName
398
399 def __ne__(self, other):
400 return not self == other
401
402 def __hash__(self):
Collin Winter9453e5d2007-03-09 23:30:39 +0000403 return hash((type(self), self._testMethodName))
Georg Brandl15c5ce92007-03-07 09:09:40 +0000404
Fred Drake02538202001-03-21 18:09:46 +0000405 def __str__(self):
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000406 return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
Fred Drake02538202001-03-21 18:09:46 +0000407
408 def __repr__(self):
409 return "<%s testMethod=%s>" % \
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000410 (_strclass(self.__class__), self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000411
412 def run(self, result=None):
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000413 if result is None:
414 result = self.defaultTestResult()
Fred Drake02538202001-03-21 18:09:46 +0000415 result.startTest(self)
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000416 testMethod = getattr(self, self._testMethodName)
Fred Drake02538202001-03-21 18:09:46 +0000417 try:
418 try:
419 self.setUp()
Benjamin Peterson692428e2009-03-23 21:50:21 +0000420 except SkipTest as e:
421 result.addSkip(self, str(e))
422 return
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000423 except Exception:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000424 result.addError(self, sys.exc_info())
Fred Drake02538202001-03-21 18:09:46 +0000425 return
426
Benjamin Peterson692428e2009-03-23 21:50:21 +0000427 success = False
Fred Drake02538202001-03-21 18:09:46 +0000428 try:
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000429 testMethod()
Skip Montanaroae5c37b2003-07-13 15:18:12 +0000430 except self.failureException:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000431 result.addFailure(self, sys.exc_info())
Benjamin Peterson692428e2009-03-23 21:50:21 +0000432 except _ExpectedFailure as e:
433 result.addExpectedFailure(self, e.exc_info)
434 except _UnexpectedSuccess:
435 result.addUnexpectedSuccess(self)
436 except SkipTest as e:
437 result.addSkip(self, str(e))
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000438 except Exception:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000439 result.addError(self, sys.exc_info())
Benjamin Peterson692428e2009-03-23 21:50:21 +0000440 else:
441 success = True
Fred Drake02538202001-03-21 18:09:46 +0000442
443 try:
444 self.tearDown()
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000445 except Exception:
Benjamin Petersonc9301352009-03-26 16:32:23 +0000446 result.addError(self, sys.exc_info())
Benjamin Peterson692428e2009-03-23 21:50:21 +0000447 success = False
448 if success:
449 result.addSuccess(self)
Fred Drake02538202001-03-21 18:09:46 +0000450 finally:
451 result.stopTest(self)
452
Raymond Hettinger664347b2004-12-04 21:21:53 +0000453 def __call__(self, *args, **kwds):
454 return self.run(*args, **kwds)
Steve Purcell7e743842003-09-22 11:08:12 +0000455
Fred Drake02538202001-03-21 18:09:46 +0000456 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000457 """Run the test without collecting errors in a TestResult"""
Fred Drake02538202001-03-21 18:09:46 +0000458 self.setUp()
Georg Brandl81cdb4e2006-01-20 17:55:00 +0000459 getattr(self, self._testMethodName)()
Fred Drake02538202001-03-21 18:09:46 +0000460 self.tearDown()
461
Benjamin Peterson47d97382009-03-26 20:05:50 +0000462 def skipTest(self, reason):
Benjamin Peterson692428e2009-03-23 21:50:21 +0000463 """Skip this test."""
464 raise SkipTest(reason)
465
Steve Purcell15d89272001-04-12 09:05:01 +0000466 def fail(self, msg=None):
467 """Fail immediately, with the given message."""
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000468 raise self.failureException(msg)
Fred Drake02538202001-03-21 18:09:46 +0000469
470 def failIf(self, expr, msg=None):
471 "Fail the test if the expression is true."
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000472 if expr:
473 raise self.failureException(msg)
Fred Drake02538202001-03-21 18:09:46 +0000474
Steve Purcell15d89272001-04-12 09:05:01 +0000475 def failUnless(self, expr, msg=None):
476 """Fail the test unless the expression is true."""
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000477 if not expr:
478 raise self.failureException(msg)
Steve Purcell15d89272001-04-12 09:05:01 +0000479
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000480 def failUnlessRaises(self, excClass, callableObj=None, *args, **kwargs):
Steve Purcell15d89272001-04-12 09:05:01 +0000481 """Fail unless an exception of class excClass is thrown
Fred Drake02538202001-03-21 18:09:46 +0000482 by callableObj when invoked with arguments args and keyword
483 arguments kwargs. If a different type of exception is
484 thrown, it will not be caught, and the test case will be
485 deemed to have suffered an error, exactly as for an
486 unexpected exception.
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000487
488 If called with callableObj omitted or None, will return a
489 context object used like this::
490
491 with self.failUnlessRaises(some_error_class):
492 do_something()
Fred Drake02538202001-03-21 18:09:46 +0000493 """
Gregory P. Smith28399852009-03-31 16:54:10 +0000494 context = _AssertRaisesContext(excClass, self)
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000495 if callableObj is None:
496 return context
497 with context:
Guido van Rossum68468eb2003-02-27 20:14:51 +0000498 callableObj(*args, **kwargs)
Fred Drake02538202001-03-21 18:09:46 +0000499
Gregory P. Smith28399852009-03-31 16:54:10 +0000500 def _getAssertEqualityFunc(self, first, second):
501 """Get a detailed comparison function for the types of the two args.
502
503 Returns: A callable accepting (first, second, msg=None) that will
504 raise a failure exception if first != second with a useful human
505 readable error message for those types.
506 """
507 #
508 # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
509 # and vice versa. I opted for the conservative approach in case
510 # subclasses are not intended to be compared in detail to their super
511 # class instances using a type equality func. This means testing
512 # subtypes won't automagically use the detailed comparison. Callers
513 # should use their type specific assertSpamEqual method to compare
514 # subclasses if the detailed comparison is desired and appropriate.
515 # See the discussion in http://bugs.python.org/issue2578.
516 #
517 if type(first) is type(second):
518 return self.__type_equality_funcs.get(type(first),
519 self._baseAssertEqual)
520 return self._baseAssertEqual
521
522 def _baseAssertEqual(self, first, second, msg=None):
523 """The default assertEqual implementation, not type specific."""
524 if not first == second:
525 raise self.failureException(msg or '%r != %r' % (first, second))
526
Steve Purcell15d89272001-04-12 09:05:01 +0000527 def failUnlessEqual(self, first, second, msg=None):
Raymond Hettingerc377cbf2003-04-04 22:56:42 +0000528 """Fail if the two objects are unequal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000529 operator.
530 """
Gregory P. Smith28399852009-03-31 16:54:10 +0000531 assertion_func = self._getAssertEqualityFunc(first, second)
532 assertion_func(first, second, msg=msg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000533
Steve Purcell15d89272001-04-12 09:05:01 +0000534 def failIfEqual(self, first, second, msg=None):
535 """Fail if the two objects are equal as determined by the '=='
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000536 operator.
537 """
Steve Purcell15d89272001-04-12 09:05:01 +0000538 if first == second:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000539 raise self.failureException(msg or '%r == %r' % (first, second))
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000540
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000541 def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
542 """Fail if the two objects are unequal as determined by their
543 difference rounded to the given number of decimal places
544 (default 7) and comparing to zero.
545
Steve Purcell397b45d2003-10-26 10:41:03 +0000546 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000547 as significant digits (measured from the most signficant digit).
548 """
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000549 if round(abs(second-first), places) != 0:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000550 raise self.failureException(
551 msg or '%r != %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000552
553 def failIfAlmostEqual(self, first, second, places=7, msg=None):
554 """Fail if the two objects are equal as determined by their
555 difference rounded to the given number of decimal places
556 (default 7) and comparing to zero.
557
Steve Purcellcca34912003-10-26 16:38:16 +0000558 Note that decimal places (from zero) are usually not the same
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000559 as significant digits (measured from the most signficant digit).
560 """
Jeffrey Yasskin2f3c16b2008-01-03 02:21:52 +0000561 if round(abs(second-first), places) == 0:
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000562 raise self.failureException(
563 msg or '%r == %r within %r places' % (first, second, places))
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000564
Steve Purcell7e743842003-09-22 11:08:12 +0000565 # Synonyms for assertion methods
566
Steve Purcell15d89272001-04-12 09:05:01 +0000567 assertEqual = assertEquals = failUnlessEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000568
Steve Purcell15d89272001-04-12 09:05:01 +0000569 assertNotEqual = assertNotEquals = failIfEqual
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000570
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000571 assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
572
573 assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
574
Steve Purcell15d89272001-04-12 09:05:01 +0000575 assertRaises = failUnlessRaises
576
Steve Purcell7e743842003-09-22 11:08:12 +0000577 assert_ = assertTrue = failUnless
578
579 assertFalse = failIf
Steve Purcell15d89272001-04-12 09:05:01 +0000580
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000581
Gregory P. Smith28399852009-03-31 16:54:10 +0000582 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
583 """An equality assertion for ordered sequences (like lists and tuples).
584
585 For the purposes of this function, a valid orderd sequence type is one
586 which can be indexed, has a length, and has an equality operator.
587
588 Args:
589 seq1: The first sequence to compare.
590 seq2: The second sequence to compare.
591 seq_type: The expected datatype of the sequences, or None if no
592 datatype should be enforced.
593 msg: Optional message to use on failure instead of a list of
594 differences.
595 """
596 if seq_type != None:
597 seq_type_name = seq_type.__name__
598 if not isinstance(seq1, seq_type):
599 raise self.failureException('First sequence is not a %s: %r'
600 % (seq_type_name, seq1))
601 if not isinstance(seq2, seq_type):
602 raise self.failureException('Second sequence is not a %s: %r'
603 % (seq_type_name, seq2))
604 else:
605 seq_type_name = "sequence"
606
607 differing = None
608 try:
609 len1 = len(seq1)
610 except (TypeError, NotImplementedError):
611 differing = 'First %s has no length. Non-sequence?' % (
612 seq_type_name)
613
614 if differing is None:
615 try:
616 len2 = len(seq2)
617 except (TypeError, NotImplementedError):
618 differing = 'Second %s has no length. Non-sequence?' % (
619 seq_type_name)
620
621 if differing is None:
622 if seq1 == seq2:
623 return
624
625 for i in xrange(min(len1, len2)):
626 try:
627 item1 = seq1[i]
628 except (TypeError, IndexError, NotImplementedError):
629 differing = ('Unable to index element %d of first %s\n' %
630 (i, seq_type_name))
631 break
632
633 try:
634 item2 = seq2[i]
635 except (TypeError, IndexError, NotImplementedError):
636 differing = ('Unable to index element %d of second %s\n' %
637 (i, seq_type_name))
638 break
639
640 if item1 != item2:
641 differing = ('First differing element %d:\n%s\n%s\n' %
642 (i, item1, item2))
643 break
644 else:
645 if (len1 == len2 and seq_type is None and
646 type(seq1) != type(seq2)):
647 # The sequences are the same, but have differing types.
648 return
649 # A catch-all message for handling arbitrary user-defined
650 # sequences.
651 differing = '%ss differ:\n' % seq_type_name.capitalize()
652 if len1 > len2:
653 differing = ('First %s contains %d additional '
654 'elements.\n' % (seq_type_name, len1 - len2))
655 try:
656 differing += ('First extra element %d:\n%s\n' %
657 (len2, seq1[len2]))
658 except (TypeError, IndexError, NotImplementedError):
659 differing += ('Unable to index element %d '
660 'of first %s\n' % (len2, seq_type_name))
661 elif len1 < len2:
662 differing = ('Second %s contains %d additional '
663 'elements.\n' % (seq_type_name, len2 - len1))
664 try:
665 differing += ('First extra element %d:\n%s\n' %
666 (len1, seq2[len1]))
667 except (TypeError, IndexError, NotImplementedError):
668 differing += ('Unable to index element %d '
669 'of second %s\n' % (len1, seq_type_name))
670 if not msg:
671 msg = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(),
672 pprint.pformat(seq2).splitlines()))
673 self.fail(differing + msg)
674
675 def assertListEqual(self, list1, list2, msg=None):
676 """A list-specific equality assertion.
677
678 Args:
679 list1: The first list to compare.
680 list2: The second list to compare.
681 msg: Optional message to use on failure instead of a list of
682 differences.
683
684 """
685 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
686
687 def assertTupleEqual(self, tuple1, tuple2, msg=None):
688 """A tuple-specific equality assertion.
689
690 Args:
691 tuple1: The first tuple to compare.
692 tuple2: The second tuple to compare.
693 msg: Optional message to use on failure instead of a list of
694 differences.
695 """
696 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
697
698 def assertSetEqual(self, set1, set2, msg=None):
699 """A set-specific equality assertion.
700
701 Args:
702 set1: The first set to compare.
703 set2: The second set to compare.
704 msg: Optional message to use on failure instead of a list of
705 differences.
706
707 For more general containership equality, assertSameElements will work
708 with things other than sets. This uses ducktyping to support
709 different types of sets, and is optimized for sets specifically
710 (parameters must support a difference method).
711 """
712 try:
713 difference1 = set1.difference(set2)
714 except TypeError, e:
715 self.fail('invalid type when attempting set difference: %s' % e)
716 except AttributeError, e:
717 self.fail('first argument does not support set difference: %s' % e)
718
719 try:
720 difference2 = set2.difference(set1)
721 except TypeError, e:
722 self.fail('invalid type when attempting set difference: %s' % e)
723 except AttributeError, e:
724 self.fail('second argument does not support set difference: %s' % e)
725
726 if not (difference1 or difference2):
727 return
728
729 if msg is not None:
730 self.fail(msg)
731
732 lines = []
733 if difference1:
734 lines.append('Items in the first set but not the second:')
735 for item in difference1:
736 lines.append(repr(item))
737 if difference2:
738 lines.append('Items in the second set but not the first:')
739 for item in difference2:
740 lines.append(repr(item))
741 self.fail('\n'.join(lines))
742
743 def assertIn(self, a, b, msg=None):
744 """Just like self.assert_(a in b), but with a nicer default message."""
745 if msg is None:
746 msg = '"%s" not found in "%s"' % (a, b)
747 self.assert_(a in b, msg)
748
749 def assertNotIn(self, a, b, msg=None):
750 """Just like self.assert_(a not in b), but with a nicer default message."""
751 if msg is None:
752 msg = '"%s" unexpectedly found in "%s"' % (a, b)
753 self.assert_(a not in b, msg)
754
755 def assertDictEqual(self, d1, d2, msg=None):
756 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
757 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
758
759 if d1 != d2:
760 self.fail(msg or ('\n' + '\n'.join(difflib.ndiff(
761 pprint.pformat(d1).splitlines(),
762 pprint.pformat(d2).splitlines()))))
763
764 def assertDictContainsSubset(self, expected, actual, msg=None):
765 """Checks whether actual is a superset of expected."""
766 missing = []
767 mismatched = []
768 for key, value in expected.iteritems():
769 if key not in actual:
770 missing.append(key)
771 elif value != actual[key]:
772 mismatched.append('%s, expected: %s, actual: %s' % (key, value,
773 actual[key]))
774
775 if not (missing or mismatched):
776 return
777
778 missing_msg = mismatched_msg = ''
779 if missing:
780 missing_msg = 'Missing: %s' % ','.join(missing)
781 if mismatched:
782 mismatched_msg = 'Mismatched values: %s' % ','.join(mismatched)
783
784 if msg:
785 msg = '%s: %s; %s' % (msg, missing_msg, mismatched_msg)
786 else:
787 msg = '%s; %s' % (missing_msg, mismatched_msg)
788 self.fail(msg)
789
790 def assertSameElements(self, expected_seq, actual_seq, msg=None):
791 """An unordered sequence specific comparison.
792
793 Raises with an error message listing which elements of expected_seq
794 are missing from actual_seq and vice versa if any.
795 """
796 try:
797 expected = set(expected_seq)
798 actual = set(actual_seq)
799 missing = list(expected.difference(actual))
800 unexpected = list(actual.difference(expected))
801 missing.sort()
802 unexpected.sort()
803 except TypeError:
804 # Fall back to slower list-compare if any of the objects are
805 # not hashable.
806 expected = list(expected_seq)
807 actual = list(actual_seq)
808 expected.sort()
809 actual.sort()
810 missing, unexpected = _SortedListDifference(expected, actual)
811 errors = []
812 if missing:
813 errors.append('Expected, but missing:\n %r\n' % missing)
814 if unexpected:
815 errors.append('Unexpected, but present:\n %r\n' % unexpected)
816 if errors:
817 self.fail(msg or ''.join(errors))
818
819 def assertMultiLineEqual(self, first, second, msg=None):
820 """Assert that two multi-line strings are equal."""
821 self.assert_(isinstance(first, types.StringTypes), (
822 'First argument is not a string'))
823 self.assert_(isinstance(second, types.StringTypes), (
824 'Second argument is not a string'))
825
826 if first != second:
827 raise self.failureException(
828 msg or '\n' + ''.join(difflib.ndiff(first.splitlines(True),
829 second.splitlines(True))))
830
831 def assertLess(self, a, b, msg=None):
832 """Just like self.assert_(a < b), but with a nicer default message."""
833 if msg is None:
834 msg = '"%r" unexpectedly not less than "%r"' % (a, b)
835 self.assert_(a < b, msg)
836
837 def assertLessEqual(self, a, b, msg=None):
838 """Just like self.assert_(a <= b), but with a nicer default message."""
839 if msg is None:
840 msg = '"%r" unexpectedly not less than or equal to "%r"' % (a, b)
841 self.assert_(a <= b, msg)
842
843 def assertGreater(self, a, b, msg=None):
844 """Just like self.assert_(a > b), but with a nicer default message."""
845 if msg is None:
846 msg = '"%r" unexpectedly not greater than "%r"' % (a, b)
847 self.assert_(a > b, msg)
848
849 def assertGreaterEqual(self, a, b, msg=None):
850 """Just like self.assert_(a >= b), but with a nicer default message."""
851 if msg is None:
852 msg = '"%r" unexpectedly not greater than or equal to "%r"' % (a, b)
853 self.assert_(a >= b, msg)
854
855 def assertIsNone(self, obj, msg=None):
856 """Same as self.assert_(obj is None), with a nicer default message."""
857 if msg is None:
858 msg = '"%s" unexpectedly not None' % obj
859 self.assert_(obj is None, msg)
860
861 def assertIsNotNone(self, obj, msg='unexpectedly None'):
862 """Included for symmetry with assertIsNone."""
863 self.assert_(obj is not None, msg)
864
865 def assertRaisesRegexp(self, expected_exception, expected_regexp,
866 callable_obj=None, *args, **kwargs):
867 """Asserts that the message in a raised exception matches a regexp.
868
869 Args:
870 expected_exception: Exception class expected to be raised.
871 expected_regexp: Regexp (re pattern object or string) expected
872 to be found in error message.
873 callable_obj: Function to be called.
874 args: Extra args.
875 kwargs: Extra kwargs.
876 """
877 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
878 if callable_obj is None:
879 return context
880 with context:
881 callable_obj(*args, **kwargs)
882
883 def assertRegexpMatches(self, text, expected_regex, msg=None):
884 if isinstance(expected_regex, basestring):
885 expected_regex = re.compile(expected_regex)
886 if not expected_regex.search(text):
887 msg = msg or "Regexp didn't match"
888 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
889 raise self.failureException(msg)
890
891
892def _SortedListDifference(expected, actual):
893 """Finds elements in only one or the other of two, sorted input lists.
894
895 Returns a two-element tuple of lists. The first list contains those
896 elements in the "expected" list but not in the "actual" list, and the
897 second contains those elements in the "actual" list but not in the
898 "expected" list. Duplicate elements in either input list are ignored.
899 """
900 i = j = 0
901 missing = []
902 unexpected = []
903 while True:
904 try:
905 e = expected[i]
906 a = actual[j]
907 if e < a:
908 missing.append(e)
909 i += 1
910 while expected[i] == e:
911 i += 1
912 elif e > a:
913 unexpected.append(a)
914 j += 1
915 while actual[j] == a:
916 j += 1
917 else:
918 i += 1
919 try:
920 while expected[i] == e:
921 i += 1
922 finally:
923 j += 1
924 while actual[j] == a:
925 j += 1
926 except IndexError:
927 missing.extend(expected[i:])
928 unexpected.extend(actual[j:])
929 break
930 return missing, unexpected
931
Fred Drake02538202001-03-21 18:09:46 +0000932
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000933class TestSuite(object):
Fred Drake02538202001-03-21 18:09:46 +0000934 """A test suite is a composite test consisting of a number of TestCases.
935
936 For use, create an instance of TestSuite, then add test case instances.
937 When all tests have been added, the suite can be passed to a test
938 runner, such as TextTestRunner. It will run the individual test cases
939 in the order in which they were added, aggregating the results. When
940 subclassing, do not forget to call the base class constructor.
941 """
942 def __init__(self, tests=()):
943 self._tests = []
944 self.addTests(tests)
945
946 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000947 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +0000948
Georg Brandl15c5ce92007-03-07 09:09:40 +0000949 def __eq__(self, other):
Benjamin Peterson692428e2009-03-23 21:50:21 +0000950 if not isinstance(other, self.__class__):
951 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +0000952 return self._tests == other._tests
953
954 def __ne__(self, other):
955 return not self == other
956
Nick Coghlan48361f52008-08-11 15:45:58 +0000957 # Can't guarantee hash invariant, so flag as unhashable
958 __hash__ = None
959
Jim Fultonfafd8742004-08-28 15:22:12 +0000960 def __iter__(self):
961 return iter(self._tests)
962
Fred Drake02538202001-03-21 18:09:46 +0000963 def countTestCases(self):
964 cases = 0
965 for test in self._tests:
Steve Purcell7e743842003-09-22 11:08:12 +0000966 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +0000967 return cases
968
969 def addTest(self, test):
Georg Brandld9e50262007-03-07 11:54:49 +0000970 # sanity checks
Raymond Hettinger5930d8f2008-07-10 16:06:41 +0000971 if not hasattr(test, '__call__'):
Georg Brandld9e50262007-03-07 11:54:49 +0000972 raise TypeError("the test to add must be callable")
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000973 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
Georg Brandld9e50262007-03-07 11:54:49 +0000974 raise TypeError("TestCases and TestSuites must be instantiated "
975 "before passing them to addTest()")
Fred Drake02538202001-03-21 18:09:46 +0000976 self._tests.append(test)
977
978 def addTests(self, tests):
Georg Brandld9e50262007-03-07 11:54:49 +0000979 if isinstance(tests, basestring):
980 raise TypeError("tests must be an iterable of tests, not a string")
Fred Drake02538202001-03-21 18:09:46 +0000981 for test in tests:
982 self.addTest(test)
983
984 def run(self, result):
Fred Drake02538202001-03-21 18:09:46 +0000985 for test in self._tests:
986 if result.shouldStop:
987 break
988 test(result)
989 return result
990
Raymond Hettinger664347b2004-12-04 21:21:53 +0000991 def __call__(self, *args, **kwds):
992 return self.run(*args, **kwds)
993
Fred Drake02538202001-03-21 18:09:46 +0000994 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000995 """Run the tests without collecting errors in a TestResult"""
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000996 for test in self._tests:
997 test.debug()
Fred Drake02538202001-03-21 18:09:46 +0000998
999
Benjamin Peterson692428e2009-03-23 21:50:21 +00001000class ClassTestSuite(TestSuite):
1001 """
1002 Suite of tests derived from a single TestCase class.
1003 """
1004
1005 def __init__(self, tests, class_collected_from):
1006 super(ClassTestSuite, self).__init__(tests)
1007 self.collected_from = class_collected_from
1008
1009 def id(self):
1010 module = getattr(self.collected_from, "__module__", None)
1011 if module is not None:
1012 return "{0}.{1}".format(module, self.collected_from.__name__)
1013 return self.collected_from.__name__
1014
1015 def run(self, result):
1016 if getattr(self.collected_from, "__unittest_skip__", False):
1017 # ClassTestSuite result pretends to be a TestCase enough to be
1018 # reported.
1019 result.startTest(self)
1020 try:
1021 result.addSkip(self, self.collected_from.__unittest_skip_why__)
1022 finally:
1023 result.stopTest(self)
1024 else:
1025 result = super(ClassTestSuite, self).run(result)
1026 return result
1027
1028 shortDescription = id
1029
1030
Fred Drake02538202001-03-21 18:09:46 +00001031class FunctionTestCase(TestCase):
1032 """A test case that wraps a test function.
1033
1034 This is useful for slipping pre-existing test functions into the
Georg Brandl15c5ce92007-03-07 09:09:40 +00001035 unittest framework. Optionally, set-up and tidy-up functions can be
Fred Drake02538202001-03-21 18:09:46 +00001036 supplied. As with TestCase, the tidy-up ('tearDown') function will
1037 always be called if the set-up ('setUp') function ran successfully.
1038 """
1039
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001040 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1041 super(FunctionTestCase, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001042 self.__setUpFunc = setUp
1043 self.__tearDownFunc = tearDown
1044 self.__testFunc = testFunc
1045 self.__description = description
1046
1047 def setUp(self):
1048 if self.__setUpFunc is not None:
1049 self.__setUpFunc()
1050
1051 def tearDown(self):
1052 if self.__tearDownFunc is not None:
1053 self.__tearDownFunc()
1054
1055 def runTest(self):
1056 self.__testFunc()
1057
1058 def id(self):
1059 return self.__testFunc.__name__
1060
Georg Brandl15c5ce92007-03-07 09:09:40 +00001061 def __eq__(self, other):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001062 if not isinstance(other, self.__class__):
1063 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +00001064
1065 return self.__setUpFunc == other.__setUpFunc and \
1066 self.__tearDownFunc == other.__tearDownFunc and \
1067 self.__testFunc == other.__testFunc and \
1068 self.__description == other.__description
1069
1070 def __ne__(self, other):
1071 return not self == other
1072
1073 def __hash__(self):
Collin Winter9453e5d2007-03-09 23:30:39 +00001074 return hash((type(self), self.__setUpFunc, self.__tearDownFunc,
1075 self.__testFunc, self.__description))
Georg Brandl15c5ce92007-03-07 09:09:40 +00001076
Fred Drake02538202001-03-21 18:09:46 +00001077 def __str__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +00001078 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +00001079
1080 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +00001081 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
Fred Drake02538202001-03-21 18:09:46 +00001082
1083 def shortDescription(self):
1084 if self.__description is not None: return self.__description
1085 doc = self.__testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +00001086 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +00001087
1088
1089
1090##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001091# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +00001092##############################################################################
1093
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001094class TestLoader(object):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001095 """
1096 This class is responsible for loading tests according to various criteria
1097 and returning them wrapped in a TestSuite
Fred Drake02538202001-03-21 18:09:46 +00001098 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001099 testMethodPrefix = 'test'
1100 sortTestMethodsUsing = cmp
1101 suiteClass = TestSuite
Benjamin Peterson692428e2009-03-23 21:50:21 +00001102 classSuiteClass = ClassTestSuite
Fred Drake02538202001-03-21 18:09:46 +00001103
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001104 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001105 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +00001106 if issubclass(testCaseClass, TestSuite):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001107 raise TypeError("Test cases should not be derived from TestSuite." \
1108 " Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +00001109 testCaseNames = self.getTestCaseNames(testCaseClass)
1110 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1111 testCaseNames = ['runTest']
Benjamin Peterson692428e2009-03-23 21:50:21 +00001112 suite = self.classSuiteClass(map(testCaseClass, testCaseNames),
1113 testCaseClass)
1114 return suite
Fred Drake02538202001-03-21 18:09:46 +00001115
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001116 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +00001117 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001118 tests = []
1119 for name in dir(module):
1120 obj = getattr(module, name)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001121 if isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001122 tests.append(self.loadTestsFromTestCase(obj))
1123 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +00001124
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001125 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001126 """Return a suite of all tests cases given a string specifier.
1127
1128 The name may resolve either to a module, a test case class, a
1129 test method within a test case class, or a callable object which
1130 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +00001131
Steve Purcell15d89272001-04-12 09:05:01 +00001132 The method optionally resolves the names relative to a given module.
1133 """
Steve Purcell7e743842003-09-22 11:08:12 +00001134 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001135 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +00001136 parts_copy = parts[:]
1137 while parts_copy:
1138 try:
1139 module = __import__('.'.join(parts_copy))
1140 break
1141 except ImportError:
1142 del parts_copy[-1]
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001143 if not parts_copy:
1144 raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +00001145 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001146 obj = module
1147 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +00001148 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +00001149
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001150 if isinstance(obj, types.ModuleType):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001151 return self.loadTestsFromModule(obj)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001152 elif isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001153 return self.loadTestsFromTestCase(obj)
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001154 elif (isinstance(obj, types.UnboundMethodType) and
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001155 isinstance(parent, type) and
Georg Brandl15c5ce92007-03-07 09:09:40 +00001156 issubclass(parent, TestCase)):
1157 return TestSuite([parent(obj.__name__)])
Steve Purcell397b45d2003-10-26 10:41:03 +00001158 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +00001159 return obj
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001160 elif hasattr(obj, '__call__'):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001161 test = obj()
Georg Brandl15c5ce92007-03-07 09:09:40 +00001162 if isinstance(test, TestSuite):
1163 return test
1164 elif isinstance(test, TestCase):
1165 return TestSuite([test])
1166 else:
1167 raise TypeError("calling %s returned %s, not a test" %
1168 (obj, test))
Fred Drake02538202001-03-21 18:09:46 +00001169 else:
Georg Brandl15c5ce92007-03-07 09:09:40 +00001170 raise TypeError("don't know how to make test from: %s" % obj)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001171
1172 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001173 """Return a suite of all tests cases found using the given sequence
1174 of string specifiers. See 'loadTestsFromName()'.
1175 """
Steve Purcell7e743842003-09-22 11:08:12 +00001176 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001177 return self.suiteClass(suites)
1178
1179 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001180 """Return a sorted sequence of method names found within testCaseClass
1181 """
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001182 def isTestMethod(attrname, testCaseClass=testCaseClass,
1183 prefix=self.testMethodPrefix):
1184 return attrname.startswith(prefix) and \
1185 hasattr(getattr(testCaseClass, attrname), '__call__')
Steve Purcell7e743842003-09-22 11:08:12 +00001186 testFnNames = filter(isTestMethod, dir(testCaseClass))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001187 if self.sortTestMethodsUsing:
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001188 testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001189 return testFnNames
1190
1191
1192
1193defaultTestLoader = TestLoader()
1194
1195
1196##############################################################################
1197# Patches for old functions: these functions should be considered obsolete
1198##############################################################################
1199
1200def _makeLoader(prefix, sortUsing, suiteClass=None):
1201 loader = TestLoader()
1202 loader.sortTestMethodsUsing = sortUsing
1203 loader.testMethodPrefix = prefix
1204 if suiteClass: loader.suiteClass = suiteClass
1205 return loader
1206
1207def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
1208 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1209
1210def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1211 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
1212
1213def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1214 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +00001215
1216
1217##############################################################################
1218# Text UI
1219##############################################################################
1220
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001221class _WritelnDecorator(object):
Fred Drake02538202001-03-21 18:09:46 +00001222 """Used to decorate file-like objects with a handy 'writeln' method"""
1223 def __init__(self,stream):
1224 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +00001225
1226 def __getattr__(self, attr):
1227 return getattr(self.stream,attr)
1228
Raymond Hettinger91dd19d2003-09-13 02:58:00 +00001229 def writeln(self, arg=None):
Benjamin Petersond0cdb2d2009-03-24 23:07:07 +00001230 if arg:
1231 self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001232 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +00001233
Fred Drake02538202001-03-21 18:09:46 +00001234
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001235class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +00001236 """A test result class that can print formatted text results to a stream.
1237
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001238 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +00001239 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001240 separator1 = '=' * 70
1241 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +00001242
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001243 def __init__(self, stream, descriptions, verbosity):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001244 super(_TextTestResult, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001245 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001246 self.showAll = verbosity > 1
1247 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +00001248 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001249
1250 def getDescription(self, test):
1251 if self.descriptions:
1252 return test.shortDescription() or str(test)
1253 else:
1254 return str(test)
1255
Fred Drake02538202001-03-21 18:09:46 +00001256 def startTest(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001257 super(_TextTestResult, self).startTest(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001258 if self.showAll:
1259 self.stream.write(self.getDescription(test))
1260 self.stream.write(" ... ")
Georg Brandld0632402008-05-11 15:17:41 +00001261 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001262
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001263 def addSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001264 super(_TextTestResult, self).addSuccess(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001265 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001266 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001267 elif self.dots:
1268 self.stream.write('.')
Georg Brandld0632402008-05-11 15:17:41 +00001269 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001270
1271 def addError(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001272 super(_TextTestResult, self).addError(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001273 if self.showAll:
1274 self.stream.writeln("ERROR")
1275 elif self.dots:
1276 self.stream.write('E')
Georg Brandld0632402008-05-11 15:17:41 +00001277 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001278
1279 def addFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001280 super(_TextTestResult, self).addFailure(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001281 if self.showAll:
1282 self.stream.writeln("FAIL")
1283 elif self.dots:
1284 self.stream.write('F')
Georg Brandld0632402008-05-11 15:17:41 +00001285 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001286
Benjamin Peterson692428e2009-03-23 21:50:21 +00001287 def addSkip(self, test, reason):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001288 super(_TextTestResult, self).addSkip(test, reason)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001289 if self.showAll:
1290 self.stream.writeln("skipped {0!r}".format(reason))
1291 elif self.dots:
1292 self.stream.write("s")
1293 self.stream.flush()
1294
1295 def addExpectedFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001296 super(_TextTestResult, self).addExpectedFailure(test, err)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001297 if self.showAll:
1298 self.stream.writeln("expected failure")
1299 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001300 self.stream.write("x")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001301 self.stream.flush()
1302
1303 def addUnexpectedSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001304 super(_TextTestResult, self).addUnexpectedSuccess(test)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001305 if self.showAll:
1306 self.stream.writeln("unexpected success")
1307 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001308 self.stream.write("u")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001309 self.stream.flush()
1310
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001311 def printErrors(self):
1312 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001313 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001314 self.printErrorList('ERROR', self.errors)
1315 self.printErrorList('FAIL', self.failures)
1316
1317 def printErrorList(self, flavour, errors):
1318 for test, err in errors:
1319 self.stream.writeln(self.separator1)
1320 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1321 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +00001322 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +00001323
1324
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001325class TextTestRunner(object):
Fred Drake02538202001-03-21 18:09:46 +00001326 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +00001327
Fred Drake02538202001-03-21 18:09:46 +00001328 It prints out the names of tests as they are run, errors as they
1329 occur, and a summary of the results at the end of the test run.
1330 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001331 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +00001332 self.stream = _WritelnDecorator(stream)
1333 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001334 self.verbosity = verbosity
1335
1336 def _makeResult(self):
1337 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +00001338
1339 def run(self, test):
1340 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001341 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +00001342 startTime = time.time()
1343 test(result)
1344 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +00001345 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001346 result.printErrors()
1347 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +00001348 run = result.testsRun
1349 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +00001350 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +00001351 self.stream.writeln()
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001352 results = map(len, (result.expectedFailures,
1353 result.unexpectedSuccesses,
Benjamin Peterson692428e2009-03-23 21:50:21 +00001354 result.skipped))
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001355 expectedFails, unexpectedSuccesses, skipped = results
Benjamin Peterson692428e2009-03-23 21:50:21 +00001356 infos = []
Fred Drake02538202001-03-21 18:09:46 +00001357 if not result.wasSuccessful():
Benjamin Peterson692428e2009-03-23 21:50:21 +00001358 self.stream.write("FAILED")
Fred Drake02538202001-03-21 18:09:46 +00001359 failed, errored = map(len, (result.failures, result.errors))
1360 if failed:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001361 infos.append("failures=%d" % failed)
Fred Drake02538202001-03-21 18:09:46 +00001362 if errored:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001363 infos.append("errors=%d" % errored)
Fred Drake02538202001-03-21 18:09:46 +00001364 else:
Benjamin Petersona473f002009-03-24 22:56:32 +00001365 self.stream.write("OK")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001366 if skipped:
1367 infos.append("skipped=%d" % skipped)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001368 if expectedFails:
1369 infos.append("expected failures=%d" % expectedFails)
1370 if unexpectedSuccesses:
1371 infos.append("unexpected successes=%d" % unexpectedSuccesses)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001372 if infos:
1373 self.stream.writeln(" (%s)" % (", ".join(infos),))
Benjamin Petersona473f002009-03-24 22:56:32 +00001374 else:
1375 self.stream.write("\n")
Fred Drake02538202001-03-21 18:09:46 +00001376 return result
Tim Petersa19a1682001-03-29 04:36:09 +00001377
Fred Drake02538202001-03-21 18:09:46 +00001378
Fred Drake02538202001-03-21 18:09:46 +00001379
1380##############################################################################
1381# Facilities for running tests from the command line
1382##############################################################################
1383
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001384class TestProgram(object):
Fred Drake02538202001-03-21 18:09:46 +00001385 """A command-line program that runs a set of tests; this is primarily
1386 for making test modules conveniently executable.
1387 """
1388 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +00001389Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001390
1391Options:
1392 -h, --help Show this message
1393 -v, --verbose Verbose output
1394 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +00001395
1396Examples:
1397 %(progName)s - run default set of tests
1398 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001399 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1400 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +00001401 in MyTestCase
1402"""
1403 def __init__(self, module='__main__', defaultTest=None,
Georg Brandld0a96252007-03-07 09:21:06 +00001404 argv=None, testRunner=TextTestRunner,
1405 testLoader=defaultTestLoader):
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001406 if isinstance(module, basestring):
Fred Drake02538202001-03-21 18:09:46 +00001407 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +00001408 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +00001409 self.module = getattr(self.module, part)
1410 else:
1411 self.module = module
1412 if argv is None:
1413 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001414 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +00001415 self.defaultTest = defaultTest
1416 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001417 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +00001418 self.progName = os.path.basename(argv[0])
1419 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +00001420 self.runTests()
1421
1422 def usageExit(self, msg=None):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001423 if msg:
1424 print msg
Fred Drake02538202001-03-21 18:09:46 +00001425 print self.USAGE % self.__dict__
1426 sys.exit(2)
1427
1428 def parseArgs(self, argv):
1429 import getopt
Benjamin Peterson692428e2009-03-23 21:50:21 +00001430 long_opts = ['help','verbose','quiet']
Fred Drake02538202001-03-21 18:09:46 +00001431 try:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001432 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
Fred Drake02538202001-03-21 18:09:46 +00001433 for opt, value in options:
1434 if opt in ('-h','-H','--help'):
1435 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001436 if opt in ('-q','--quiet'):
1437 self.verbosity = 0
1438 if opt in ('-v','--verbose'):
1439 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +00001440 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001441 self.test = self.testLoader.loadTestsFromModule(self.module)
1442 return
Fred Drake02538202001-03-21 18:09:46 +00001443 if len(args) > 0:
1444 self.testNames = args
1445 else:
1446 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001447 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +00001448 except getopt.error, msg:
1449 self.usageExit(msg)
1450
1451 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001452 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1453 self.module)
Fred Drake02538202001-03-21 18:09:46 +00001454
1455 def runTests(self):
Georg Brandld0a96252007-03-07 09:21:06 +00001456 if isinstance(self.testRunner, (type, types.ClassType)):
1457 try:
1458 testRunner = self.testRunner(verbosity=self.verbosity)
1459 except TypeError:
1460 # didn't accept the verbosity argument
1461 testRunner = self.testRunner()
1462 else:
1463 # it is assumed to be a TestRunner instance
1464 testRunner = self.testRunner
1465 result = testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +00001466 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +00001467
1468main = TestProgram
1469
1470
1471##############################################################################
1472# Executing this module from the command line
1473##############################################################################
1474
1475if __name__ == "__main__":
1476 main(module=None)