root/galaxy-central/eggs/Cheetah-2.2.2-py2.6-macosx-10.6-universal-ucs2.egg/Cheetah/Tests/unittest_local_copy.py @ 3

リビジョン 3, 32.6 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1#!/usr/bin/env python
2""" This is a hacked version of PyUnit that extends its reporting capabilities
3with optional meta data on the test cases.  It also makes it possible to
4separate the standard and error output streams in TextTestRunner.
5
6It's a hack rather than a set of subclasses because a) Steve had used double
7underscore private attributes for some things I needed access to, and b) the
8changes affected so many classes that it was easier just to hack it.
9
10The changes are in the following places:
11TestCase:
12   - minor refactoring of  __init__ and __call__ internals
13   - added some attributes and methods for storing and retrieving meta data
14
15_TextTestResult
16   - refactored the stream handling
17   - incorporated all the output code from TextTestRunner
18   - made the output of FAIL and ERROR information more flexible and
19     incorporated the new meta data from TestCase
20   - added a flag called 'explain' to __init__ that controls whether the new '
21     explanation'   meta data from TestCase is printed along with tracebacks
22   
23TextTestRunner
24   - delegated all output to _TextTestResult
25   - added 'err' and 'explain' to the __init__ signature to match the changes
26     in _TextTestResult
27   
28TestProgram
29   - added -e and --explain as flags on the command line
30
31-- Tavis Rudd <tavis@redonions.net> (Sept 28th, 2001)
32
33- _TestTextResult.printErrorList(): print blank line after each traceback
34
35-- Mike Orr <mso@oz.net> (Nov 11, 2002)
36
37TestCase methods copied from unittest in Python 2.3:
38  - .assertAlmostEqual(first, second, places=7, msg=None): to N decimal places.
39  - .failIfAlmostEqual(first, second, places=7, msg=None)
40
41-- Mike Orr (Jan 5, 2004)
42
43
44Below is the original docstring for unittest.
45---------------------------------------------------------------------------
46Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's
47Smalltalk testing framework.
48
49This module contains the core framework classes that form the basis of
50specific test cases and suites (TestCase, TestSuite etc.), and also a
51text-based utility class for running the tests and reporting the results
52(TextTestRunner).
53
54Simple usage:
55
56    import unittest
57
58    class IntegerArithmenticTestCase(unittest.TestCase):
59        def testAdd(self):  ## test method names begin 'test*'
60            self.assertEquals((1 + 2), 3)
61            self.assertEquals(0 + 1, 1)
62        def testMultiply(self);
63            self.assertEquals((0 * 10), 0)
64            self.assertEquals((5 * 8), 40)
65
66    if __name__ == '__main__':
67        unittest.main()
68
69Further information is available in the bundled documentation, and from
70
71  http://pyunit.sourceforge.net/
72
73Copyright (c) 1999, 2000, 2001 Steve Purcell
74This module is free software, and you may redistribute it and/or modify
75it under the same terms as Python itself, so long as this copyright message
76and disclaimer are retained in their original form.
77
78IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
79SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
80THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
81DAMAGE.
82
83THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
84LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
85PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
86AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
87SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
88"""
89
90__author__ = "Steve Purcell"
91__email__ = "stephen_purcell at yahoo dot com"
92__revision__ = "$Revision: 1.11 $"[11:-2]
93
94
95##################################################
96## DEPENDENCIES ##
97
98import os
99import re
100import string
101import sys
102import time
103import traceback
104import types
105import pprint
106
107##################################################
108## CONSTANTS & GLOBALS
109
110try:
111    True,False
112except NameError:
113    True, False = (1==1),(1==0)
114
115##############################################################################
116# Test framework core
117##############################################################################
118
119
120class TestResult:
121    """Holder for test result information.
122
123    Test results are automatically managed by the TestCase and TestSuite
124    classes, and do not need to be explicitly manipulated by writers of tests.
125
126    Each instance holds the total number of tests run, and collections of
127    failures and errors that occurred among those test runs. The collections
128    contain tuples of (testcase, exceptioninfo), where exceptioninfo is a
129    tuple of values as returned by sys.exc_info().
130    """
131    def __init__(self):
132        self.failures = []
133        self.errors = []
134        self.testsRun = 0
135        self.shouldStop = 0
136
137    def startTest(self, test):
138        "Called when the given test is about to be run"
139        self.testsRun = self.testsRun + 1
140
141    def stopTest(self, test):
142        "Called when the given test has been run"
143        pass
144
145    def addError(self, test, err):
146        "Called when an error has occurred"
147        self.errors.append((test, err))
148
149    def addFailure(self, test, err):
150        "Called when a failure has occurred"
151        self.failures.append((test, err))
152
153    def addSuccess(self, test):
154        "Called when a test has completed successfully"
155        pass
156
157    def wasSuccessful(self):
158        "Tells whether or not this result was a success"
159        return len(self.failures) == len(self.errors) == 0
160
161    def stop(self):
162        "Indicates that the tests should be aborted"
163        self.shouldStop = 1
164
165    def __repr__(self):
166        return "<%s run=%i errors=%i failures=%i>" % \
167               (self.__class__, self.testsRun, len(self.errors),
168                len(self.failures))
169       
170class TestCase:
171    """A class whose instances are single test cases.
172
173    By default, the test code itself should be placed in a method named
174    'runTest'.
175
176    If the fixture may be used for many test cases, create as
177    many test methods as are needed. When instantiating such a TestCase
178    subclass, specify in the constructor arguments the name of the test method
179    that the instance is to execute.
180
181    Test authors should subclass TestCase for their own tests. Construction
182    and deconstruction of the test's environment ('fixture') can be
183    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
184
185    If it is necessary to override the __init__ method, the base class
186    __init__ method must always be called. It is important that subclasses
187    should not change the signature of their __init__ method, since instances
188    of the classes are instantiated automatically by parts of the framework
189    in order to be run.
190    """
191
192    # This attribute determines which exception will be raised when
193    # the instance's assertion methods fail; test methods raising this
194    # exception will be deemed to have 'failed' rather than 'errored'
195
196    failureException = AssertionError
197
198    # the name of the fixture.  Used for displaying meta data about the test
199    name = None
200   
201    def __init__(self, methodName='runTest'):
202        """Create an instance of the class that will use the named test
203        method when executed. Raises a ValueError if the instance does
204        not have a method with the specified name.
205        """
206        self._testMethodName = methodName
207        self._setupTestMethod()
208        self._setupMetaData()
209
210    def _setupTestMethod(self):
211        try:
212            self._testMethod = getattr(self, self._testMethodName)
213        except AttributeError:
214            raise ValueError, "no such test method in %s: %s" % \
215                  (self.__class__, self._testMethodName)
216       
217    ## meta data methods
218       
219    def _setupMetaData(self):
220        """Setup the default meta data for the test case:
221
222        - id: self.__class__.__name__ + testMethodName OR self.name + testMethodName
223        - description: 1st line of Class docstring + 1st line of method docstring
224        - explanation: rest of Class docstring + rest of method docstring
225       
226        """
227
228       
229        testDoc = self._testMethod.__doc__ or '\n'
230        testDocLines = testDoc.splitlines()
231       
232        testDescription = testDocLines[0].strip()
233        if len(testDocLines) > 1:
234            testExplanation = '\n'.join(
235                [ln.strip() for ln in testDocLines[1:]]
236                ).strip()
237        else:
238            testExplanation = ''
239           
240        fixtureDoc = self.__doc__ or '\n'
241        fixtureDocLines = fixtureDoc.splitlines()
242        fixtureDescription = fixtureDocLines[0].strip()
243        if len(fixtureDocLines) > 1:
244            fixtureExplanation = '\n'.join(
245                [ln.strip() for ln in fixtureDocLines[1:]]
246                ).strip()
247        else:
248            fixtureExplanation = ''
249       
250        if not self.name:
251            self.name = self.__class__
252        self._id = "%s.%s" % (self.name, self._testMethodName)
253       
254        if not fixtureDescription:
255            self._description = testDescription
256        else:
257            self._description = fixtureDescription + ', ' + testDescription
258
259        if not fixtureExplanation:
260            self._explanation = testExplanation
261        else:
262            self._explanation = ['Fixture Explanation:',
263                                 '--------------------',
264                                 fixtureExplanation,
265                                 '',
266                                 'Test Explanation:',
267                                 '-----------------',
268                                 testExplanation
269                                 ]
270            self._explanation = '\n'.join(self._explanation)
271
272    def id(self):
273        return self._id
274
275    def setId(self, id):
276        self._id = id
277
278    def describe(self):
279        """Returns a one-line description of the test, or None if no
280        description has been provided.
281
282        The default implementation of this method returns the first line of
283        the specified test method's docstring.
284        """
285        return self._description
286
287    shortDescription = describe
288   
289    def setDescription(self, descr):
290        self._description = descr
291   
292    def explain(self):
293        return self._explanation
294
295    def setExplanation(self, expln):
296        self._explanation = expln
297
298    ## core methods
299
300    def setUp(self):
301        "Hook method for setting up the test fixture before exercising it."
302        pass
303   
304    def run(self, result=None):
305        return self(result)
306       
307    def tearDown(self):
308        "Hook method for deconstructing the test fixture after testing it."
309        pass
310
311    def debug(self):
312        """Run the test without collecting errors in a TestResult"""
313        self.setUp()
314        self._testMethod()
315        self.tearDown()
316
317    ## internal methods
318
319    def defaultTestResult(self):
320        return TestResult()
321   
322    def __call__(self, result=None):
323        if result is None:
324            result = self.defaultTestResult()
325       
326        result.startTest(self)
327        try:
328            try:
329                self.setUp()
330            except:
331                result.addError(self, self.__exc_info())
332                return
333           
334            ok = 0
335            try:
336                self._testMethod()
337                ok = 1
338            except self.failureException, e:
339                result.addFailure(self, self.__exc_info())
340            except:
341                result.addError(self, self.__exc_info())
342            try:
343                self.tearDown()
344            except:
345                result.addError(self, self.__exc_info())
346                ok = 0
347            if ok:
348                result.addSuccess(self)
349        finally:
350            result.stopTest(self)
351           
352        return result
353       
354    def countTestCases(self):
355        return 1
356       
357    def __str__(self):
358        return "%s (%s)" % (self._testMethodName, self.__class__)
359
360    def __repr__(self):
361        return "<%s testMethod=%s>" % \
362               (self.__class__, self._testMethodName)
363
364    def __exc_info(self):
365        """Return a version of sys.exc_info() with the traceback frame
366           minimised; usually the top level of the traceback frame is not
367           needed.
368        """
369        exctype, excvalue, tb = sys.exc_info()
370        if sys.platform[:4] == 'java': ## tracebacks look different in Jython
371            return (exctype, excvalue, tb)
372        newtb = tb.tb_next
373        if newtb is None:
374            return (exctype, excvalue, tb)
375        return (exctype, excvalue, newtb)
376
377    ## methods for use by the test cases
378
379    def fail(self, msg=None):
380        """Fail immediately, with the given message."""
381        raise self.failureException, msg
382
383    def failIf(self, expr, msg=None):
384        "Fail the test if the expression is true."
385        if expr: raise self.failureException, msg
386
387    def failUnless(self, expr, msg=None):
388        """Fail the test unless the expression is true."""
389        if not expr: raise self.failureException, msg
390
391    def failUnlessRaises(self, excClass, callableObj, *args, **kwargs):
392        """Fail unless an exception of class excClass is thrown
393           by callableObj when invoked with arguments args and keyword
394           arguments kwargs. If a different type of exception is
395           thrown, it will not be caught, and the test case will be
396           deemed to have suffered an error, exactly as for an
397           unexpected exception.
398        """
399        try:
400            apply(callableObj, args, kwargs)
401        except excClass:
402            return
403        else:
404            if hasattr(excClass,'__name__'): excName = excClass.__name__
405            else: excName = str(excClass)
406            raise self.failureException, excName
407
408    def failUnlessEqual(self, first, second, msg=None):
409        """Fail if the two objects are unequal as determined by the '!='
410           operator.
411        """
412        if first != second:
413            raise self.failureException, (msg or '%s != %s' % (first, second))
414
415    def failIfEqual(self, first, second, msg=None):
416        """Fail if the two objects are equal as determined by the '=='
417           operator.
418        """
419        if first == second:
420            raise self.failureException, (msg or '%s == %s' % (first, second))
421
422    def failUnlessAlmostEqual(self, first, second, places=7, msg=None):
423        """Fail if the two objects are unequal as determined by their
424           difference rounded to the given number of decimal places
425           (default 7) and comparing to zero.
426
427           Note that decimal places (from zero) is usually not the same
428           as significant digits (measured from the most signficant digit).
429        """
430        if round(second-first, places) != 0:
431            raise self.failureException, \
432                  (msg or '%s != %s within %s places' % (`first`, `second`, `places` ))
433
434    def failIfAlmostEqual(self, first, second, places=7, msg=None):
435        """Fail if the two objects are equal as determined by their
436           difference rounded to the given number of decimal places
437           (default 7) and comparing to zero.
438
439           Note that decimal places (from zero) is usually not the same
440           as significant digits (measured from the most signficant digit).
441        """
442        if round(second-first, places) == 0:
443            raise self.failureException, \
444                  (msg or '%s == %s within %s places' % (`first`, `second`, `places`))
445
446    ## aliases
447
448    assertEqual = assertEquals = failUnlessEqual
449
450    assertNotEqual = assertNotEquals = failIfEqual
451
452    assertAlmostEqual = assertAlmostEquals = failUnlessAlmostEqual
453
454    assertNotAlmostEqual = assertNotAlmostEquals = failIfAlmostEqual
455
456    assertRaises = failUnlessRaises
457
458    assert_ = failUnless
459
460
461class FunctionTestCase(TestCase):
462    """A test case that wraps a test function.
463
464    This is useful for slipping pre-existing test functions into the
465    PyUnit framework. Optionally, set-up and tidy-up functions can be
466    supplied. As with TestCase, the tidy-up ('tearDown') function will
467    always be called if the set-up ('setUp') function ran successfully.
468    """
469
470    def __init__(self, testFunc, setUp=None, tearDown=None,
471                 description=None):
472        TestCase.__init__(self)
473        self.__setUpFunc = setUp
474        self.__tearDownFunc = tearDown
475        self.__testFunc = testFunc
476        self.__description = description
477
478    def setUp(self):
479        if self.__setUpFunc is not None:
480            self.__setUpFunc()
481
482    def tearDown(self):
483        if self.__tearDownFunc is not None:
484            self.__tearDownFunc()
485
486    def runTest(self):
487        self.__testFunc()
488
489    def id(self):
490        return self.__testFunc.__name__
491
492    def __str__(self):
493        return "%s (%s)" % (self.__class__, self.__testFunc.__name__)
494
495    def __repr__(self):
496        return "<%s testFunc=%s>" % (self.__class__, self.__testFunc)
497
498
499    def describe(self):
500        if self.__description is not None: return self.__description
501        doc = self.__testFunc.__doc__
502        return doc and string.strip(string.split(doc, "\n")[0]) or None
503   
504    ## aliases
505    shortDescription = describe
506
507class TestSuite:
508    """A test suite is a composite test consisting of a number of TestCases.
509
510    For use, create an instance of TestSuite, then add test case instances.
511    When all tests have been added, the suite can be passed to a test
512    runner, such as TextTestRunner. It will run the individual test cases
513    in the order in which they were added, aggregating the results. When
514    subclassing, do not forget to call the base class constructor.
515    """
516    def __init__(self, tests=(), suiteName=None):
517        self._tests = []
518        self._testMap = {}
519        self.suiteName = suiteName
520        self.addTests(tests)
521
522    def __repr__(self):
523        return "<%s tests=%s>" % (self.__class__, pprint.pformat(self._tests))
524
525    __str__ = __repr__
526
527    def countTestCases(self):
528        cases = 0
529        for test in self._tests:
530            cases = cases + test.countTestCases()
531        return cases
532
533    def addTest(self, test):
534        self._tests.append(test)
535        if isinstance(test, TestSuite) and test.suiteName:
536            name = test.suiteName
537        elif isinstance(test, TestCase):
538            #print test, test._testMethodName
539            name = test._testMethodName
540        else:
541            name = test.__class__.__name__
542        self._testMap[name] = test
543       
544    def addTests(self, tests):
545        for test in tests:
546            self.addTest(test)
547
548    def getTestForName(self, name):
549        return self._testMap[name]
550
551    def run(self, result):
552        return self(result)
553
554    def __call__(self, result):
555        for test in self._tests:
556            if result.shouldStop:
557                break
558            test(result)
559        return result
560
561    def debug(self):
562        """Run the tests without collecting errors in a TestResult"""
563        for test in self._tests: test.debug()
564
565
566##############################################################################
567# Text UI
568##############################################################################
569
570class StreamWrapper:
571    def __init__(self, out=sys.stdout, err=sys.stderr):
572        self._streamOut = out
573        self._streamErr = err
574
575    def write(self, txt):
576        self._streamOut.write(txt)
577        self._streamOut.flush()
578   
579    def writeln(self, *lines):
580        for line in lines:
581            self.write(line + '\n')
582        if not lines:
583            self.write('\n')
584
585    def writeErr(self, txt):
586        self._streamErr.write(txt)
587   
588    def writelnErr(self, *lines):
589        for line in lines:
590            self.writeErr(line + '\n')
591        if not lines:
592            self.writeErr('\n')
593
594
595class _TextTestResult(TestResult, StreamWrapper):
596    _separatorWidth = 70
597    _sep1 = '='
598    _sep2 = '-'
599    _errorSep1 = '*'
600    _errorSep2 = '-'
601    _errorSep3 = ''
602   
603    def __init__(self,
604                 stream=sys.stdout,
605                 errStream=sys.stderr,
606                 verbosity=1,
607                 explain=False):
608       
609        TestResult.__init__(self)
610        StreamWrapper.__init__(self, out=stream, err=errStream)       
611
612        self._verbosity = verbosity
613        self._showAll = verbosity > 1
614        self._dots = (verbosity == 1)
615        self._explain = explain
616
617    ## startup and shutdown methods
618       
619    def beginTests(self):
620        self._startTime = time.time()
621
622    def endTests(self):
623        self._stopTime = time.time()
624        self._timeTaken = float(self._stopTime - self._startTime)
625
626    def stop(self):
627        self.shouldStop = 1
628       
629    ## methods called for each test
630       
631    def startTest(self, test):
632        TestResult.startTest(self, test)
633        if self._showAll:
634            self.write("%s (%s)" %( test.id(), test.describe() ) )
635            self.write(" ... ")
636
637    def addSuccess(self, test):
638        TestResult.addSuccess(self, test)
639        if self._showAll:
640            self.writeln("ok")
641        elif self._dots:
642            self.write('.')
643
644    def addError(self, test, err):
645        TestResult.addError(self, test, err)
646        if self._showAll:
647            self.writeln("ERROR")
648        elif self._dots:
649            self.write('E')
650        if err[0] is KeyboardInterrupt:
651            self.stop()
652
653    def addFailure(self, test, err):
654        TestResult.addFailure(self, test, err)
655        if self._showAll:
656            self.writeln("FAIL")
657        elif self._dots:
658            self.write('F')
659
660    ## display methods
661
662    def summarize(self):
663        self.printErrors()
664        self.writeSep2()
665        run = self.testsRun
666        self.writeln("Ran %d test%s in %.3fs" %
667                            (run, run == 1 and "" or "s", self._timeTaken))
668        self.writeln()
669        if not self.wasSuccessful():
670            self.writeErr("FAILED (")
671            failed, errored = map(len, (self.failures, self.errors))
672            if failed:
673                self.writeErr("failures=%d" % failed)
674            if errored:
675                if failed: self.writeErr(", ")
676                self.writeErr("errors=%d" % errored)
677            self.writelnErr(")")
678        else:
679            self.writelnErr("OK")
680
681    def writeSep1(self):
682        self.writeln(self._sep1 * self._separatorWidth)
683
684    def writeSep2(self):
685        self.writeln(self._sep2 * self._separatorWidth)
686
687    def writeErrSep1(self):
688        self.writeln(self._errorSep1 * self._separatorWidth)
689
690    def writeErrSep2(self):
691        self.writeln(self._errorSep2 * self._separatorWidth)
692
693    def printErrors(self):
694        if self._dots or self._showAll:
695            self.writeln()
696        self.printErrorList('ERROR', self.errors)
697        self.printErrorList('FAIL', self.failures)
698
699    def printErrorList(self, flavour, errors):
700        for test, err in errors:
701            self.writeErrSep1()
702            self.writelnErr("%s %s (%s)" % (flavour, test.id(), test.describe() ))
703            if self._explain:
704                expln = test.explain()
705                if expln:
706                    self.writeErrSep2()
707                    self.writeErr( expln )
708                    self.writelnErr()
709
710            self.writeErrSep2()
711            for line in apply(traceback.format_exception, err):
712                for l in line.split("\n")[:-1]:
713                    self.writelnErr(l)
714            self.writelnErr("")
715
716class TextTestRunner:
717    def __init__(self,
718                 stream=sys.stdout,
719                 errStream=sys.stderr,
720                 verbosity=1,
721                 explain=False):
722
723        self._out = stream
724        self._err = errStream
725        self._verbosity = verbosity
726        self._explain = explain
727       
728    ## main methods
729
730    def run(self, test):
731        result = self._makeResult()
732        result.beginTests()
733        test( result )
734        result.endTests()       
735        result.summarize()
736       
737        return result
738   
739    ## internal methods
740
741    def _makeResult(self):
742        return _TextTestResult(stream=self._out,
743                               errStream=self._err,
744                               verbosity=self._verbosity,
745                               explain=self._explain,
746                               )
747
748##############################################################################
749# Locating and loading tests
750##############################################################################
751
752class TestLoader:
753    """This class is responsible for loading tests according to various
754    criteria and returning them wrapped in a Test
755    """
756    testMethodPrefix = 'test'
757    sortTestMethodsUsing = cmp
758    suiteClass = TestSuite
759
760    def loadTestsFromTestCase(self, testCaseClass):
761        """Return a suite of all tests cases contained in testCaseClass"""
762        return self.suiteClass(tests=map(testCaseClass,
763                                         self.getTestCaseNames(testCaseClass)),
764                               suiteName=testCaseClass.__name__)
765
766    def loadTestsFromModule(self, module):
767        """Return a suite of all tests cases contained in the given module"""
768        tests = []
769        for name in dir(module):
770            obj = getattr(module, name)
771            if type(obj) == types.ClassType and issubclass(obj, TestCase):
772                tests.append(self.loadTestsFromTestCase(obj))
773        return self.suiteClass(tests)
774
775    def loadTestsFromName(self, name, module=None):
776        """Return a suite of all tests cases given a string specifier.
777
778        The name may resolve either to a module, a test case class, a
779        test method within a test case class, or a callable object which
780        returns a TestCase or TestSuite instance.
781
782        The method optionally resolves the names relative to a given module.
783        """
784        parts = string.split(name, '.')
785        if module is None:
786            if not parts:
787                raise ValueError, "incomplete test name: %s" % name
788            else:
789                parts_copy = parts[:]
790                while parts_copy:
791                    try:
792                        module = __import__(string.join(parts_copy,'.'))
793                        break
794                    except ImportError:
795                        del parts_copy[-1]
796                        if not parts_copy: raise
797                parts = parts[1:]
798        obj = module
799        for part in parts:
800            if isinstance(obj, TestSuite):
801                obj = obj.getTestForName(part)
802            else:
803                obj = getattr(obj, part)
804
805        if type(obj) == types.ModuleType:
806            return self.loadTestsFromModule(obj)
807        elif type(obj) == types.ClassType and issubclass(obj, TestCase):
808            return self.loadTestsFromTestCase(obj)
809        elif type(obj) == types.UnboundMethodType:
810            return obj.im_class(obj.__name__)
811        elif isinstance(obj, TestSuite):
812            return obj
813        elif isinstance(obj, TestCase):
814            return obj
815        elif callable(obj):
816            test = obj()
817            if not isinstance(test, TestCase) and \
818               not isinstance(test, TestSuite):
819                raise ValueError, \
820                      "calling %s returned %s, not a test" %(obj,test)
821            return test
822        else:
823            raise ValueError, "don't know how to make test from: %s" % obj
824
825    def loadTestsFromNames(self, names, module=None):
826        """Return a suite of all tests cases found using the given sequence
827        of string specifiers. See 'loadTestsFromName()'.
828        """
829        suites = []
830        for name in names:
831            suites.append(self.loadTestsFromName(name, module))
832        return self.suiteClass(suites)
833
834    def getTestCaseNames(self, testCaseClass):
835        """Return a sorted sequence of method names found within testCaseClass.
836        """
837        testFnNames = [fn for fn in dir(testCaseClass) if fn.startswith(self.testMethodPrefix)]
838        if hasattr(testCaseClass, 'runTest'):
839            testFnNames.append('runTest')
840        for baseclass in testCaseClass.__bases__:
841            for testFnName in self.getTestCaseNames(baseclass):
842                if testFnName not in testFnNames:  # handle overridden methods
843                    testFnNames.append(testFnName)
844        if self.sortTestMethodsUsing:
845            testFnNames.sort(self.sortTestMethodsUsing)
846        return testFnNames
847
848
849
850defaultTestLoader = TestLoader()
851
852
853##############################################################################
854# Patches for old functions: these functions should be considered obsolete
855##############################################################################
856
857def _makeLoader(prefix, sortUsing, suiteClass=None):
858    loader = TestLoader()
859    loader.sortTestMethodsUsing = sortUsing
860    loader.testMethodPrefix = prefix
861    if suiteClass: loader.suiteClass = suiteClass
862    return loader
863
864def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
865    return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass)
866
867def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
868    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass)
869
870def findTestCases(module, prefix='test', sortUsing=cmp, suiteClass=TestSuite):
871    return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module)
872
873##############################################################################
874# Facilities for running tests from the command line
875##############################################################################
876
877class TestProgram:
878    """A command-line program that runs a set of tests; this is primarily
879       for making test modules conveniently executable.
880    """
881    USAGE = """\
882Usage: %(progName)s [options] [test] [...]
883
884Options:
885  -h, --help       Show this message
886  -v, --verbose    Verbose output
887  -q, --quiet      Minimal output
888  -e, --expain     Output extra test details if there is a failure or error
889 
890Examples:
891  %(progName)s                               - run default set of tests
892  %(progName)s MyTestSuite                   - run suite 'MyTestSuite'
893  %(progName)s MyTestSuite.MyTestCase        - run suite 'MyTestSuite'
894  %(progName)s MyTestCase.testSomething      - run MyTestCase.testSomething
895  %(progName)s MyTestCase                    - run all 'test*' test methods
896                                               in MyTestCase
897"""
898    def __init__(self, module='__main__', defaultTest=None,
899                 argv=None, testRunner=None, testLoader=defaultTestLoader,
900                 testSuite=None):
901        if type(module) == type(''):
902            self.module = __import__(module)
903            for part in string.split(module,'.')[1:]:
904                self.module = getattr(self.module, part)
905        else:
906            self.module = module
907        if argv is None:
908            argv = sys.argv
909        self.test = testSuite
910        self.verbosity = 1
911        self.explain = 0
912        self.defaultTest = defaultTest
913        self.testRunner = testRunner
914        self.testLoader = testLoader
915        self.progName = os.path.basename(argv[0])
916        self.parseArgs(argv)
917        self.runTests()
918
919    def usageExit(self, msg=None):
920        if msg: print msg
921        print self.USAGE % self.__dict__
922        sys.exit(2)
923
924    def parseArgs(self, argv):
925        import getopt
926        try:
927            options, args = getopt.getopt(argv[1:], 'hHvqer',
928                                  ['help','verbose','quiet','explain', 'raise'])
929            for opt, value in options:
930                if opt in ('-h','-H','--help'):
931                    self.usageExit()
932                if opt in ('-q','--quiet'):
933                    self.verbosity = 0
934                if opt in ('-v','--verbose'):
935                    self.verbosity = 2
936                if opt in ('-e','--explain'):
937                    self.explain = True
938            if len(args) == 0 and self.defaultTest is None and self.test is None:
939                self.test = self.testLoader.loadTestsFromModule(self.module)
940                return
941            if len(args) > 0:
942                self.testNames = args
943            else:
944                self.testNames = (self.defaultTest,)
945            self.createTests()
946        except getopt.error, msg:
947            self.usageExit(msg)
948
949    def createTests(self):
950        if self.test == None:
951            self.test = self.testLoader.loadTestsFromNames(self.testNames,
952                                                           self.module)
953
954    def runTests(self):
955        if self.testRunner is None:
956            self.testRunner = TextTestRunner(verbosity=self.verbosity,
957                                             explain=self.explain)
958        result = self.testRunner.run(self.test)
959        self._cleanupAfterRunningTests()
960        sys.exit(not result.wasSuccessful())
961
962    def _cleanupAfterRunningTests(self):
963        """A hook method that is called immediately prior to calling
964        sys.exit(not result.wasSuccessful()) in self.runTests().
965        """
966        pass
967
968main = TestProgram
969
970
971##############################################################################
972# Executing this module from the command line
973##############################################################################
974
975if __name__ == "__main__":
976    main(module=None)
977
978# vim: shiftwidth=4 tabstop=4 expandtab
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。