~ubuntu-branches/ubuntu/maverick/pygame/maverick

« back to all changes in this revision

Viewing changes to test/test_utils/unittest.py

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-01-14 17:02:11 UTC
  • mfrom: (1.3.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100114170211-21eop2ja7mr9vdcr
Tags: 1.9.1release-0ubuntu1
* New upstream version (lp: #433304)
* debian/control:
  - build-depends on libportmidi-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
'''
 
4
Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
 
5
Smalltalk testing framework.
 
6
 
 
7
This module contains the core framework classes that form the basis of
 
8
specific test cases and suites (TestCase, TestSuite etc.), and also a
 
9
text-based utility class for running the tests and reporting the results
 
10
 (TextTestRunner).
 
11
 
 
12
Simple usage:
 
13
 
 
14
    import unittest
 
15
 
 
16
    class IntegerArithmenticTestCase(unittest.TestCase):
 
17
        def testAdd(self):  ## test method names begin 'test*'
 
18
            self.assertEquals((1 + 2), 3)
 
19
            self.assertEquals(0 + 1, 1)
 
20
        def testMultiply(self):
 
21
            self.assertEquals((0 * 10), 0)
 
22
            self.assertEquals((5 * 8), 40)
 
23
 
 
24
    if __name__ == '__main__':
 
25
        unittest.main()
 
26
 
 
27
Further information is available in the bundled documentation, and from
 
28
 
 
29
  http://pyunit.sourceforge.net/
 
30
 
 
31
Copyright (c) 1999-2003 Steve Purcell
 
32
This module is free software, and you may redistribute it and/or modify
 
33
it under the same terms as Python itself, so long as this copyright message
 
34
and disclaimer are retained in their original form.
 
35
 
 
36
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 
37
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
 
38
THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 
39
DAMAGE.
 
40
 
 
41
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
 
42
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
43
PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
 
44
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 
45
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
46
'''
 
47
 
 
48
__author__ = "Steve Purcell"
 
49
__email__ = "stephen_purcell at yahoo dot com"
 
50
__version__ = "#Revision: 1.63 $"[11:-2]
 
51
 
 
52
import time
 
53
import sys
 
54
import traceback
 
55
import os
 
56
import types
 
57
 
 
58
try:
 
59
    cmp
 
60
except NameError:
 
61
    def cmp(x, y):
 
62
        """Return -1 if x < y, 0 if x == y and 1 if x > y"""
 
63
        return (x > y) - (x < y)
 
64
    cmp = staticmethod(cmp)
 
65
 
 
66
try:
 
67
    types.ClassType
 
68
except AttributeError:
 
69
    class_types = (type,)
 
70
else:
 
71
    class_types = (type, types.ClassType)
 
72
 
 
73
try:
 
74
    callable
 
75
except NameError:
 
76
    def callable(o):
 
77
        try:
 
78
            o.__call__
 
79
        except AttributeError:
 
80
            return False
 
81
        return True
 
82
 
 
83
try:
 
84
    basestring
 
85
except NameError:
 
86
    basestring = str
 
87
 
 
88
def geterror():
 
89
    return sys.exc_info()[1]
 
90
 
 
91
##############################################################################
 
92
# Exported classes and functions
 
93
##############################################################################
 
94
__all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner',
 
95
           'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader']
 
96
 
 
97
# Expose obsolete functions for backwards compatibility
 
98
__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
 
99
 
 
100
 
 
101
 
 
102
 
 
103
def _sort_using_key(seq, key_func):
 
104
    deco = [ (key_func(word), i, word) for i, word in enumerate(seq) ]
 
105
    deco.sort()
 
106
    new_words = [ word for _, _, word in deco ]
 
107
    return new_words
 
108
 
 
109
 
 
110
##############################################################################
 
111
# Backward compatibility
 
112
##############################################################################
 
113
#if sys.version_info[:2] < (2, 2):
 
114
#    False, True = 0, 1
 
115
#    def isinstance(obj, clsinfo):
 
116
#        import __builtin__
 
117
#        if type(clsinfo) in (tuple, list):
 
118
#            for cls in clsinfo:
 
119
#                if cls is type: cls = types.ClassType
 
120
#                if __builtin__.isinstance(obj, cls):
 
121
#                    return 1
 
122
#            return 0
 
123
#        else: return __builtin__.isinstance(obj, clsinfo)
 
124
 
 
125
 
 
126
##############################################################################
 
127
# Test framework core
 
128
##############################################################################
 
129
 
 
130
# All classes defined herein are 'new-style' classes, allowing use of 'super()'
 
131
__metaclass__ = type
 
132
 
 
133
def _strclass(cls):
 
134
    return "%s.%s" % (cls.__module__, cls.__name__)
 
135
 
 
136
__unittest = 1
 
137
 
 
138
class TestResult:
 
139
    """Holder for test result information.
 
140
 
 
141
    Test results are automatically managed by the TestCase and TestSuite
 
142
    classes, and do not need to be explicitly manipulated by writers of tests.
 
143
 
 
144
    Each instance holds the total number of tests run, and collections of
 
145
    failures and errors that occurred among those test runs. The collections
 
146
    contain tuples of (testcase, exceptioninfo), where exceptioninfo is the
 
147
    formatted traceback of the error that occurred.
 
148
    """
 
149
    def __init__(self):
 
150
        self.failures = []
 
151
        self.errors = []
 
152
        self.testsRun = 0
 
153
        self.shouldStop = 0
 
154
 
 
155
    def startTest(self, test):
 
156
        "Called when the given test is about to be run"
 
157
        self.testsRun = self.testsRun + 1
 
158
 
 
159
    def stopTest(self, test):
 
160
        "Called when the given test has been run"
 
161
        pass
 
162
 
 
163
    def addError(self, test, err):
 
164
        """Called when an error has occurred. 'err' is a tuple of values as
 
165
        returned by sys.exc_info().
 
166
        """
 
167
        self.errors.append((test, self._exc_info_to_string(err, test)))
 
168
 
 
169
    def addFailure(self, test, err):
 
170
        """Called when an error has occurred. 'err' is a tuple of values as
 
171
        returned by sys.exc_info()."""
 
172
        self.failures.append((test, self._exc_info_to_string(err, test)))
 
173
 
 
174
    def addSuccess(self, test):
 
175
        "Called when a test has completed successfully"
 
176
        pass
 
177
 
 
178
    def wasSuccessful(self):
 
179
        "Tells whether or not this result was a success"
 
180
        return len(self.failures) == len(self.errors) == 0
 
181
 
 
182
    def stop(self):
 
183
        "Indicates that the tests should be aborted"
 
184
        self.shouldStop = True
 
185
 
 
186
    def _exc_info_to_string(self, err, test):
 
187
        """Converts a sys.exc_info()-style tuple of values into a string."""
 
188
        exctype, value, tb = err
 
189
        # Skip test runner traceback levels
 
190
        while tb and self._is_relevant_tb_level(tb):
 
191
            tb = tb.tb_next
 
192
        if exctype is test.failureException:
 
193
            # Skip assert*() traceback levels
 
194
            length = self._count_relevant_tb_levels(tb)
 
195
            return ''.join(traceback.format_exception(exctype, value, tb, length))
 
196
        return ''.join(traceback.format_exception(exctype, value, tb))
 
197
 
 
198
    def _is_relevant_tb_level(self, tb):
 
199
        return '__unittest' in tb.tb_frame.f_globals
 
200
 
 
201
    def _count_relevant_tb_levels(self, tb):
 
202
        length = 0
 
203
        while tb and not self._is_relevant_tb_level(tb):
 
204
            length += 1
 
205
            tb = tb.tb_next
 
206
        return length
 
207
 
 
208
    def __repr__(self):
 
209
        return "<%s run=%i errors=%i failures=%i>" % \
 
210
               (_strclass(self.__class__), self.testsRun, len(self.errors),
 
211
                len(self.failures))
 
212
 
 
213
class TestCase:
 
214
    """A class whose instances are single test cases.
 
215
 
 
216
    By default, the test code itself should be placed in a method named
 
217
    'runTest'.
 
218
 
 
219
    If the fixture may be used for many test cases, create as
 
220
    many test methods as are needed. When instantiating such a TestCase
 
221
    subclass, specify in the constructor arguments the name of the test method
 
222
    that the instance is to execute.
 
223
 
 
224
    Test authors should subclass TestCase for their own tests. Construction
 
225
    and deconstruction of the test's environment ('fixture') can be
 
226
    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
 
227
 
 
228
    If it is necessary to override the __init__ method, the base class
 
229
    __init__ method must always be called. It is important that subclasses
 
230
    should not change the signature of their __init__ method, since instances
 
231
    of the classes are instantiated automatically by parts of the framework
 
232
    in order to be run.
 
233
    """
 
234
 
 
235
    # This attribute determines which exception will be raised when
 
236
    # the instance's assertion methods fail; test methods raising this
 
237
    # exception will be deemed to have 'failed' rather than 'errored'
 
238
 
 
239
    failureException = AssertionError
 
240
 
 
241
    def __init__(self, methodName='runTest'):
 
242
        """Create an instance of the class that will use the named test
 
243
           method when executed. Raises a ValueError if the instance does
 
244
           not have a method with the specified name.
 
245
        """
 
246
        try:
 
247
            self._testMethodName = methodName
 
248
            testMethod = getattr(self, methodName)
 
249
            self._testMethodDoc = testMethod.__doc__
 
250
        except AttributeError:
 
251
            raise ValueError( "no such test method in %s: %s" % \
 
252
                  (self.__class__, methodName))
 
253
 
 
254
    def setUp(self):
 
255
        "Hook method for setting up the test fixture before exercising it."
 
256
        pass
 
257
 
 
258
    def tearDown(self):
 
259
        "Hook method for deconstructing the test fixture after testing it."
 
260
        pass
 
261
 
 
262
    def countTestCases(self):
 
263
        return 1
 
264
 
 
265
    def defaultTestResult(self):
 
266
        return TestResult()
 
267
 
 
268
    def shortDescription(self):
 
269
        """Returns a one-line description of the test, or None if no
 
270
        description has been provided.
 
271
 
 
272
        The default implementation of this method returns the first line of
 
273
        the specified test method's docstring.
 
274
        """
 
275
        doc = self._testMethodDoc
 
276
        return doc and doc.split("\n")[0].strip() or None
 
277
 
 
278
    def id(self):
 
279
        return "%s.%s" % (_strclass(self.__class__), self._testMethodName)
 
280
 
 
281
    def __str__(self):
 
282
        return "%s (%s)" % (self._testMethodName, _strclass(self.__class__))
 
283
 
 
284
    def __repr__(self):
 
285
        return "<%s testMethod=%s>" % \
 
286
               (_strclass(self.__class__), self._testMethodName)
 
287
 
 
288
    def run(self, result=None):
 
289
        if result is None: result = self.defaultTestResult()
 
290
        result.startTest(self)
 
291
        testMethod = getattr(self, self._testMethodName)
 
292
        try:
 
293
            try:
 
294
                self.setUp()
 
295
            except KeyboardInterrupt:
 
296
                raise
 
297
            except:
 
298
                result.addError(self, self._exc_info())
 
299
                return
 
300
 
 
301
            ok = False
 
302
            try:
 
303
                testMethod()
 
304
                ok = True
 
305
            except self.failureException:
 
306
                result.addFailure(self, self._exc_info())
 
307
            except KeyboardInterrupt:
 
308
                raise
 
309
            except:
 
310
                result.addError(self, self._exc_info())
 
311
 
 
312
            try:
 
313
                self.tearDown()
 
314
            except KeyboardInterrupt:
 
315
                raise
 
316
            except:
 
317
                result.addError(self, self._exc_info())
 
318
                ok = False
 
319
            if ok: result.addSuccess(self)
 
320
        finally:
 
321
            result.stopTest(self)
 
322
 
 
323
    def __call__(self, *args, **kwds):
 
324
        return self.run(*args, **kwds)
 
325
 
 
326
    def debug(self):
 
327
        """Run the test without collecting errors in a TestResult"""
 
328
        self.setUp()
 
329
        getattr(self, self._testMethodName)()
 
330
        self.tearDown()
 
331
 
 
332
    def _exc_info(self):
 
333
        """Return a version of sys.exc_info() with the traceback frame
 
334
           minimised; usually the top level of the traceback frame is not
 
335
           needed.
 
336
        """
 
337
        exctype, excvalue, tb = sys.exc_info()
 
338
        if sys.platform[:4] == 'java': ## tracebacks look different in Jython
 
339
            return (exctype, excvalue, tb)
 
340
        return (exctype, excvalue, tb)
 
341
 
 
342
    def fail(self, msg=None):
 
343
        """Fail immediately, with the given message."""
 
344
        raise self.failureException( msg)
 
345
 
 
346
    def failIf(self, expr, msg=None):
 
347
        "Fail the test if the expression is true."
 
348
        if expr: raise self.failureException( msg)
 
349
 
 
350
    def failUnless(self, expr, msg=None):
 
351
        """Fail the test unless the expression is true."""
 
352
        if not expr: raise self.failureException( msg)
 
353
 
 
354
    def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
 
355
        """Fail unless an exception of class excClass is thrown
 
356
           by callableObj when invoked with arguments args and keyword
 
357
           arguments kwargs. If a different type of exception is
 
358
           thrown, it will not be caught, and the test case will be
 
359
           deemed to have suffered an error, exactly as for an
 
360
           unexpected exception.
 
361
        """
 
362
        try:
 
363
            callableObj(*args, **kwargs)
 
364
        except excClass:
 
365
            return
 
366
        else:
 
367
            if hasattr(excClass,'__name__'): excName = excClass.__name__
 
368
            else: excName = str(excClass)
 
369
            raise self.failureException( "%s not raised" % excName)
 
370
 
 
371
    def failUnlessEqual(self, first, second, msg=None):
 
372
        """Fail if the two objects are unequal as determined by the '=='
 
373
           operator.
 
374
        """
 
375
        if not first == second:
 
376
            raise self.failureException(
 
377
                  (msg or '%r != %r' % (first, second)))
 
378
 
 
379
    def failIfEqual(self, first, second, msg=None):
 
380
        """Fail if the two objects are equal as determined by the '=='
 
381
           operator.
 
382
        """
 
383
        if first == second:
 
384
            raise self.failureException(
 
385
                  (msg or '%r == %r' % (first, second)))
 
386
 
 
387
    def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
 
388
        """Fail if the two objects are unequal as determined by their
 
389
           difference rounded to the given number of decimal places
 
390
           (default 7) and comparing to zero.
 
391
 
 
392
           Note that decimal places (from zero) are usually not the same
 
393
           as significant digits (measured from the most signficant digit).
 
394
        """
 
395
        if round(second-first, places) != 0:
 
396
            raise self.failureException(
 
397
                  (msg or '%r != %r within %r places' % (first, second, places)))
 
398
 
 
399
    def failIfAlmostEqual(self, first, second, places=7, msg=None):
 
400
        """Fail if the two objects are equal as determined by their
 
401
           difference rounded to the given number of decimal places
 
402
           (default 7) and comparing to zero.
 
403
 
 
404
           Note that decimal places (from zero) are usually not the same
 
405
           as significant digits (measured from the most signficant digit).
 
406
        """
 
407
        if round(second-first, places) == 0:
 
408
            raise self.failureException(
 
409
                  (msg or '%r == %r within %r places' % (first, second, places)))
 
410
 
 
411
    # Synonyms for assertion methods
 
412
 
 
413
    assertEqual = assertEquals = failUnlessEqual
 
414
 
 
415
    assertNotEqual = assertNotEquals = failIfEqual
 
416
 
 
417
    assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
 
418
 
 
419
    assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
 
420
 
 
421
    assertRaises = failUnlessRaises
 
422
 
 
423
    assert_ = assertTrue = failUnless
 
424
 
 
425
    assertFalse = failIf
 
426
 
 
427
 
 
428
 
 
429
class TestSuite:
 
430
    """A test suite is a composite test consisting of a number of TestCases.
 
431
 
 
432
    For use, create an instance of TestSuite, then add test case instances.
 
433
    When all tests have been added, the suite can be passed to a test
 
434
    runner, such as TextTestRunner. It will run the individual test cases
 
435
    in the order in which they were added, aggregating the results. When
 
436
    subclassing, do not forget to call the base class constructor.
 
437
    """
 
438
    
 
439
    def __init__(self, tests=()):
 
440
        self._tests = []
 
441
        self.addTests(tests)
 
442
 
 
443
    def __repr__(self):
 
444
        return "<%s tests=%s>" % (_strclass(self.__class__), self._tests)
 
445
 
 
446
    __str__ = __repr__
 
447
 
 
448
    def __iter__(self):
 
449
        return iter(self._tests)
 
450
 
 
451
    def countTestCases(self):
 
452
        cases = 0
 
453
        for test in self._tests:
 
454
            cases += test.countTestCases()
 
455
        return cases
 
456
 
 
457
    def addTest(self, test):
 
458
        # sanity checks
 
459
        if not callable(test):
 
460
            raise TypeError("the test to add must be callable")
 
461
        if (isinstance(test, class_types) and
 
462
            issubclass(test, (TestCase, TestSuite))):
 
463
            raise TypeError("TestCases and TestSuites must be instantiated "
 
464
                            "before passing them to addTest()")
 
465
        self._tests.append(test)
 
466
 
 
467
    def addTests(self, tests):
 
468
        if isinstance(tests, basestring):
 
469
            raise TypeError("tests must be an iterable of tests, not a string")
 
470
        for test in tests:
 
471
            self.addTest(test)
 
472
 
 
473
    def run(self, result):
 
474
        for test in self._tests:
 
475
            if result.shouldStop:
 
476
                break
 
477
            test(result)
 
478
        return result
 
479
 
 
480
    def __call__(self, *args, **kwds):
 
481
        return self.run(*args, **kwds)
 
482
 
 
483
    def debug(self):
 
484
        """Run the tests without collecting errors in a TestResult"""
 
485
        for test in self._tests: test.debug()
 
486
 
 
487
 
 
488
class FunctionTestCase(TestCase):
 
489
    """A test case that wraps a test function.
 
490
 
 
491
    This is useful for slipping pre-existing test functions into the
 
492
    PyUnit framework. Optionally, set-up and tidy-up functions can be
 
493
    supplied. As with TestCase, the tidy-up ('tearDown') function will
 
494
    always be called if the set-up ('setUp') function ran successfully.
 
495
    """
 
496
 
 
497
    def __init__(self, testFunc, setUp=None, tearDown=None,
 
498
                 description=None):
 
499
        TestCase.__init__(self)
 
500
        self.__setUpFunc = setUp
 
501
        self.__tearDownFunc = tearDown
 
502
        self.__testFunc = testFunc
 
503
        self.__description = description
 
504
 
 
505
    def setUp(self):
 
506
        if self.__setUpFunc is not None:
 
507
            self.__setUpFunc()
 
508
 
 
509
    def tearDown(self):
 
510
        if self.__tearDownFunc is not None:
 
511
            self.__tearDownFunc()
 
512
 
 
513
    def runTest(self):
 
514
        self.__testFunc()
 
515
 
 
516
    def id(self):
 
517
        return self.__testFunc.__name__
 
518
 
 
519
    def __str__(self):
 
520
        return "%s (%s)" % (_strclass(self.__class__), self.__testFunc.__name__)
 
521
 
 
522
    def __repr__(self):
 
523
        return "<%s testFunc=%s>" % (_strclass(self.__class__), self.__testFunc)
 
524
 
 
525
    def shortDescription(self):
 
526
        if self.__description is not None: return self.__description
 
527
        doc = self.__testFunc.__doc__
 
528
        return doc and doc.split("\n")[0].strip() or None
 
529
 
 
530
##############################################################################
 
531
# Locating and loading tests
 
532
##############################################################################
 
533
 
 
534
def CmpToKey(mycmp):
 
535
    'Convert a cmp= function into a key= function'
 
536
    class K(object):
 
537
        def __init__(self, obj, *args):
 
538
            self.obj = obj
 
539
        def __lt__(self, other):
 
540
            return mycmp(self.obj, other.obj) == -1
 
541
    return K
 
542
 
 
543
def three_way_cmp(x, y):
 
544
    """Return -1 if x < y, 0 if x == y and 1 if x > y"""
 
545
    return (x > y) - (x < y)
 
546
 
 
547
class TestLoader:
 
548
    """This class is responsible for loading tests according to various
 
549
    criteria and returning them wrapped in a Test
 
550
    """
 
551
    testMethodPrefix = 'test'
 
552
    sortTestMethodsUsing = cmp
 
553
    suiteClass = TestSuite
 
554
 
 
555
    def loadTestsFromTestCase(self, testCaseClass):
 
556
        """Return a suite of all tests cases contained in testCaseClass"""
 
557
        if issubclass(testCaseClass, TestSuite):
 
558
            raise TypeError("Test cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?")
 
559
        testCaseNames = self.getTestCaseNames(testCaseClass)
 
560
        if not testCaseNames and hasattr(testCaseClass, 'runTest'):
 
561
            testCaseNames = ['runTest']
 
562
        return self.suiteClass([testCaseClass(n) for n in testCaseNames])
 
563
 
 
564
    def loadTestsFromModule(self, module):
 
565
        """Return a suite of all tests cases contained in the given module"""
 
566
        tests = []
 
567
        for name in dir(module):
 
568
            obj = getattr(module, name)
 
569
            if (isinstance(obj, class_types) and
 
570
                issubclass(obj, TestCase)):
 
571
                tests.append(self.loadTestsFromTestCase(obj))
 
572
        return self.suiteClass(tests)
 
573
 
 
574
    def loadTestsFromName(self, name, module=None):
 
575
        """Return a suite of all tests cases given a string specifier.
 
576
 
 
577
        The name may resolve either to a module, a test case class, a
 
578
        test method within a test case class, or a callable object which
 
579
        returns a TestCase or TestSuite instance.
 
580
 
 
581
        The method optionally resolves the names relative to a given module.
 
582
        """
 
583
        parts = name.split('.')
 
584
        if module is None:
 
585
            parts_copy = parts[:]
 
586
            while parts_copy:
 
587
                try:
 
588
                    module = __import__('.'.join(parts_copy))
 
589
                    break
 
590
                except ImportError:
 
591
                    del parts_copy[-1]
 
592
                    if not parts_copy: raise
 
593
            parts = parts[1:]
 
594
        obj = module
 
595
        for part in parts:
 
596
            parent, obj = obj, getattr(obj, part)
 
597
 
 
598
        if type(obj) == types.ModuleType:
 
599
            return self.loadTestsFromModule(obj)
 
600
        elif (isinstance(obj, class_types) and
 
601
              issubclass(obj, TestCase)):
 
602
            return self.loadTestsFromTestCase(obj)
 
603
        elif type(obj) == types.UnboundMethodType:
 
604
            return parent(obj.__name__)
 
605
        elif isinstance(obj, TestSuite):
 
606
            return obj
 
607
        elif callable(obj):
 
608
            test = obj()
 
609
            if not isinstance(test, (TestCase, TestSuite)):
 
610
                raise ValueError(
 
611
                      "calling %s returned %s, not a test" % (obj,test))
 
612
            return test
 
613
        else:
 
614
            raise ValueError( "don't know how to make test from: %s" % obj)
 
615
 
 
616
    def loadTestsFromNames(self, names, module=None):
 
617
        """Return a suite of all tests cases found using the given sequence
 
618
        of string specifiers. See 'loadTestsFromName()'.
 
619
        """
 
620
        suites = [self.loadTestsFromName(name, module) for name in names]
 
621
        return self.suiteClass(suites)
 
622
 
 
623
    def getTestCaseNames(self, testCaseClass):
 
624
        """Return a sorted sequence of method names found within testCaseClass
 
625
        """
 
626
        def isTestMethod(attrname, testCaseClass=testCaseClass, prefix=self.testMethodPrefix):
 
627
            return attrname.startswith(prefix) and callable(getattr(testCaseClass, attrname))
 
628
        testFnNames = list(filter(isTestMethod, dir(testCaseClass)))
 
629
        for baseclass in testCaseClass.__bases__:
 
630
            for testFnName in self.getTestCaseNames(baseclass):
 
631
                if testFnName not in testFnNames:  # handle overridden methods
 
632
                    testFnNames.append(testFnName)
 
633
        if self.sortTestMethodsUsing:
 
634
            #testFnNames.sort(key=CmpToKey(self.sortTestMethodsUsing))
 
635
            testFnNames = _sort_using_key(testFnNames, CmpToKey(self.sortTestMethodsUsing))
 
636
        return testFnNames
 
637
 
 
638
 
 
639
 
 
640
 
 
641
 
 
642
defaultTestLoader = TestLoader()
 
643
 
 
644
 
 
645
##############################################################################
 
646
# Patches for old functions: these functions should be considered obsolete
 
647
##############################################################################
 
648
 
 
649
def _makeLoader(prefix, sortUsing, suiteClass=None):
 
650
    loader = TestLoader()
 
651
    loader.sortTestMethodsUsing = sortUsing
 
652
    loader.testMethodPrefix = prefix
 
653
    if suiteClass: loader.suiteClass = suiteClass
 
654
    return loader
 
655
 
 
656
def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
 
657
    return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
 
658
 
 
659
def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
 
660
    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
 
661
 
 
662
def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
 
663
    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
 
664
 
 
665
 
 
666
##############################################################################
 
667
# Text UI
 
668
##############################################################################
 
669
 
 
670
class _WritelnDecorator:
 
671
    """Used to decorate file-like objects with a handy 'writeln' method"""
 
672
    def __init__(self,stream):
 
673
        self.stream = stream
 
674
 
 
675
    def __getattr__(self, attr):
 
676
        return getattr(self.stream,attr)
 
677
 
 
678
    def writeln(self, arg=None):
 
679
        if arg: self.write(arg)
 
680
        self.write('\n') # text-mode streams translate to \r\n if needed
 
681
 
 
682
 
 
683
class _TextTestResult(TestResult):
 
684
    """A test result class that can print formatted text results to a stream.
 
685
 
 
686
    Used by TextTestRunner.
 
687
    """
 
688
    separator1 = '=' * 70
 
689
    separator2 = '-' * 70
 
690
 
 
691
    def __init__(self, stream, descriptions, verbosity):
 
692
        TestResult.__init__(self)
 
693
        self.stream = stream
 
694
        self.showAll = verbosity > 1
 
695
        self.dots = verbosity == 1
 
696
        self.descriptions = descriptions
 
697
 
 
698
    def getDescription(self, test):
 
699
        if self.descriptions:
 
700
            return test.shortDescription() or str(test)
 
701
        else:
 
702
            return str(test)
 
703
 
 
704
    def startTest(self, test):
 
705
        TestResult.startTest(self, test)
 
706
        if self.showAll:
 
707
            self.stream.write(self.getDescription(test))
 
708
            self.stream.write(" ... ")
 
709
 
 
710
    def addSuccess(self, test):
 
711
        TestResult.addSuccess(self, test)
 
712
        if self.showAll:
 
713
            self.stream.writeln("ok")
 
714
        elif self.dots:
 
715
            self.stream.write('.')
 
716
 
 
717
    def addError(self, test, err):
 
718
        TestResult.addError(self, test, err)
 
719
        if self.showAll:
 
720
            self.stream.writeln("ERROR")
 
721
        elif self.dots:
 
722
            self.stream.write('E')
 
723
 
 
724
    def addFailure(self, test, err):
 
725
        TestResult.addFailure(self, test, err)
 
726
        if self.showAll:
 
727
            self.stream.writeln("FAIL")
 
728
        elif self.dots:
 
729
            self.stream.write('F')
 
730
 
 
731
    def printErrors(self):
 
732
        if self.dots or self.showAll:
 
733
            self.stream.writeln()
 
734
        self.printErrorList('ERROR', self.errors)
 
735
        self.printErrorList('FAIL', self.failures)
 
736
 
 
737
    def printErrorList(self, flavour, errors):
 
738
        for test, err in errors:
 
739
            self.stream.writeln(self.separator1)
 
740
            self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
 
741
            self.stream.writeln(self.separator2)
 
742
            self.stream.writeln("%s" % err)
 
743
 
 
744
 
 
745
class TextTestRunner:
 
746
    """A test runner class that displays results in textual form.
 
747
 
 
748
    It prints out the names of tests as they are run, errors as they
 
749
    occur, and a summary of the results at the end of the test run.
 
750
    """
 
751
    def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1):
 
