blob: ba6a0f9ce6649425059afc9520a14354099a0eb9 [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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000470 def assertFalse(self, expr, msg=None):
Fred Drake02538202001-03-21 18:09:46 +0000471 "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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000475 def assertTrue(self, expr, msg=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000476 """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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000480 def assertRaises(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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000491 with self.assertRaises(some_error_class):
Antoine Pitrou697ca3d2008-12-28 14:09:36 +0000492 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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000527 def assertEqual(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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000534 def assertNotEqual(self, first, second, msg=None):
Steve Purcell15d89272001-04-12 09:05:01 +0000535 """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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000541 def assertAlmostEqual(self, first, second, places=7, msg=None):
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000542 """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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000553 def assertNotAlmostEqual(self, first, second, places=7, msg=None):
Raymond Hettingerc7b07692002-12-29 17:59:24 +0000554 """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
Gregory P. Smith7558d572009-03-31 19:03:28 +0000567 # The plurals are undocumented. Keep them that way to discourage use.
568 # Do not add more. Do not remove.
569 # Going through a deprecation cycle on these would annoy many people.
570 assertEquals = assertEqual
571 assertNotEquals = assertNotEqual
572 assertAlmostEquals = assertAlmostEqual
573 assertNotAlmostEquals = assertNotAlmostEqual
574 assert_ = assertTrue
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000575
Gregory P. Smith7558d572009-03-31 19:03:28 +0000576 # These fail* assertion method names are pending deprecation and will
577 # be a deprecation warning in 3.2; http://bugs.python.org/issue2578
578 failUnlessEqual = assertEqual
579 failIfEqual = assertNotEqual
580 failUnlessAlmostEqual = assertAlmostEqual
581 failIfAlmostEqual = assertNotAlmostEqual
582 failUnless = assertTrue
583 failUnlessRaises = assertRaises
584 failIf = assertFalse
Steve Purcell15d89272001-04-12 09:05:01 +0000585
Steve Purcell5ddd1a82001-03-22 08:45:36 +0000586
Gregory P. Smith28399852009-03-31 16:54:10 +0000587 def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
588 """An equality assertion for ordered sequences (like lists and tuples).
589
590 For the purposes of this function, a valid orderd sequence type is one
591 which can be indexed, has a length, and has an equality operator.
592
593 Args:
594 seq1: The first sequence to compare.
595 seq2: The second sequence to compare.
596 seq_type: The expected datatype of the sequences, or None if no
597 datatype should be enforced.
598 msg: Optional message to use on failure instead of a list of
599 differences.
600 """
601 if seq_type != None:
602 seq_type_name = seq_type.__name__
603 if not isinstance(seq1, seq_type):
604 raise self.failureException('First sequence is not a %s: %r'
605 % (seq_type_name, seq1))
606 if not isinstance(seq2, seq_type):
607 raise self.failureException('Second sequence is not a %s: %r'
608 % (seq_type_name, seq2))
609 else:
610 seq_type_name = "sequence"
611
612 differing = None
613 try:
614 len1 = len(seq1)
615 except (TypeError, NotImplementedError):
616 differing = 'First %s has no length. Non-sequence?' % (
617 seq_type_name)
618
619 if differing is None:
620 try:
621 len2 = len(seq2)
622 except (TypeError, NotImplementedError):
623 differing = 'Second %s has no length. Non-sequence?' % (
624 seq_type_name)
625
626 if differing is None:
627 if seq1 == seq2:
628 return
629
630 for i in xrange(min(len1, len2)):
631 try:
632 item1 = seq1[i]
633 except (TypeError, IndexError, NotImplementedError):
634 differing = ('Unable to index element %d of first %s\n' %
635 (i, seq_type_name))
636 break
637
638 try:
639 item2 = seq2[i]
640 except (TypeError, IndexError, NotImplementedError):
641 differing = ('Unable to index element %d of second %s\n' %
642 (i, seq_type_name))
643 break
644
645 if item1 != item2:
646 differing = ('First differing element %d:\n%s\n%s\n' %
647 (i, item1, item2))
648 break
649 else:
650 if (len1 == len2 and seq_type is None and
651 type(seq1) != type(seq2)):
652 # The sequences are the same, but have differing types.
653 return
654 # A catch-all message for handling arbitrary user-defined
655 # sequences.
656 differing = '%ss differ:\n' % seq_type_name.capitalize()
657 if len1 > len2:
658 differing = ('First %s contains %d additional '
659 'elements.\n' % (seq_type_name, len1 - len2))
660 try:
661 differing += ('First extra element %d:\n%s\n' %
662 (len2, seq1[len2]))
663 except (TypeError, IndexError, NotImplementedError):
664 differing += ('Unable to index element %d '
665 'of first %s\n' % (len2, seq_type_name))
666 elif len1 < len2:
667 differing = ('Second %s contains %d additional '
668 'elements.\n' % (seq_type_name, len2 - len1))
669 try:
670 differing += ('First extra element %d:\n%s\n' %
671 (len1, seq2[len1]))
672 except (TypeError, IndexError, NotImplementedError):
673 differing += ('Unable to index element %d '
674 'of second %s\n' % (len1, seq_type_name))
675 if not msg:
676 msg = '\n'.join(difflib.ndiff(pprint.pformat(seq1).splitlines(),
677 pprint.pformat(seq2).splitlines()))
678 self.fail(differing + msg)
679
680 def assertListEqual(self, list1, list2, msg=None):
681 """A list-specific equality assertion.
682
683 Args:
684 list1: The first list to compare.
685 list2: The second list to compare.
686 msg: Optional message to use on failure instead of a list of
687 differences.
688
689 """
690 self.assertSequenceEqual(list1, list2, msg, seq_type=list)
691
692 def assertTupleEqual(self, tuple1, tuple2, msg=None):
693 """A tuple-specific equality assertion.
694
695 Args:
696 tuple1: The first tuple to compare.
697 tuple2: The second tuple to compare.
698 msg: Optional message to use on failure instead of a list of
699 differences.
700 """
701 self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
702
703 def assertSetEqual(self, set1, set2, msg=None):
704 """A set-specific equality assertion.
705
706 Args:
707 set1: The first set to compare.
708 set2: The second set to compare.
709 msg: Optional message to use on failure instead of a list of
710 differences.
711
712 For more general containership equality, assertSameElements will work
713 with things other than sets. This uses ducktyping to support
714 different types of sets, and is optimized for sets specifically
715 (parameters must support a difference method).
716 """
717 try:
718 difference1 = set1.difference(set2)
719 except TypeError, e:
720 self.fail('invalid type when attempting set difference: %s' % e)
721 except AttributeError, e:
722 self.fail('first argument does not support set difference: %s' % e)
723
724 try:
725 difference2 = set2.difference(set1)
726 except TypeError, e:
727 self.fail('invalid type when attempting set difference: %s' % e)
728 except AttributeError, e:
729 self.fail('second argument does not support set difference: %s' % e)
730
731 if not (difference1 or difference2):
732 return
733
734 if msg is not None:
735 self.fail(msg)
736
737 lines = []
738 if difference1:
739 lines.append('Items in the first set but not the second:')
740 for item in difference1:
741 lines.append(repr(item))
742 if difference2:
743 lines.append('Items in the second set but not the first:')
744 for item in difference2:
745 lines.append(repr(item))
746 self.fail('\n'.join(lines))
747
748 def assertIn(self, a, b, msg=None):
749 """Just like self.assert_(a in b), but with a nicer default message."""
750 if msg is None:
751 msg = '"%s" not found in "%s"' % (a, b)
752 self.assert_(a in b, msg)
753
754 def assertNotIn(self, a, b, msg=None):
755 """Just like self.assert_(a not in b), but with a nicer default message."""
756 if msg is None:
757 msg = '"%s" unexpectedly found in "%s"' % (a, b)
758 self.assert_(a not in b, msg)
759
760 def assertDictEqual(self, d1, d2, msg=None):
761 self.assert_(isinstance(d1, dict), 'First argument is not a dictionary')
762 self.assert_(isinstance(d2, dict), 'Second argument is not a dictionary')
763
764 if d1 != d2:
765 self.fail(msg or ('\n' + '\n'.join(difflib.ndiff(
766 pprint.pformat(d1).splitlines(),
767 pprint.pformat(d2).splitlines()))))
768
769 def assertDictContainsSubset(self, expected, actual, msg=None):
770 """Checks whether actual is a superset of expected."""
771 missing = []
772 mismatched = []
773 for key, value in expected.iteritems():
774 if key not in actual:
775 missing.append(key)
776 elif value != actual[key]:
777 mismatched.append('%s, expected: %s, actual: %s' % (key, value,
778 actual[key]))
779
780 if not (missing or mismatched):
781 return
782
783 missing_msg = mismatched_msg = ''
784 if missing:
785 missing_msg = 'Missing: %s' % ','.join(missing)
786 if mismatched:
787 mismatched_msg = 'Mismatched values: %s' % ','.join(mismatched)
788
789 if msg:
790 msg = '%s: %s; %s' % (msg, missing_msg, mismatched_msg)
791 else:
792 msg = '%s; %s' % (missing_msg, mismatched_msg)
793 self.fail(msg)
794
795 def assertSameElements(self, expected_seq, actual_seq, msg=None):
796 """An unordered sequence specific comparison.
797
798 Raises with an error message listing which elements of expected_seq
799 are missing from actual_seq and vice versa if any.
800 """
801 try:
802 expected = set(expected_seq)
803 actual = set(actual_seq)
804 missing = list(expected.difference(actual))
805 unexpected = list(actual.difference(expected))
806 missing.sort()
807 unexpected.sort()
808 except TypeError:
809 # Fall back to slower list-compare if any of the objects are
810 # not hashable.
811 expected = list(expected_seq)
812 actual = list(actual_seq)
813 expected.sort()
814 actual.sort()
815 missing, unexpected = _SortedListDifference(expected, actual)
816 errors = []
817 if missing:
818 errors.append('Expected, but missing:\n %r\n' % missing)
819 if unexpected:
820 errors.append('Unexpected, but present:\n %r\n' % unexpected)
821 if errors:
822 self.fail(msg or ''.join(errors))
823
824 def assertMultiLineEqual(self, first, second, msg=None):
825 """Assert that two multi-line strings are equal."""
826 self.assert_(isinstance(first, types.StringTypes), (
827 'First argument is not a string'))
828 self.assert_(isinstance(second, types.StringTypes), (
829 'Second argument is not a string'))
830
831 if first != second:
832 raise self.failureException(
833 msg or '\n' + ''.join(difflib.ndiff(first.splitlines(True),
834 second.splitlines(True))))
835
836 def assertLess(self, a, b, msg=None):
837 """Just like self.assert_(a < b), but with a nicer default message."""
838 if msg is None:
839 msg = '"%r" unexpectedly not less than "%r"' % (a, b)
840 self.assert_(a < b, msg)
841
842 def assertLessEqual(self, a, b, msg=None):
843 """Just like self.assert_(a <= b), but with a nicer default message."""
844 if msg is None:
845 msg = '"%r" unexpectedly not less than or equal to "%r"' % (a, b)
846 self.assert_(a <= b, msg)
847
848 def assertGreater(self, a, b, msg=None):
849 """Just like self.assert_(a > b), but with a nicer default message."""
850 if msg is None:
851 msg = '"%r" unexpectedly not greater than "%r"' % (a, b)
852 self.assert_(a > b, msg)
853
854 def assertGreaterEqual(self, a, b, msg=None):
855 """Just like self.assert_(a >= b), but with a nicer default message."""
856 if msg is None:
857 msg = '"%r" unexpectedly not greater than or equal to "%r"' % (a, b)
858 self.assert_(a >= b, msg)
859
860 def assertIsNone(self, obj, msg=None):
861 """Same as self.assert_(obj is None), with a nicer default message."""
862 if msg is None:
863 msg = '"%s" unexpectedly not None' % obj
864 self.assert_(obj is None, msg)
865
866 def assertIsNotNone(self, obj, msg='unexpectedly None'):
867 """Included for symmetry with assertIsNone."""
868 self.assert_(obj is not None, msg)
869
870 def assertRaisesRegexp(self, expected_exception, expected_regexp,
871 callable_obj=None, *args, **kwargs):
872 """Asserts that the message in a raised exception matches a regexp.
873
874 Args:
875 expected_exception: Exception class expected to be raised.
876 expected_regexp: Regexp (re pattern object or string) expected
877 to be found in error message.
878 callable_obj: Function to be called.
879 args: Extra args.
880 kwargs: Extra kwargs.
881 """
882 context = _AssertRaisesContext(expected_exception, self, expected_regexp)
883 if callable_obj is None:
884 return context
885 with context:
886 callable_obj(*args, **kwargs)
887
888 def assertRegexpMatches(self, text, expected_regex, msg=None):
889 if isinstance(expected_regex, basestring):
890 expected_regex = re.compile(expected_regex)
891 if not expected_regex.search(text):
892 msg = msg or "Regexp didn't match"
893 msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
894 raise self.failureException(msg)
895
896
897def _SortedListDifference(expected, actual):
898 """Finds elements in only one or the other of two, sorted input lists.
899
900 Returns a two-element tuple of lists. The first list contains those
901 elements in the "expected" list but not in the "actual" list, and the
902 second contains those elements in the "actual" list but not in the
903 "expected" list. Duplicate elements in either input list are ignored.
904 """
905 i = j = 0
906 missing = []
907 unexpected = []
908 while True:
909 try:
910 e = expected[i]
911 a = actual[j]
912 if e < a:
913 missing.append(e)
914 i += 1
915 while expected[i] == e:
916 i += 1
917 elif e > a:
918 unexpected.append(a)
919 j += 1
920 while actual[j] == a:
921 j += 1
922 else:
923 i += 1
924 try:
925 while expected[i] == e:
926 i += 1
927 finally:
928 j += 1
929 while actual[j] == a:
930 j += 1
931 except IndexError:
932 missing.extend(expected[i:])
933 unexpected.extend(actual[j:])
934 break
935 return missing, unexpected
936
Fred Drake02538202001-03-21 18:09:46 +0000937
Antoine Pitroudae1a6a2008-12-28 16:01:11 +0000938class TestSuite(object):
Fred Drake02538202001-03-21 18:09:46 +0000939 """A test suite is a composite test consisting of a number of TestCases.
940
941 For use, create an instance of TestSuite, then add test case instances.
942 When all tests have been added, the suite can be passed to a test
943 runner, such as TextTestRunner. It will run the individual test cases
944 in the order in which they were added, aggregating the results. When
945 subclassing, do not forget to call the base class constructor.
946 """
947 def __init__(self, tests=()):
948 self._tests = []
949 self.addTests(tests)
950
951 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +0000952 return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
Fred Drake02538202001-03-21 18:09:46 +0000953
Georg Brandl15c5ce92007-03-07 09:09:40 +0000954 def __eq__(self, other):
Benjamin Peterson692428e2009-03-23 21:50:21 +0000955 if not isinstance(other, self.__class__):
956 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +0000957 return self._tests == other._tests
958
959 def __ne__(self, other):
960 return not self == other
961
Nick Coghlan48361f52008-08-11 15:45:58 +0000962 # Can't guarantee hash invariant, so flag as unhashable
963 __hash__ = None
964
Jim Fultonfafd8742004-08-28 15:22:12 +0000965 def __iter__(self):
966 return iter(self._tests)
967
Fred Drake02538202001-03-21 18:09:46 +0000968 def countTestCases(self):
969 cases = 0
970 for test in self._tests:
Steve Purcell7e743842003-09-22 11:08:12 +0000971 cases += test.countTestCases()
Fred Drake02538202001-03-21 18:09:46 +0000972 return cases
973
974 def addTest(self, test):
Georg Brandld9e50262007-03-07 11:54:49 +0000975 # sanity checks
Raymond Hettinger5930d8f2008-07-10 16:06:41 +0000976 if not hasattr(test, '__call__'):
Georg Brandld9e50262007-03-07 11:54:49 +0000977 raise TypeError("the test to add must be callable")
Benjamin Petersona7d441d2009-03-24 00:35:20 +0000978 if isinstance(test, type) and issubclass(test, (TestCase, TestSuite)):
Georg Brandld9e50262007-03-07 11:54:49 +0000979 raise TypeError("TestCases and TestSuites must be instantiated "
980 "before passing them to addTest()")
Fred Drake02538202001-03-21 18:09:46 +0000981 self._tests.append(test)
982
983 def addTests(self, tests):
Georg Brandld9e50262007-03-07 11:54:49 +0000984 if isinstance(tests, basestring):
985 raise TypeError("tests must be an iterable of tests, not a string")
Fred Drake02538202001-03-21 18:09:46 +0000986 for test in tests:
987 self.addTest(test)
988
989 def run(self, result):
Fred Drake02538202001-03-21 18:09:46 +0000990 for test in self._tests:
991 if result.shouldStop:
992 break
993 test(result)
994 return result
995
Raymond Hettinger664347b2004-12-04 21:21:53 +0000996 def __call__(self, *args, **kwds):
997 return self.run(*args, **kwds)
998
Fred Drake02538202001-03-21 18:09:46 +0000999 def debug(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001000 """Run the tests without collecting errors in a TestResult"""
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001001 for test in self._tests:
1002 test.debug()
Fred Drake02538202001-03-21 18:09:46 +00001003
1004
Benjamin Peterson692428e2009-03-23 21:50:21 +00001005class ClassTestSuite(TestSuite):
1006 """
1007 Suite of tests derived from a single TestCase class.
1008 """
1009
1010 def __init__(self, tests, class_collected_from):
1011 super(ClassTestSuite, self).__init__(tests)
1012 self.collected_from = class_collected_from
1013
1014 def id(self):
1015 module = getattr(self.collected_from, "__module__", None)
1016 if module is not None:
1017 return "{0}.{1}".format(module, self.collected_from.__name__)
1018 return self.collected_from.__name__
1019
1020 def run(self, result):
1021 if getattr(self.collected_from, "__unittest_skip__", False):
1022 # ClassTestSuite result pretends to be a TestCase enough to be
1023 # reported.
1024 result.startTest(self)
1025 try:
1026 result.addSkip(self, self.collected_from.__unittest_skip_why__)
1027 finally:
1028 result.stopTest(self)
1029 else:
1030 result = super(ClassTestSuite, self).run(result)
1031 return result
1032
1033 shortDescription = id
1034
1035
Fred Drake02538202001-03-21 18:09:46 +00001036class FunctionTestCase(TestCase):
1037 """A test case that wraps a test function.
1038
1039 This is useful for slipping pre-existing test functions into the
Georg Brandl15c5ce92007-03-07 09:09:40 +00001040 unittest framework. Optionally, set-up and tidy-up functions can be
Fred Drake02538202001-03-21 18:09:46 +00001041 supplied. As with TestCase, the tidy-up ('tearDown') function will
1042 always be called if the set-up ('setUp') function ran successfully.
1043 """
1044
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001045 def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
1046 super(FunctionTestCase, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001047 self.__setUpFunc = setUp
1048 self.__tearDownFunc = tearDown
1049 self.__testFunc = testFunc
1050 self.__description = description
1051
1052 def setUp(self):
1053 if self.__setUpFunc is not None:
1054 self.__setUpFunc()
1055
1056 def tearDown(self):
1057 if self.__tearDownFunc is not None:
1058 self.__tearDownFunc()
1059
1060 def runTest(self):
1061 self.__testFunc()
1062
1063 def id(self):
1064 return self.__testFunc.__name__
1065
Georg Brandl15c5ce92007-03-07 09:09:40 +00001066 def __eq__(self, other):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001067 if not isinstance(other, self.__class__):
1068 return NotImplemented
Georg Brandl15c5ce92007-03-07 09:09:40 +00001069
1070 return self.__setUpFunc == other.__setUpFunc and \
1071 self.__tearDownFunc == other.__tearDownFunc and \
1072 self.__testFunc == other.__testFunc and \
1073 self.__description == other.__description
1074
1075 def __ne__(self, other):
1076 return not self == other
1077
1078 def __hash__(self):
Collin Winter9453e5d2007-03-09 23:30:39 +00001079 return hash((type(self), self.__setUpFunc, self.__tearDownFunc,
1080 self.__testFunc, self.__description))
Georg Brandl15c5ce92007-03-07 09:09:40 +00001081
Fred Drake02538202001-03-21 18:09:46 +00001082 def __str__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +00001083 return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
Fred Drake02538202001-03-21 18:09:46 +00001084
1085 def __repr__(self):
Steve Purcelldc391a62002-08-09 09:46:23 +00001086 return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
Fred Drake02538202001-03-21 18:09:46 +00001087
1088 def shortDescription(self):
1089 if self.__description is not None: return self.__description
1090 doc = self.__testFunc.__doc__
Steve Purcell7e743842003-09-22 11:08:12 +00001091 return doc and doc.split("\n")[0].strip() or None
Fred Drake02538202001-03-21 18:09:46 +00001092
1093
1094
1095##############################################################################
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001096# Locating and loading tests
Fred Drake02538202001-03-21 18:09:46 +00001097##############################################################################
1098
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001099class TestLoader(object):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001100 """
1101 This class is responsible for loading tests according to various criteria
1102 and returning them wrapped in a TestSuite
Fred Drake02538202001-03-21 18:09:46 +00001103 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001104 testMethodPrefix = 'test'
1105 sortTestMethodsUsing = cmp
1106 suiteClass = TestSuite
Benjamin Peterson692428e2009-03-23 21:50:21 +00001107 classSuiteClass = ClassTestSuite
Fred Drake02538202001-03-21 18:09:46 +00001108
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001109 def loadTestsFromTestCase(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001110 """Return a suite of all tests cases contained in testCaseClass"""
Johannes Gijsbersd7b6ad42004-11-07 15:46:25 +00001111 if issubclass(testCaseClass, TestSuite):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001112 raise TypeError("Test cases should not be derived from TestSuite." \
1113 " Maybe you meant to derive from TestCase?")
Steve Purcell7e743842003-09-22 11:08:12 +00001114 testCaseNames = self.getTestCaseNames(testCaseClass)
1115 if not testCaseNames and hasattr(testCaseClass, 'runTest'):
1116 testCaseNames = ['runTest']
Benjamin Peterson692428e2009-03-23 21:50:21 +00001117 suite = self.classSuiteClass(map(testCaseClass, testCaseNames),
1118 testCaseClass)
1119 return suite
Fred Drake02538202001-03-21 18:09:46 +00001120
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001121 def loadTestsFromModule(self, module):
Steve Purcell15d89272001-04-12 09:05:01 +00001122 """Return a suite of all tests cases contained in the given module"""
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001123 tests = []
1124 for name in dir(module):
1125 obj = getattr(module, name)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001126 if isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001127 tests.append(self.loadTestsFromTestCase(obj))
1128 return self.suiteClass(tests)
Fred Drake02538202001-03-21 18:09:46 +00001129
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001130 def loadTestsFromName(self, name, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001131 """Return a suite of all tests cases given a string specifier.
1132
1133 The name may resolve either to a module, a test case class, a
1134 test method within a test case class, or a callable object which
1135 returns a TestCase or TestSuite instance.
Tim Peters613b2222001-04-13 05:37:27 +00001136
Steve Purcell15d89272001-04-12 09:05:01 +00001137 The method optionally resolves the names relative to a given module.
1138 """
Steve Purcell7e743842003-09-22 11:08:12 +00001139 parts = name.split('.')
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001140 if module is None:
Steve Purcell7e743842003-09-22 11:08:12 +00001141 parts_copy = parts[:]
1142 while parts_copy:
1143 try:
1144 module = __import__('.'.join(parts_copy))
1145 break
1146 except ImportError:
1147 del parts_copy[-1]
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001148 if not parts_copy:
1149 raise
Armin Rigo1b3c04b2003-10-24 17:15:29 +00001150 parts = parts[1:]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001151 obj = module
1152 for part in parts:
Steve Purcell7e743842003-09-22 11:08:12 +00001153 parent, obj = obj, getattr(obj, part)
Fred Drake02538202001-03-21 18:09:46 +00001154
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001155 if isinstance(obj, types.ModuleType):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001156 return self.loadTestsFromModule(obj)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001157 elif isinstance(obj, type) and issubclass(obj, TestCase):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001158 return self.loadTestsFromTestCase(obj)
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001159 elif (isinstance(obj, types.UnboundMethodType) and
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001160 isinstance(parent, type) and
Georg Brandl15c5ce92007-03-07 09:09:40 +00001161 issubclass(parent, TestCase)):
1162 return TestSuite([parent(obj.__name__)])
Steve Purcell397b45d2003-10-26 10:41:03 +00001163 elif isinstance(obj, TestSuite):
Steve Purcell7e743842003-09-22 11:08:12 +00001164 return obj
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001165 elif hasattr(obj, '__call__'):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001166 test = obj()
Georg Brandl15c5ce92007-03-07 09:09:40 +00001167 if isinstance(test, TestSuite):
1168 return test
1169 elif isinstance(test, TestCase):
1170 return TestSuite([test])
1171 else:
1172 raise TypeError("calling %s returned %s, not a test" %
1173 (obj, test))
Fred Drake02538202001-03-21 18:09:46 +00001174 else:
Georg Brandl15c5ce92007-03-07 09:09:40 +00001175 raise TypeError("don't know how to make test from: %s" % obj)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001176
1177 def loadTestsFromNames(self, names, module=None):
Steve Purcell15d89272001-04-12 09:05:01 +00001178 """Return a suite of all tests cases found using the given sequence
1179 of string specifiers. See 'loadTestsFromName()'.
1180 """
Steve Purcell7e743842003-09-22 11:08:12 +00001181 suites = [self.loadTestsFromName(name, module) for name in names]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001182 return self.suiteClass(suites)
1183
1184 def getTestCaseNames(self, testCaseClass):
Steve Purcell15d89272001-04-12 09:05:01 +00001185 """Return a sorted sequence of method names found within testCaseClass
1186 """
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001187 def isTestMethod(attrname, testCaseClass=testCaseClass,
1188 prefix=self.testMethodPrefix):
1189 return attrname.startswith(prefix) and \
1190 hasattr(getattr(testCaseClass, attrname), '__call__')
Steve Purcell7e743842003-09-22 11:08:12 +00001191 testFnNames = filter(isTestMethod, dir(testCaseClass))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001192 if self.sortTestMethodsUsing:
Raymond Hettinger5930d8f2008-07-10 16:06:41 +00001193 testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing))
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001194 return testFnNames
1195
1196
1197
1198defaultTestLoader = TestLoader()
1199
1200
1201##############################################################################
1202# Patches for old functions: these functions should be considered obsolete
1203##############################################################################
1204
1205def _makeLoader(prefix, sortUsing, suiteClass=None):
1206 loader = TestLoader()
1207 loader.sortTestMethodsUsing = sortUsing
1208 loader.testMethodPrefix = prefix
1209 if suiteClass: loader.suiteClass = suiteClass
1210 return loader
1211
1212def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
1213 return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
1214
1215def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1216 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
1217
1218def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
1219 return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
Fred Drake02538202001-03-21 18:09:46 +00001220
1221
1222##############################################################################
1223# Text UI
1224##############################################################################
1225
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001226class _WritelnDecorator(object):
Fred Drake02538202001-03-21 18:09:46 +00001227 """Used to decorate file-like objects with a handy 'writeln' method"""
1228 def __init__(self,stream):
1229 self.stream = stream
Fred Drake02538202001-03-21 18:09:46 +00001230
1231 def __getattr__(self, attr):
1232 return getattr(self.stream,attr)
1233
Raymond Hettinger91dd19d2003-09-13 02:58:00 +00001234 def writeln(self, arg=None):
Benjamin Petersond0cdb2d2009-03-24 23:07:07 +00001235 if arg:
1236 self.write(arg)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001237 self.write('\n') # text-mode streams translate to \r\n if needed
Tim Petersa19a1682001-03-29 04:36:09 +00001238
Fred Drake02538202001-03-21 18:09:46 +00001239
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001240class _TextTestResult(TestResult):
Fred Drake02538202001-03-21 18:09:46 +00001241 """A test result class that can print formatted text results to a stream.
1242
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001243 Used by TextTestRunner.
Fred Drake02538202001-03-21 18:09:46 +00001244 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001245 separator1 = '=' * 70
1246 separator2 = '-' * 70
Fred Drake02538202001-03-21 18:09:46 +00001247
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001248 def __init__(self, stream, descriptions, verbosity):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001249 super(_TextTestResult, self).__init__()
Fred Drake02538202001-03-21 18:09:46 +00001250 self.stream = stream
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001251 self.showAll = verbosity > 1
1252 self.dots = verbosity == 1
Fred Drake02538202001-03-21 18:09:46 +00001253 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001254
1255 def getDescription(self, test):
1256 if self.descriptions:
1257 return test.shortDescription() or str(test)
1258 else:
1259 return str(test)
1260
Fred Drake02538202001-03-21 18:09:46 +00001261 def startTest(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001262 super(_TextTestResult, self).startTest(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001263 if self.showAll:
1264 self.stream.write(self.getDescription(test))
1265 self.stream.write(" ... ")
Georg Brandld0632402008-05-11 15:17:41 +00001266 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001267
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001268 def addSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001269 super(_TextTestResult, self).addSuccess(test)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001270 if self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001271 self.stream.writeln("ok")
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001272 elif self.dots:
1273 self.stream.write('.')
Georg Brandld0632402008-05-11 15:17:41 +00001274 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001275
1276 def addError(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001277 super(_TextTestResult, self).addError(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001278 if self.showAll:
1279 self.stream.writeln("ERROR")
1280 elif self.dots:
1281 self.stream.write('E')
Georg Brandld0632402008-05-11 15:17:41 +00001282 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001283
1284 def addFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001285 super(_TextTestResult, self).addFailure(test, err)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001286 if self.showAll:
1287 self.stream.writeln("FAIL")
1288 elif self.dots:
1289 self.stream.write('F')
Georg Brandld0632402008-05-11 15:17:41 +00001290 self.stream.flush()
Fred Drake02538202001-03-21 18:09:46 +00001291
Benjamin Peterson692428e2009-03-23 21:50:21 +00001292 def addSkip(self, test, reason):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001293 super(_TextTestResult, self).addSkip(test, reason)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001294 if self.showAll:
1295 self.stream.writeln("skipped {0!r}".format(reason))
1296 elif self.dots:
1297 self.stream.write("s")
1298 self.stream.flush()
1299
1300 def addExpectedFailure(self, test, err):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001301 super(_TextTestResult, self).addExpectedFailure(test, err)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001302 if self.showAll:
1303 self.stream.writeln("expected failure")
1304 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001305 self.stream.write("x")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001306 self.stream.flush()
1307
1308 def addUnexpectedSuccess(self, test):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001309 super(_TextTestResult, self).addUnexpectedSuccess(test)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001310 if self.showAll:
1311 self.stream.writeln("unexpected success")
1312 elif self.dots:
Benjamin Petersona8adceb2009-03-25 21:24:04 +00001313 self.stream.write("u")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001314 self.stream.flush()
1315
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001316 def printErrors(self):
1317 if self.dots or self.showAll:
Fred Drake02538202001-03-21 18:09:46 +00001318 self.stream.writeln()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001319 self.printErrorList('ERROR', self.errors)
1320 self.printErrorList('FAIL', self.failures)
1321
1322 def printErrorList(self, flavour, errors):
1323 for test, err in errors:
1324 self.stream.writeln(self.separator1)
1325 self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
1326 self.stream.writeln(self.separator2)
Steve Purcell7b065702001-09-06 08:24:40 +00001327 self.stream.writeln("%s" % err)
Fred Drake02538202001-03-21 18:09:46 +00001328
1329
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001330class TextTestRunner(object):
Fred Drake02538202001-03-21 18:09:46 +00001331 """A test runner class that displays results in textual form.
Tim Petersa19a1682001-03-29 04:36:09 +00001332
Fred Drake02538202001-03-21 18:09:46 +00001333 It prints out the names of tests as they are run, errors as they
1334 occur, and a summary of the results at the end of the test run.
1335 """
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001336 def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
Fred Drake02538202001-03-21 18:09:46 +00001337 self.stream = _WritelnDecorator(stream)
1338 self.descriptions = descriptions
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001339 self.verbosity = verbosity
1340
1341 def _makeResult(self):
1342 return _TextTestResult(self.stream, self.descriptions, self.verbosity)
Fred Drake02538202001-03-21 18:09:46 +00001343
1344 def run(self, test):
1345 "Run the given test case or test suite."
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001346 result = self._makeResult()
Fred Drake02538202001-03-21 18:09:46 +00001347 startTime = time.time()
1348 test(result)
1349 stopTime = time.time()
Steve Purcell397b45d2003-10-26 10:41:03 +00001350 timeTaken = stopTime - startTime
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001351 result.printErrors()
1352 self.stream.writeln(result.separator2)
Fred Drake02538202001-03-21 18:09:46 +00001353 run = result.testsRun
1354 self.stream.writeln("Ran %d test%s in %.3fs" %
Neal Norwitz76165042002-05-31 14:15:11 +00001355 (run, run != 1 and "s" or "", timeTaken))
Fred Drake02538202001-03-21 18:09:46 +00001356 self.stream.writeln()
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001357 results = map(len, (result.expectedFailures,
1358 result.unexpectedSuccesses,
Benjamin Peterson692428e2009-03-23 21:50:21 +00001359 result.skipped))
Benjamin Petersoncb2b0e42009-03-23 22:29:45 +00001360 expectedFails, unexpectedSuccesses, skipped = results
Benjamin Peterson692428e2009-03-23 21:50:21 +00001361 infos = []
Fred Drake02538202001-03-21 18:09:46 +00001362 if not result.wasSuccessful():
Benjamin Peterson692428e2009-03-23 21:50:21 +00001363 self.stream.write("FAILED")
Fred Drake02538202001-03-21 18:09:46 +00001364 failed, errored = map(len, (result.failures, result.errors))
1365 if failed:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001366 infos.append("failures=%d" % failed)
Fred Drake02538202001-03-21 18:09:46 +00001367 if errored:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001368 infos.append("errors=%d" % errored)
Fred Drake02538202001-03-21 18:09:46 +00001369 else:
Benjamin Petersona473f002009-03-24 22:56:32 +00001370 self.stream.write("OK")
Benjamin Peterson692428e2009-03-23 21:50:21 +00001371 if skipped:
1372 infos.append("skipped=%d" % skipped)
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001373 if expectedFails:
1374 infos.append("expected failures=%d" % expectedFails)
1375 if unexpectedSuccesses:
1376 infos.append("unexpected successes=%d" % unexpectedSuccesses)
Benjamin Peterson692428e2009-03-23 21:50:21 +00001377 if infos:
1378 self.stream.writeln(" (%s)" % (", ".join(infos),))
Benjamin Petersona473f002009-03-24 22:56:32 +00001379 else:
1380 self.stream.write("\n")
Fred Drake02538202001-03-21 18:09:46 +00001381 return result
Tim Petersa19a1682001-03-29 04:36:09 +00001382
Fred Drake02538202001-03-21 18:09:46 +00001383
Fred Drake02538202001-03-21 18:09:46 +00001384
1385##############################################################################
1386# Facilities for running tests from the command line
1387##############################################################################
1388
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001389class TestProgram(object):
Fred Drake02538202001-03-21 18:09:46 +00001390 """A command-line program that runs a set of tests; this is primarily
1391 for making test modules conveniently executable.
1392 """
1393 USAGE = """\
Steve Purcell17a781b2001-04-09 15:37:31 +00001394Usage: %(progName)s [options] [test] [...]
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001395
1396Options:
1397 -h, --help Show this message
1398 -v, --verbose Verbose output
1399 -q, --quiet Minimal output
Fred Drake02538202001-03-21 18:09:46 +00001400
1401Examples:
1402 %(progName)s - run default set of tests
1403 %(progName)s MyTestSuite - run suite 'MyTestSuite'
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001404 %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
1405 %(progName)s MyTestCase - run all 'test*' test methods
Fred Drake02538202001-03-21 18:09:46 +00001406 in MyTestCase
1407"""
1408 def __init__(self, module='__main__', defaultTest=None,
Georg Brandld0a96252007-03-07 09:21:06 +00001409 argv=None, testRunner=TextTestRunner,
1410 testLoader=defaultTestLoader):
Antoine Pitroudae1a6a2008-12-28 16:01:11 +00001411 if isinstance(module, basestring):
Fred Drake02538202001-03-21 18:09:46 +00001412 self.module = __import__(module)
Steve Purcell7e743842003-09-22 11:08:12 +00001413 for part in module.split('.')[1:]:
Fred Drake02538202001-03-21 18:09:46 +00001414 self.module = getattr(self.module, part)
1415 else:
1416 self.module = module
1417 if argv is None:
1418 argv = sys.argv
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001419 self.verbosity = 1
Fred Drake02538202001-03-21 18:09:46 +00001420 self.defaultTest = defaultTest
1421 self.testRunner = testRunner
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001422 self.testLoader = testLoader
Fred Drake02538202001-03-21 18:09:46 +00001423 self.progName = os.path.basename(argv[0])
1424 self.parseArgs(argv)
Fred Drake02538202001-03-21 18:09:46 +00001425 self.runTests()
1426
1427 def usageExit(self, msg=None):
Benjamin Petersona7d441d2009-03-24 00:35:20 +00001428 if msg:
1429 print msg
Fred Drake02538202001-03-21 18:09:46 +00001430 print self.USAGE % self.__dict__
1431 sys.exit(2)
1432
1433 def parseArgs(self, argv):
1434 import getopt
Benjamin Peterson692428e2009-03-23 21:50:21 +00001435 long_opts = ['help','verbose','quiet']
Fred Drake02538202001-03-21 18:09:46 +00001436 try:
Benjamin Peterson692428e2009-03-23 21:50:21 +00001437 options, args = getopt.getopt(argv[1:], 'hHvq', long_opts)
Fred Drake02538202001-03-21 18:09:46 +00001438 for opt, value in options:
1439 if opt in ('-h','-H','--help'):
1440 self.usageExit()
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001441 if opt in ('-q','--quiet'):
1442 self.verbosity = 0
1443 if opt in ('-v','--verbose'):
1444 self.verbosity = 2
Fred Drake02538202001-03-21 18:09:46 +00001445 if len(args) == 0 and self.defaultTest is None:
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001446 self.test = self.testLoader.loadTestsFromModule(self.module)
1447 return
Fred Drake02538202001-03-21 18:09:46 +00001448 if len(args) > 0:
1449 self.testNames = args
1450 else:
1451 self.testNames = (self.defaultTest,)
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001452 self.createTests()
Fred Drake02538202001-03-21 18:09:46 +00001453 except getopt.error, msg:
1454 self.usageExit(msg)
1455
1456 def createTests(self):
Steve Purcell5ddd1a82001-03-22 08:45:36 +00001457 self.test = self.testLoader.loadTestsFromNames(self.testNames,
1458 self.module)
Fred Drake02538202001-03-21 18:09:46 +00001459
1460 def runTests(self):
Georg Brandld0a96252007-03-07 09:21:06 +00001461 if isinstance(self.testRunner, (type, types.ClassType)):
1462 try:
1463 testRunner = self.testRunner(verbosity=self.verbosity)
1464 except TypeError:
1465 # didn't accept the verbosity argument
1466 testRunner = self.testRunner()
1467 else:
1468 # it is assumed to be a TestRunner instance
1469 testRunner = self.testRunner
1470 result = testRunner.run(self.test)
Tim Petersa19a1682001-03-29 04:36:09 +00001471 sys.exit(not result.wasSuccessful())
Fred Drake02538202001-03-21 18:09:46 +00001472
1473main = TestProgram
1474
1475
1476##############################################################################
1477# Executing this module from the command line
1478##############################################################################
1479
1480if __name__ == "__main__":
1481 main(module=None)