Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: third_party/twisted_8_1/twisted/trial/runner.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.trial.test.test_runner -*-
2
3 #
4 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
5 # See LICENSE for details.
6
7 """
8 A miscellany of code used to run Trial tests.
9
10 Maintainer: Jonathan Lange <jml@twistedmatrix.com>
11 """
12
13
14 import pdb, shutil
15 import os, types, warnings, sys, inspect, imp
16 import random, doctest, time
17
18 from twisted.python import reflect, log, failure, modules
19 from twisted.python.util import dsu
20 from twisted.python.compat import set
21
22 from twisted.internet import defer, interfaces
23 from twisted.trial import util, unittest
24 from twisted.trial.itrial import ITestCase
25 from twisted.trial.reporter import UncleanWarningsReporterWrapper
26
27 # These are imported so that they remain in the public API for t.trial.runner
28 from twisted.trial.unittest import suiteVisit, TestSuite
29
30 from zope.interface import implements
31
32 pyunit = __import__('unittest')
33
34
35 def isPackage(module):
36 """Given an object return True if the object looks like a package"""
37 if not isinstance(module, types.ModuleType):
38 return False
39 basename = os.path.splitext(os.path.basename(module.__file__))[0]
40 return basename == '__init__'
41
42
43 def isPackageDirectory(dirname):
44 """Is the directory at path 'dirname' a Python package directory?
45 Returns the name of the __init__ file (it may have a weird extension)
46 if dirname is a package directory. Otherwise, returns False"""
47 for ext in zip(*imp.get_suffixes())[0]:
48 initFile = '__init__' + ext
49 if os.path.exists(os.path.join(dirname, initFile)):
50 return initFile
51 return False
52
53
54 def samefile(filename1, filename2):
55 """
56 A hacky implementation of C{os.path.samefile}. Used by L{filenameToModule}
57 when the platform doesn't provide C{os.path.samefile}. Do not use this.
58 """
59 return os.path.abspath(filename1) == os.path.abspath(filename2)
60
61 def filenameToModule(fn):
62 """
63 Given a filename, do whatever possible to return a module object matching
64 that file.
65
66 If the file in question is a module in Python path, properly import and
67 return that module. Otherwise, load the source manually.
68
69 @param fn: A filename.
70 @return: A module object.
71 @raise ValueError: If C{fn} does not exist.
72 """
73 if not os.path.exists(fn):
74 raise ValueError("%r doesn't exist" % (fn,))
75 try:
76 ret = reflect.namedAny(reflect.filenameToModuleName(fn))
77 except (ValueError, AttributeError):
78 # Couldn't find module. The file 'fn' is not in PYTHONPATH
79 return _importFromFile(fn)
80 # ensure that the loaded module matches the file
81 retFile = os.path.splitext(ret.__file__)[0] + '.py'
82 # not all platforms (e.g. win32) have os.path.samefile
83 same = getattr(os.path, 'samefile', samefile)
84 if os.path.isfile(fn) and not same(fn, retFile):
85 del sys.modules[ret.__name__]
86 ret = _importFromFile(fn)
87 return ret
88
89
90 def _importFromFile(fn, moduleName=None):
91 fn = _resolveDirectory(fn)
92 if not moduleName:
93 moduleName = os.path.splitext(os.path.split(fn)[-1])[0]
94 if moduleName in sys.modules:
95 return sys.modules[moduleName]
96 fd = open(fn, 'r')
97 try:
98 module = imp.load_source(moduleName, fn, fd)
99 finally:
100 fd.close()
101 return module
102
103
104 def _resolveDirectory(fn):
105 if os.path.isdir(fn):
106 initFile = isPackageDirectory(fn)
107 if initFile:
108 fn = os.path.join(fn, initFile)
109 else:
110 raise ValueError('%r is not a package directory' % (fn,))
111 return fn
112
113
114
115 class DestructiveTestSuite(TestSuite):
116 """
117 A test suite which remove the tests once run, to minimize memory usage.
118 """
119
120 def run(self, result):
121 """
122 Almost the same as L{TestSuite.run}, but with C{self._tests} being
123 empty at the end.
124 """
125 while self._tests:
126 if result.shouldStop:
127 break
128 test = self._tests.pop(0)
129 test(result)
130 return result
131
132
133
134 # When an error occurs outside of any test, the user will see this string
135 # in place of a test's name.
136 NOT_IN_TEST = "<not in test>"
137
138
139
140 class LoggedSuite(TestSuite):
141 """
142 Any errors logged in this suite will be reported to the L{TestResult}
143 object.
144 """
145
146 def run(self, result):
147 """
148 Run the suite, storing all errors in C{result}. If an error is logged
149 while no tests are running, then it will be added as an error to
150 C{result}.
151
152 @param result: A L{TestResult} object.
153 """
154 observer = unittest._logObserver
155 observer._add()
156 super(LoggedSuite, self).run(result)
157 observer._remove()
158 for error in observer.getErrors():
159 result.addError(TestHolder(NOT_IN_TEST), error)
160 observer.flushErrors()
161
162
163
164 class DocTestSuite(TestSuite):
165 """
166 DEPRECATED in Twisted 8.0.
167
168 Behaves like doctest.DocTestSuite, but decorates individual TestCases so
169 they support visit and so that id() behaviour is meaningful and consistent
170 between Python versions.
171 """
172
173 def __init__(self, testModule):
174 warnings.warn("DocTestSuite is deprecated in Twisted 8.0.",
175 category=DeprecationWarning, stacklevel=3)
176 TestSuite.__init__(self)
177 suite = doctest.DocTestSuite(testModule)
178 for test in suite._tests: #yay encapsulation
179 self.addTest(ITestCase(test))
180
181
182
183 class PyUnitTestCase(object):
184 """
185 DEPRECATED in Twisted 8.0.
186
187 This class decorates the pyunit.TestCase class, mainly to work around the
188 differences between unittest in Python 2.3, 2.4, and 2.5. These
189 differences are::
190
191 - The way doctest unittests describe themselves
192 - Where the implementation of TestCase.run is (used to be in __call__)
193 - Where the test method name is kept (mangled-private or non-mangled
194 private variable)
195
196 It also implements visit, which we like.
197 """
198
199 def __init__(self, test):
200 warnings.warn("Deprecated in Twisted 8.0.",
201 category=DeprecationWarning)
202 self._test = test
203 test.id = self.id
204
205 def id(self):
206 cls = self._test.__class__
207 tmn = getattr(self._test, '_TestCase__testMethodName', None)
208 if tmn is None:
209 # python2.5's 'unittest' module is more sensible; but different.
210 tmn = self._test._testMethodName
211 return (cls.__module__ + '.' + cls.__name__ + '.' +
212 tmn)
213
214 def __repr__(self):
215 return 'PyUnitTestCase<%r>'%(self.id(),)
216
217 def __call__(self, results):
218 return self._test(results)
219
220
221 def visit(self, visitor):
222 """
223 Call the given visitor with the original, standard library, test case
224 that C{self} wraps. See L{unittest.TestCase.visit}.
225
226 Deprecated in Twisted 8.0.
227 """
228 warnings.warn("Test visitors deprecated in Twisted 8.0",
229 category=DeprecationWarning)
230 visitor(self._test)
231
232
233 def __getattr__(self, name):
234 return getattr(self._test, name)
235
236
237
238 class DocTestCase(PyUnitTestCase):
239 """
240 DEPRECATED in Twisted 8.0.
241 """
242
243 def id(self):
244 """
245 In Python 2.4, doctests have correct id() behaviour. In Python 2.3,
246 id() returns 'runit'.
247
248 Here we override id() so that at least it will always contain the
249 fully qualified Python name of the doctest.
250 """
251 return self._test.shortDescription()
252
253
254 class TrialSuite(TestSuite):
255 """
256 Suite to wrap around every single test in a C{trial} run. Used internally
257 by Trial to set up things necessary for Trial tests to work, regardless of
258 what context they are run in.
259 """
260
261 def __init__(self, tests=()):
262 suite = LoggedSuite(tests)
263 super(TrialSuite, self).__init__([suite])
264
265
266 def _bail(self):
267 from twisted.internet import reactor
268 d = defer.Deferred()
269 reactor.addSystemEventTrigger('after', 'shutdown',
270 lambda: d.callback(None))
271 reactor.fireSystemEvent('shutdown') # radix's suggestion
272 treactor = interfaces.IReactorThreads(reactor, None)
273 if treactor is not None:
274 treactor.suggestThreadPoolSize(0)
275 # As long as TestCase does crap stuff with the reactor we need to
276 # manually shutdown the reactor here, and that requires util.wait
277 # :(
278 # so that the shutdown event completes
279 unittest.TestCase('mktemp')._wait(d)
280
281 def run(self, result):
282 try:
283 TestSuite.run(self, result)
284 finally:
285 self._bail()
286
287
288 def name(thing):
289 """
290 @param thing: an object from modules (instance of PythonModule,
291 PythonAttribute), a TestCase subclass, or an instance of a TestCase.
292 """
293 if isTestCase(thing):
294 # TestCase subclass
295 theName = reflect.qual(thing)
296 else:
297 # thing from trial, or thing from modules.
298 # this monstrosity exists so that modules' objects do not have to
299 # implement id(). -jml
300 try:
301 theName = thing.id()
302 except AttributeError:
303 theName = thing.name
304 return theName
305
306
307 def isTestCase(obj):
308 """
309 Returns C{True} if C{obj} is a class that contains test cases, C{False}
310 otherwise. Used to find all the tests in a module.
311 """
312 try:
313 return issubclass(obj, pyunit.TestCase)
314 except TypeError:
315 return False
316
317
318
319 class TestHolder(object):
320 """
321 Placeholder for a L{TestCase} inside a reporter. As far as a L{TestResult}
322 is concerned, this looks exactly like a unit test.
323 """
324
325 implements(ITestCase)
326
327 def __init__(self, description):
328 """
329 @param description: A string to be displayed L{TestResult}.
330 """
331 self.description = description
332
333
334 def id(self):
335 return self.description
336
337
338 def shortDescription(self):
339 return self.description
340
341
342
343 class ErrorHolder(TestHolder):
344 """
345 Used to insert arbitrary errors into a test suite run. Provides enough
346 methods to look like a C{TestCase}, however, when it is run, it simply adds
347 an error to the C{TestResult}. The most common use-case is for when a
348 module fails to import.
349 """
350
351 def __init__(self, description, error):
352 """
353 @param description: A string used by C{TestResult}s to identify this
354 error. Generally, this is the name of a module that failed to import.
355
356 @param error: The error to be added to the result. Can be an exc_info
357 tuple or a L{twisted.python.failure.Failure}.
358 """
359 super(ErrorHolder, self).__init__(description)
360 self.error = error
361
362
363 def __repr__(self):
364 return "<ErrorHolder description=%r error=%r>" % (self.description,
365 self.error)
366
367
368 def run(self, result):
369 result.addError(self, self.error)
370
371
372 def __call__(self, result):
373 return self.run(result)
374
375
376 def countTestCases(self):
377 return 0
378
379
380 def visit(self, visitor):
381 """
382 See L{unittest.TestCase.visit}.
383 """
384 visitor(self)
385
386
387
388 class TestLoader(object):
389 """
390 I find tests inside function, modules, files -- whatever -- then return
391 them wrapped inside a Test (either a L{TestSuite} or a L{TestCase}).
392
393 @ivar methodPrefix: A string prefix. C{TestLoader} will assume that all the
394 methods in a class that begin with C{methodPrefix} are test cases.
395
396 @ivar modulePrefix: A string prefix. Every module in a package that begins
397 with C{modulePrefix} is considered a module full of tests.
398
399 @ivar forceGarbageCollection: A flag applied to each C{TestCase} loaded.
400 See L{unittest.TestCase} for more information.
401
402 @ivar sorter: A key function used to sort C{TestCase}s, test classes,
403 modules and packages.
404
405 @ivar suiteFactory: A callable which is passed a list of tests (which
406 themselves may be suites of tests). Must return a test suite.
407 """
408
409 methodPrefix = 'test'
410 modulePrefix = 'test_'
411
412 def __init__(self):
413 self.suiteFactory = TestSuite
414 self.sorter = name
415 self._importErrors = []
416
417 def sort(self, xs):
418 """
419 Sort the given things using L{sorter}.
420
421 @param xs: A list of test cases, class or modules.
422 """
423 return dsu(xs, self.sorter)
424
425 def findTestClasses(self, module):
426 """Given a module, return all Trial test classes"""
427 classes = []
428 for name, val in inspect.getmembers(module):
429 if isTestCase(val):
430 classes.append(val)
431 return self.sort(classes)
432
433 def findByName(self, name):
434 """
435 Return a Python object given a string describing it.
436
437 @param name: a string which may be either a filename or a
438 fully-qualified Python name.
439
440 @return: If C{name} is a filename, return the module. If C{name} is a
441 fully-qualified Python name, return the object it refers to.
442 """
443 if os.path.exists(name):
444 return filenameToModule(name)
445 return reflect.namedAny(name)
446
447 def loadModule(self, module):
448 """
449 Return a test suite with all the tests from a module.
450
451 Included are TestCase subclasses and doctests listed in the module's
452 __doctests__ module. If that's not good for you, put a function named
453 either C{testSuite} or C{test_suite} in your module that returns a
454 TestSuite, and I'll use the results of that instead.
455
456 If C{testSuite} and C{test_suite} are both present, then I'll use
457 C{testSuite}.
458 """
459 ## XXX - should I add an optional parameter to disable the check for
460 ## a custom suite.
461 ## OR, should I add another method
462 if not isinstance(module, types.ModuleType):
463 raise TypeError("%r is not a module" % (module,))
464 if hasattr(module, 'testSuite'):
465 return module.testSuite()
466 elif hasattr(module, 'test_suite'):
467 return module.test_suite()
468 suite = self.suiteFactory()
469 for testClass in self.findTestClasses(module):
470 suite.addTest(self.loadClass(testClass))
471 if not hasattr(module, '__doctests__'):
472 return suite
473 docSuite = self.suiteFactory()
474 for doctest in module.__doctests__:
475 docSuite.addTest(self.loadDoctests(doctest))
476 return self.suiteFactory([suite, docSuite])
477 loadTestsFromModule = loadModule
478
479 def loadClass(self, klass):
480 """
481 Given a class which contains test cases, return a sorted list of
482 C{TestCase} instances.
483 """
484 if not (isinstance(klass, type) or isinstance(klass, types.ClassType)):
485 raise TypeError("%r is not a class" % (klass,))
486 if not isTestCase(klass):
487 raise ValueError("%r is not a test case" % (klass,))
488 names = self.getTestCaseNames(klass)
489 tests = self.sort([self._makeCase(klass, self.methodPrefix+name)
490 for name in names])
491 return self.suiteFactory(tests)
492 loadTestsFromTestCase = loadClass
493
494 def getTestCaseNames(self, klass):
495 """
496 Given a class that contains C{TestCase}s, return a list of names of
497 methods that probably contain tests.
498 """
499 return reflect.prefixedMethodNames(klass, self.methodPrefix)
500
501 def loadMethod(self, method):
502 """
503 Given a method of a C{TestCase} that represents a test, return a
504 C{TestCase} instance for that test.
505 """
506 if not isinstance(method, types.MethodType):
507 raise TypeError("%r not a method" % (method,))
508 return self._makeCase(method.im_class, method.__name__)
509
510 def _makeCase(self, klass, methodName):
511 return klass(methodName)
512
513 def loadPackage(self, package, recurse=False):
514 """
515 Load tests from a module object representing a package, and return a
516 TestSuite containing those tests.
517
518 Tests are only loaded from modules whose name begins with 'test_'
519 (or whatever C{modulePrefix} is set to).
520
521 @param package: a types.ModuleType object (or reasonable facsimilie
522 obtained by importing) which may contain tests.
523
524 @param recurse: A boolean. If True, inspect modules within packages
525 within the given package (and so on), otherwise, only inspect modules
526 in the package itself.
527
528 @raise: TypeError if 'package' is not a package.
529
530 @return: a TestSuite created with my suiteFactory, containing all the
531 tests.
532 """
533 if not isPackage(package):
534 raise TypeError("%r is not a package" % (package,))
535 pkgobj = modules.getModule(package.__name__)
536 if recurse:
537 discovery = pkgobj.walkModules()
538 else:
539 discovery = pkgobj.iterModules()
540 discovered = []
541 for disco in discovery:
542 if disco.name.split(".")[-1].startswith(self.modulePrefix):
543 discovered.append(disco)
544 suite = self.suiteFactory()
545 for modinfo in self.sort(discovered):
546 try:
547 module = modinfo.load()
548 except:
549 thingToAdd = ErrorHolder(modinfo.name, failure.Failure())
550 else:
551 thingToAdd = self.loadModule(module)
552 suite.addTest(thingToAdd)
553 return suite
554
555 def loadDoctests(self, module):
556 """
557 Return a suite of tests for all the doctests defined in C{module}.
558
559 @param module: A module object or a module name.
560 """
561 if isinstance(module, str):
562 try:
563 module = reflect.namedAny(module)
564 except:
565 return ErrorHolder(module, failure.Failure())
566 if not inspect.ismodule(module):
567 warnings.warn("trial only supports doctesting modules")
568 return
569 return doctest.DocTestSuite(module)
570
571 def loadAnything(self, thing, recurse=False):
572 """
573 Given a Python object, return whatever tests that are in it. Whatever
574 'in' might mean.
575
576 @param thing: A Python object. A module, method, class or package.
577 @param recurse: Whether or not to look in subpackages of packages.
578 Defaults to False.
579
580 @return: A C{TestCase} or C{TestSuite}.
581 """
582 if isinstance(thing, types.ModuleType):
583 if isPackage(thing):
584 return self.loadPackage(thing, recurse)
585 return self.loadModule(thing)
586 elif isinstance(thing, types.ClassType):
587 return self.loadClass(thing)
588 elif isinstance(thing, type):
589 return self.loadClass(thing)
590 elif isinstance(thing, types.MethodType):
591 return self.loadMethod(thing)
592 raise TypeError("No loader for %r. Unrecognized type" % (thing,))
593
594 def loadByName(self, name, recurse=False):
595 """
596 Given a string representing a Python object, return whatever tests
597 are in that object.
598
599 If C{name} is somehow inaccessible (e.g. the module can't be imported,
600 there is no Python object with that name etc) then return an
601 L{ErrorHolder}.
602
603 @param name: The fully-qualified name of a Python object.
604 """
605 try:
606 thing = self.findByName(name)
607 except:
608 return ErrorHolder(name, failure.Failure())
609 return self.loadAnything(thing, recurse)
610 loadTestsFromName = loadByName
611
612 def loadByNames(self, names, recurse=False):
613 """
614 Construct a TestSuite containing all the tests found in 'names', where
615 names is a list of fully qualified python names and/or filenames. The
616 suite returned will have no duplicate tests, even if the same object
617 is named twice.
618 """
619 things = []
620 errors = []
621 for name in names:
622 try:
623 things.append(self.findByName(name))
624 except:
625 errors.append(ErrorHolder(name, failure.Failure()))
626 suites = [self.loadAnything(thing, recurse)
627 for thing in set(things)]
628 suites.extend(errors)
629 return self.suiteFactory(suites)
630
631
632
633 class DryRunVisitor(object):
634 """
635 A visitor that makes a reporter think that every test visited has run
636 successfully.
637 """
638
639 def __init__(self, reporter):
640 """
641 @param reporter: A C{TestResult} object.
642 """
643 self.reporter = reporter
644
645
646 def markSuccessful(self, testCase):
647 """
648 Convince the reporter that this test has been run successfully.
649 """
650 self.reporter.startTest(testCase)
651 self.reporter.addSuccess(testCase)
652 self.reporter.stopTest(testCase)
653
654
655
656 class TrialRunner(object):
657 """
658 A specialised runner that the trial front end uses.
659 """
660
661 DEBUG = 'debug'
662 DRY_RUN = 'dry-run'
663
664 def _getDebugger(self):
665 dbg = pdb.Pdb()
666 try:
667 import readline
668 except ImportError:
669 print "readline module not available"
670 hasattr(sys, 'exc_clear') and sys.exc_clear()
671 for path in ('.pdbrc', 'pdbrc'):
672 if os.path.exists(path):
673 try:
674 rcFile = file(path, 'r')
675 except IOError:
676 hasattr(sys, 'exc_clear') and sys.exc_clear()
677 else:
678 dbg.rcLines.extend(rcFile.readlines())
679 return dbg
680
681 def _setUpTestdir(self):
682 self._tearDownLogFile()
683 currentDir = os.getcwd()
684 testdir = os.path.normpath(os.path.abspath(self.workingDirectory))
685 if os.path.exists(testdir):
686 try:
687 shutil.rmtree(testdir)
688 except OSError, e:
689 print ("could not remove %r, caught OSError [Errno %s]: %s"
690 % (testdir, e.errno,e.strerror))
691 try:
692 os.rename(testdir,
693 os.path.abspath("_trial_temp_old%s"
694 % random.randint(0, 99999999)))
695 except OSError, e:
696 print ("could not rename path, caught OSError [Errno %s]: %s"
697 % (e.errno,e.strerror))
698 raise
699 os.mkdir(testdir)
700 os.chdir(testdir)
701 return currentDir
702
703 def _makeResult(self):
704 reporter = self.reporterFactory(self.stream, self.tbformat,
705 self.rterrors)
706 if self.uncleanWarnings:
707 reporter = UncleanWarningsReporterWrapper(reporter)
708 return reporter
709
710 def __init__(self, reporterFactory,
711 mode=None,
712 logfile='test.log',
713 stream=sys.stdout,
714 profile=False,
715 tracebackFormat='default',
716 realTimeErrors=False,
717 uncleanWarnings=False,
718 workingDirectory=None,
719 forceGarbageCollection=False):
720 self.reporterFactory = reporterFactory
721 self.logfile = logfile
722 self.mode = mode
723 self.stream = stream
724 self.tbformat = tracebackFormat
725 self.rterrors = realTimeErrors
726 self.uncleanWarnings = uncleanWarnings
727 self._result = None
728 self.workingDirectory = workingDirectory or '_trial_temp'
729 self._logFileObserver = None
730 self._logFileObject = None
731 self._logWarnings = False
732 self._forceGarbageCollection = forceGarbageCollection
733 if profile:
734 self.run = util.profiled(self.run, 'profile.data')
735
736 def _setUpLogging(self):
737 self._setUpLogFile()
738 self._setUpLogWarnings()
739
740 def _tearDownLogFile(self):
741 if self._logFileObserver is not None:
742 log.removeObserver(self._logFileObserver.emit)
743 self._logFileObserver = None
744 if self._logFileObject is not None:
745 self._logFileObject.close()
746 self._logFileObject = None
747
748 def _setUpLogFile(self):
749 self._tearDownLogFile()
750 if self.logfile == '-':
751 logFile = sys.stdout
752 else:
753 logFile = file(self.logfile, 'a')
754 self._logFileObject = logFile
755 self._logFileObserver = log.FileLogObserver(logFile)
756 log.startLoggingWithObserver(self._logFileObserver.emit, 0)
757
758 def _setUpLogWarnings(self):
759 if self._logWarnings:
760 return
761 def seeWarnings(x):
762 if x.has_key('warning'):
763 print
764 print x['format'] % x
765 log.addObserver(seeWarnings)
766 self._logWarnings = True
767
768 def run(self, test):
769 """
770 Run the test or suite and return a result object.
771 """
772 result = self._makeResult()
773 test = unittest.decorate(test, ITestCase)
774 if self._forceGarbageCollection:
775 test = unittest.decorate(
776 test, unittest._ForceGarbageCollectionDecorator)
777 # decorate the suite with reactor cleanup and log starting
778 # This should move out of the runner and be presumed to be
779 # present
780 suite = TrialSuite([test])
781 startTime = time.time()
782 if self.mode == self.DRY_RUN:
783 suite.visit(DryRunVisitor(result).markSuccessful)
784 elif self.mode == self.DEBUG:
785 # open question - should this be self.debug() instead.
786 debugger = self._getDebugger()
787 oldDir = self._setUpTestdir()
788 try:
789 self._setUpLogging()
790 debugger.runcall(suite.run, result)
791 finally:
792 self._tearDownLogFile()
793 os.chdir(oldDir)
794 else:
795 oldDir = self._setUpTestdir()
796 try:
797 self._setUpLogging()
798 suite.run(result)
799 finally:
800 self._tearDownLogFile()
801 os.chdir(oldDir)
802 endTime = time.time()
803 done = getattr(result, 'done', None)
804 if done is None:
805 warnings.warn(
806 "%s should implement done() but doesn't. Falling back to "
807 "printErrors() and friends." % reflect.qual(result.__class__),
808 category=DeprecationWarning, stacklevel=2)
809 result.printErrors()
810 result.writeln(result.separator)
811 result.writeln('Ran %d tests in %.3fs', result.testsRun,
812 endTime - startTime)
813 result.write('\n')
814 result.printSummary()
815 else:
816 result.done()
817 return result
818
819 def runUntilFailure(self, test):
820 """
821 Repeatedly run C{test} until it fails.
822 """
823 count = 0
824 while True:
825 count += 1
826 self.stream.write("Test Pass %d\n" % (count,))
827 result = self.run(test)
828 if result.testsRun == 0:
829 break
830 if not result.wasSuccessful():
831 break
832 return result
833
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/trial/reporter.py ('k') | third_party/twisted_8_1/twisted/trial/test/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698