752
        self.stream = _WritelnDecorator(stream)
 
753
        self.descriptions = descriptions
 
754
        self.verbosity = verbosity
 
755
 
 
756
    def _makeResult(self):
 
757
        return _TextTestResult(self.stream, self.descriptions, self.verbosity)
 
758
 
 
759
    def run(self, test):
 
760
        "Run the given test case or test suite."
 
761
        result = self._makeResult()
 
762
        startTime = time.time()
 
763
        test(result)
 
764
        stopTime = time.time()
 
765
        timeTaken = stopTime - startTime
 
766
        result.printErrors()
 
767
        self.stream.writeln(result.separator2)
 
768
        run = result.testsRun
 
769
        self.stream.writeln("Ran %d test%s in %.3fs" %
 
770
                            (run, run != 1 and "s" or "", timeTaken))
 
771
        self.stream.writeln()
 
772
        if not result.wasSuccessful():
 
773
            self.stream.write("FAILED (")
 
774
            failed, errored = len(result.failures), len(result.errors)
 
775
            if failed:
 
776
                self.stream.write("failures=%d" % failed)
 
777
            if errored:
 
778
                if failed: self.stream.write(", ")
 
779
                self.stream.write("errors=%d" % errored)
 
780
            self.stream.writeln(")")
 
