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

Side by Side Diff: third_party/twisted_8_1/twisted/trial/test/test_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 # Copyright (c) 2005-2007 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3 #
4 # Maintainer: Jonathan Lange <jml@twistedmatrix.com>
5 # Author: Robert Collins <robertc@robertcollins.net>
6
7
8 import StringIO
9 from zope.interface import implements
10
11 from twisted.trial.itrial import IReporter, ITestCase
12 from twisted.trial import unittest, runner, reporter, util
13 from twisted.python import failure, log, reflect
14 from twisted.scripts import trial
15 from twisted.plugins import twisted_trial
16 from twisted import plugin
17 from twisted.internet import defer
18
19
20 pyunit = __import__('unittest')
21
22
23 class CapturingDebugger(object):
24
25 def __init__(self):
26 self._calls = []
27
28 def runcall(self, *args, **kwargs):
29 self._calls.append('runcall')
30 args[0](*args[1:], **kwargs)
31
32
33
34 class CapturingReporter(object):
35 """
36 Reporter that keeps a log of all actions performed on it.
37 """
38
39 implements(IReporter)
40
41 stream = None
42 tbformat = None
43 args = None
44 separator = None
45 testsRun = None
46
47 def __init__(self, *a, **kw):
48 """
49 Create a capturing reporter.
50 """
51 self._calls = []
52 self.shouldStop = False
53
54
55 def startTest(self, method):
56 """
57 Report the beginning of a run of a single test method
58 @param method: an object that is adaptable to ITestMethod
59 """
60 self._calls.append('startTest')
61
62
63 def stopTest(self, method):
64 """
65 Report the status of a single test method
66 @param method: an object that is adaptable to ITestMethod
67 """
68 self._calls.append('stopTest')
69
70
71 def cleanupErrors(self, errs):
72 """called when the reactor has been left in a 'dirty' state
73 @param errs: a list of L{twisted.python.failure.Failure}s
74 """
75 self._calls.append('cleanupError')
76
77
78 def addSuccess(self, test):
79 self._calls.append('addSuccess')
80
81
82 def done(self):
83 """
84 Do nothing. These tests don't care about done.
85 """
86
87
88
89 class TestTrialRunner(unittest.TestCase):
90
91 def setUp(self):
92 self.stream = StringIO.StringIO()
93 self.runner = runner.TrialRunner(CapturingReporter, stream=self.stream)
94 self.test = TestTrialRunner('test_empty')
95
96 def test_empty(self):
97 """
98 Empty test method, used by the other tests.
99 """
100
101 def tearDown(self):
102 self.runner._tearDownLogFile()
103
104 def _getObservers(self):
105 return log.theLogPublisher.observers
106
107 def test_addObservers(self):
108 """
109 Tests that the runner add logging observers during the run.
110 """
111 originalCount = len(self._getObservers())
112 self.runner.run(self.test)
113 newCount = len(self._getObservers())
114 self.failUnlessEqual(originalCount + 1, newCount)
115
116 def test_addObservers_repeat(self):
117 self.runner.run(self.test)
118 count = len(self._getObservers())
119 self.runner.run(self.test)
120 newCount = len(self._getObservers())
121 self.failUnlessEqual(count, newCount)
122
123 def test_logFileAlwaysActive(self):
124 """
125 Test that a new file is opened on each run.
126 """
127 oldSetUpLogging = self.runner._setUpLogging
128 l = []
129 def setUpLogging():
130 oldSetUpLogging()
131 l.append(self.runner._logFileObserver)
132 self.runner._setUpLogging = setUpLogging
133 self.runner.run(self.test)
134 self.runner.run(self.test)
135 self.failUnlessEqual(len(l), 2)
136 self.failIf(l[0] is l[1], "Should have created a new file observer")
137
138 def test_logFileGetsClosed(self):
139 """
140 Test that file created is closed during the run.
141 """
142 oldSetUpLogging = self.runner._setUpLogging
143 l = []
144 def setUpLogging():
145 oldSetUpLogging()
146 l.append(self.runner._logFileObject)
147 self.runner._setUpLogging = setUpLogging
148 self.runner.run(self.test)
149 self.failUnlessEqual(len(l), 1)
150 self.failUnless(l[0].closed)
151
152
153
154 class TrialRunnerWithUncleanWarningsReporter(TestTrialRunner):
155 """
156 Tests for the TrialRunner's interaction with an unclean-error suppressing
157 reporter.
158 """
159
160 def setUp(self):
161 self.stream = StringIO.StringIO()
162 self.runner = runner.TrialRunner(CapturingReporter, stream=self.stream,
163 uncleanWarnings=True)
164 self.test = TestTrialRunner('test_empty')
165
166
167
168 class DryRunMixin(object):
169
170 suppress = [util.suppress(
171 category=DeprecationWarning,
172 message="Test visitors deprecated in Twisted 8.0")]
173
174
175 def setUp(self):
176 self.log = []
177 self.stream = StringIO.StringIO()
178 self.runner = runner.TrialRunner(CapturingReporter,
179 runner.TrialRunner.DRY_RUN,
180 stream=self.stream)
181 self.makeTestFixtures()
182
183
184 def makeTestFixtures(self):
185 """
186 Set C{self.test} and C{self.suite}, where C{self.suite} is an empty
187 TestSuite.
188 """
189
190
191 def test_empty(self):
192 """
193 If there are no tests, the reporter should not receive any events to
194 report.
195 """
196 result = self.runner.run(runner.TestSuite())
197 self.assertEqual(result._calls, [])
198
199
200 def test_singleCaseReporting(self):
201 """
202 If we are running a single test, check the reporter starts, passes and
203 then stops the test during a dry run.
204 """
205 result = self.runner.run(self.test)
206 self.assertEqual(result._calls, ['startTest', 'addSuccess', 'stopTest'])
207
208
209 def test_testsNotRun(self):
210 """
211 When we are doing a dry run, the tests should not actually be run.
212 """
213 self.runner.run(self.test)
214 self.assertEqual(self.log, [])
215
216
217
218 class DryRunTest(DryRunMixin, unittest.TestCase):
219 """
220 Check that 'dry run' mode works well with Trial tests.
221 """
222 def makeTestFixtures(self):
223 class MockTest(unittest.TestCase):
224 def test_foo(test):
225 self.log.append('test_foo')
226 self.test = MockTest('test_foo')
227 self.suite = runner.TestSuite()
228
229
230
231 class PyUnitDryRunTest(DryRunMixin, unittest.TestCase):
232 """
233 Check that 'dry run' mode works well with stdlib unittest tests.
234 """
235 def makeTestFixtures(self):
236 class PyunitCase(pyunit.TestCase):
237 def test_foo(self):
238 pass
239 self.test = PyunitCase('test_foo')
240 self.suite = pyunit.TestSuite()
241
242
243
244 class TestRunner(unittest.TestCase):
245 def setUp(self):
246 self.config = trial.Options()
247 # whitebox hack a reporter in, because plugins are CACHED and will
248 # only reload if the FILE gets changed.
249
250 parts = reflect.qual(CapturingReporter).split('.')
251 package = '.'.join(parts[:-1])
252 klass = parts[-1]
253 plugins = [twisted_trial._Reporter(
254 "Test Helper Reporter",
255 package,
256 description="Utility for unit testing.",
257 longOpt="capturing",
258 shortOpt=None,
259 klass=klass)]
260
261
262 # XXX There should really be a general way to hook the plugin system
263 # for tests.
264 def getPlugins(iface, *a, **kw):
265 self.assertEqual(iface, IReporter)
266 return plugins + list(self.original(iface, *a, **kw))
267
268 self.original = plugin.getPlugins
269 plugin.getPlugins = getPlugins
270
271 self.standardReport = ['startTest', 'addSuccess', 'stopTest',
272 'startTest', 'addSuccess', 'stopTest',
273 'startTest', 'addSuccess', 'stopTest',
274 'startTest', 'addSuccess', 'stopTest',
275 'startTest', 'addSuccess', 'stopTest',
276 'startTest', 'addSuccess', 'stopTest',
277 'startTest', 'addSuccess', 'stopTest']
278
279
280 def tearDown(self):
281 plugin.getPlugins = self.original
282
283
284 def parseOptions(self, args):
285 self.config.parseOptions(args)
286
287
288 def getRunner(self):
289 r = trial._makeRunner(self.config)
290 r.stream = StringIO.StringIO()
291 self.addCleanup(r._tearDownLogFile)
292 return r
293
294
295 def test_runner_can_get_reporter(self):
296 self.parseOptions([])
297 result = self.config['reporter']
298 my_runner = self.getRunner()
299 try:
300 self.assertEqual(result, my_runner._makeResult().__class__)
301 finally:
302 my_runner._tearDownLogFile()
303
304
305 def test_runner_get_result(self):
306 self.parseOptions([])
307 my_runner = self.getRunner()
308 result = my_runner._makeResult()
309 self.assertEqual(result.__class__, self.config['reporter'])
310
311
312 def test_uncleanWarningsOffByDefault(self):
313 """
314 By default Trial sets the 'uncleanWarnings' option on the runner to
315 False. This means that dirty reactor errors will be reported as
316 errors. See L{test_reporter.TestDirtyReactor}.
317 """
318 self.parseOptions([])
319 runner = self.getRunner()
320 self.assertNotIsInstance(runner._makeResult(),
321 reporter.UncleanWarningsReporterWrapper)
322
323
324 def test_getsUncleanWarnings(self):
325 """
326 Specifying '--unclean-warnings' on the trial command line will cause
327 reporters to be wrapped in a device which converts unclean errors to
328 warnings. See L{test_reporter.TestDirtyReactor} for implications.
329 """
330 self.parseOptions(['--unclean-warnings'])
331 runner = self.getRunner()
332 self.assertIsInstance(runner._makeResult(),
333 reporter.UncleanWarningsReporterWrapper)
334
335
336 def test_runner_working_directory(self):
337 self.parseOptions(['--temp-directory', 'some_path'])
338 runner = self.getRunner()
339 try:
340 self.assertEquals(runner.workingDirectory, 'some_path')
341 finally:
342 runner._tearDownLogFile()
343
344
345 def test_runner_normal(self):
346 self.parseOptions(['--temp-directory', self.mktemp(),
347 '--reporter', 'capturing',
348 'twisted.trial.test.sample'])
349 my_runner = self.getRunner()
350 loader = runner.TestLoader()
351 suite = loader.loadByName('twisted.trial.test.sample', True)
352 result = my_runner.run(suite)
353 self.assertEqual(self.standardReport, result._calls)
354
355
356 def test_runner_debug(self):
357 self.parseOptions(['--reporter', 'capturing',
358 '--debug', 'twisted.trial.test.sample'])
359 my_runner = self.getRunner()
360 debugger = CapturingDebugger()
361 def get_debugger():
362 return debugger
363 my_runner._getDebugger = get_debugger
364 loader = runner.TestLoader()
365 suite = loader.loadByName('twisted.trial.test.sample', True)
366 result = my_runner.run(suite)
367 self.assertEqual(self.standardReport, result._calls)
368 self.assertEqual(['runcall'], debugger._calls)
369
370
371
372 class TestTrialSuite(unittest.TestCase):
373
374 def test_imports(self):
375 # FIXME, HTF do you test the reactor can be cleaned up ?!!!
376 from twisted.trial.runner import TrialSuite
377 # silence pyflakes warning
378 silencePyflakes = TrialSuite
379
380
381
382 class TestUntilFailure(unittest.TestCase):
383 class FailAfter(unittest.TestCase):
384 """
385 A test case that fails when run 3 times in a row.
386 """
387 count = []
388 def test_foo(self):
389 self.count.append(None)
390 if len(self.count) == 3:
391 self.fail('Count reached 3')
392
393 def setUp(self):
394 TestUntilFailure.FailAfter.count = []
395 self.test = TestUntilFailure.FailAfter('test_foo')
396 self.stream = StringIO.StringIO()
397 self.runner = runner.TrialRunner(reporter.Reporter, stream=self.stream)
398
399 def test_runUntilFailure(self):
400 """
401 Test that the runUntilFailure method of the runner actually fail after
402 a few runs.
403 """
404 result = self.runner.runUntilFailure(self.test)
405 self.failUnlessEqual(result.testsRun, 1)
406 self.failIf(result.wasSuccessful())
407 self.assertEquals(self._getFailures(result), 1)
408
409 def _getFailures(self, result):
410 """
411 Get the number of failures that were reported to a result.
412 """
413 return len(result.failures)
414
415
416
417 class UncleanUntilFailureTests(TestUntilFailure):
418 """
419 Test that the run-until-failure feature works correctly with the unclean
420 error suppressor.
421 """
422
423 def setUp(self):
424 TestUntilFailure.setUp(self)
425 self.runner = runner.TrialRunner(reporter.Reporter, stream=self.stream,
426 uncleanWarnings=True)
427
428 def _getFailures(self, result):
429 """
430 Get the number of failures that were reported to a result that
431 is wrapped in an UncleanFailureWrapper.
432 """
433 return len(result._originalReporter.failures)
434
435
436
437 class BreakingSuite(runner.TestSuite):
438 """
439 A L{TestSuite} that logs an error when it is run.
440 """
441
442 def run(self, result):
443 try:
444 raise RuntimeError("error that occurs outside of a test")
445 except RuntimeError, e:
446 log.err(failure.Failure())
447
448
449
450 class TestLoggedErrors(unittest.TestCase):
451 """
452 It is possible for an error generated by a test to be logged I{outside} of
453 any test. The log observers constructed by L{TestCase} won't catch these
454 errors. Here we try to generate such errors and ensure they are reported to
455 a L{TestResult} object.
456 """
457
458 def tearDown(self):
459 self.flushLoggedErrors(RuntimeError)
460
461
462 def test_construct(self):
463 """
464 Check that we can construct a L{runner.LoggedSuite} and that it
465 starts empty.
466 """
467 suite = runner.LoggedSuite()
468 self.assertEqual(suite.countTestCases(), 0)
469
470
471 def test_capturesError(self):
472 """
473 Chek that a L{LoggedSuite} reports any logged errors to its result.
474 """
475 result = reporter.TestResult()
476 suite = runner.LoggedSuite([BreakingSuite()])
477 suite.run(result)
478 self.assertEqual(len(result.errors), 1)
479 self.assertEqual(result.errors[0][0].id(), runner.NOT_IN_TEST)
480 self.failUnless(result.errors[0][1].check(RuntimeError))
481
482
483
484 class TestTestHolder(unittest.TestCase):
485
486 def setUp(self):
487 self.description = "description"
488 self.holder = runner.TestHolder(self.description)
489
490
491 def test_holder(self):
492 """
493 Check that L{runner.TestHolder} takes a description as a parameter
494 and that this description is returned by the C{id} and
495 C{shortDescription} methods.
496 """
497 self.assertEqual(self.holder.id(), self.description)
498 self.assertEqual(self.holder.shortDescription(), self.description)
499
500
501 def test_holderImplementsITestCase(self):
502 """
503 L{runner.TestHolder} implements L{ITestCase}.
504 """
505 self.assertIdentical(self.holder, ITestCase(self.holder))
506
507
508
509 class TestErrorHolder(TestTestHolder):
510 """
511 Test L{runner.ErrorHolder} shares behaviour with L{runner.TestHolder}.
512 """
513
514 def setUp(self):
515 self.description = "description"
516 # make a real Failure so we can construct ErrorHolder()
517 try:
518 1/0
519 except ZeroDivisionError:
520 error = failure.Failure()
521 self.holder = runner.ErrorHolder(self.description, error)
522
523
524
525 class TestMalformedMethod(unittest.TestCase):
526 """
527 Test that trial manages when test methods don't have correct signatures.
528 """
529 class ContainMalformed(unittest.TestCase):
530 """
531 This TestCase holds malformed test methods that trial should handle.
532 """
533 def test_foo(self, blah):
534 pass
535 def test_bar():
536 pass
537 test_spam = defer.deferredGenerator(test_bar)
538
539 def _test(self, method):
540 """
541 Wrapper for one of the test method of L{ContainMalformed}.
542 """
543 stream = StringIO.StringIO()
544 trialRunner = runner.TrialRunner(reporter.Reporter, stream=stream)
545 test = TestMalformedMethod.ContainMalformed(method)
546 result = trialRunner.run(test)
547 self.failUnlessEqual(result.testsRun, 1)
548 self.failIf(result.wasSuccessful())
549 self.failUnlessEqual(len(result.errors), 1)
550
551 def test_extraArg(self):
552 """
553 Test when the method has extra (useless) arguments.
554 """
555 self._test('test_foo')
556
557 def test_noArg(self):
558 """
559 Test when the method doesn't have even self as argument.
560 """
561 self._test('test_bar')
562
563 def test_decorated(self):
564 """
565 Test a decorated method also fails.
566 """
567 self._test('test_spam')
568
569
570
571 class DestructiveTestSuiteTestCase(unittest.TestCase):
572 """
573 Test for L{runner.DestructiveTestSuite}.
574 """
575
576 def test_basic(self):
577 """
578 Thes destructive test suite should run the tests normally.
579 """
580 called = []
581 class MockTest(unittest.TestCase):
582 def test_foo(test):
583 called.append(True)
584 test = MockTest('test_foo')
585 result = reporter.TestResult()
586 suite = runner.DestructiveTestSuite([test])
587 self.assertEquals(called, [])
588 suite.run(result)
589 self.assertEquals(called, [True])
590 self.assertEquals(suite.countTestCases(), 0)
591
592
593 def test_shouldStop(self):
594 """
595 Test the C{shouldStop} management: raising a C{KeyboardInterrupt} must
596 interrupt the suite.
597 """
598 called = []
599 class MockTest(unittest.TestCase):
600 def test_foo1(test):
601 called.append(1)
602 def test_foo2(test):
603 raise KeyboardInterrupt()
604 def test_foo3(test):
605 called.append(2)
606 result = reporter.TestResult()
607 loader = runner.TestLoader()
608 loader.suiteFactory = runner.DestructiveTestSuite
609 suite = loader.loadClass(MockTest)
610 self.assertEquals(called, [])
611 suite.run(result)
612 self.assertEquals(called, [1])
613 # The last test shouldn't have been run
614 self.assertEquals(suite.countTestCases(), 1)
615
616
617 def test_cleanup(self):
618 """
619 Checks that the test suite cleanups its tests during the run, so that
620 it ends empty.
621 """
622 class MockTest(unittest.TestCase):
623 def test_foo(test):
624 pass
625 test = MockTest('test_foo')
626 result = reporter.TestResult()
627 suite = runner.DestructiveTestSuite([test])
628 self.assertEquals(suite.countTestCases(), 1)
629 suite.run(result)
630 self.assertEquals(suite.countTestCases(), 0)
631
632
633
634 class TestRunnerDeprecation(unittest.TestCase):
635
636 class FakeReporter(reporter.Reporter):
637 """
638 Fake reporter that does *not* implement done() but *does* implement
639 printErrors, separator, printSummary, stream, write and writeln
640 without deprecations.
641 """
642
643 done = None
644 separator = None
645 stream = None
646
647 def printErrors(self, *args):
648 pass
649
650 def printSummary(self, *args):
651 pass
652
653 def write(self, *args):
654 pass
655
656 def writeln(self, *args):
657 pass
658
659
660 def test_reporterDeprecations(self):
661 """
662 The runner emits a warning if it is using a result that doesn't
663 implement 'done'.
664 """
665 trialRunner = runner.TrialRunner(None)
666 result = self.FakeReporter()
667 trialRunner._makeResult = lambda: result
668 def f():
669 # We have to use a pyunit test, otherwise we'll get deprecation
670 # warnings about using iterate() in a test.
671 trialRunner.run(pyunit.TestCase('id'))
672 self.assertWarns(
673 DeprecationWarning,
674 "%s should implement done() but doesn't. Falling back to "
675 "printErrors() and friends." % reflect.qual(result.__class__),
676 __file__, f)
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/trial/test/test_reporter.py ('k') | third_party/twisted_8_1/twisted/trial/test/test_script.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698