781
        else:
 
782
            self.stream.writeln("OK")
 
783
        return result
 
784
 
 
785
 
 
786
 
 
787
##############################################################################
 
788
# Facilities for running tests from the command line
 
789
##############################################################################
 
790
 
 
791
class TestProgram:
 
792
    """A command-line program that runs a set of tests; this is primarily
 
793
       for making test modules conveniently executable.
 
794
    """
 
795
    USAGE = """\
 
796
Usage: %(progName)s [options] [test] [...]
 
797
 
 
798
Options:
 
799
  -h, --help       Show this message
 
800
  -v, --verbose    Verbose output
 
801
  -q, --quiet      Minimal output
 
802
 
 
803
Examples:
 
804
  %(progName)s                               - run default set of tests
 
805
  %(progName)s MyTestSuite                   - run suite 'MyTestSuite'
 
806
  %(progName)s MyTestCase.testSomething      - run MyTestCase.testSomething
 
807
  %(progName)s MyTestCase                    - run all 'test*' test methods
 
808
                                               in MyTestCase
 
809
"""
 
810
    def __init__(self, module='__main__', defaultTest=None,
 
811
                 argv=None, testRunner=None, testLoader=defaultTestLoader):
 
812
        if type(module) == type(''):
 
813
            self.module = __import__(module)
 
814
            for part in module.split('.')[1:]:
 
815
                self.module = getattr(self.module, part)
 
816
        else:
 
817
            self.module = module
 
818
        if argv is None:
 
819
            argv = sys.argv
 
820
        self.verbosity = 1
 
821
        self.defaultTest = defaultTest
 
822
        self.testRunner = testRunner
 
823
        self.testLoader = testLoader
 
824
        self.progName = os.path.basename(argv[0])
 
825
        self.parseArgs(argv)
 
826
        self.runTests()
 
827
 
 
828
    def usageExit(self, msg=None):
 
829
        if msg: print (msg)
 
830
        print (self.USAGE % self.__dict__)
 
831
        sys.exit(2)
 
832
 
 
833
    def parseArgs(self, argv):
 
834
        import getopt
 
835
        try:
 
836
            options, args = getopt.getopt(argv[1:], 'hHvq',
 
837
                                          ['help','verbose','quiet'])
 
838
            for opt, value in options:
 
839
                if opt in ('-h','-H','--help'):
 
840
                    self.usageExit()
 
841
                if opt in ('-q','--quiet'):
 
842
                    self.verbosity = 0
 
843
                if opt in ('-v','--verbose'):
 
844
                    self.verbosity = 2
 
845
            if len(args) == 0 and self.defaultTest is None:
 
846
                self.test = self.testLoader.loadTestsFromModule(self.module)
 
847
                return
 
848
            if len(args) > 0:
 
849
                self.testNames = args
 
850
            else:
 
851
                self.testNames = (self.defaultTest,)
 
852
            self.createTests()
 
853
        except getopt.error:
 
854
            msg = geterror()
 
855
            self.usageExit(msg)
 
856
 
 
857
    def createTests(self):
 
858
        self.test = self.testLoader.loadTestsFromNames(self.testNames,
 
859
                                                       self.module)
 
860
 
 
861
    def runTests(self):
 
862
        if self.testRunner is None:
 
863
            self.testRunner = TextTestRunner(verbosity=self.verbosity)
 
864
        result = self.testRunner.run(self.test)
 
865
        sys.exit(not result.wasSuccessful())
 
866
 
 
867
main = TestProgram
 
868
 
 
869
##############################################################################
 
870
# Executing this module from the command line
 
871
##############################################################################
 
872
 
 
873
if __name__ == "__main__":
 
874
    main(module=None)