~0x44/nova/bug838466

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/trial/test/test_tests.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Tests for the behaviour of unit tests.
 
6
"""
 
7
 
 
8
import gc, StringIO, sys, weakref
 
9
 
 
10
from twisted.internet import defer, reactor
 
11
from twisted.trial import unittest, runner, reporter, util
 
12
from twisted.trial.test import erroneous, suppression
 
13
from twisted.trial.test.test_reporter import LoggingReporter
 
14
 
 
15
 
 
16
class ResultsTestMixin:
 
17
    def loadSuite(self, suite):
 
18
        self.loader = runner.TestLoader()
 
19
        self.suite = self.loader.loadClass(suite)
 
20
        self.reporter = reporter.TestResult()
 
21
 
 
22
    def test_setUp(self):
 
23
        self.failUnless(self.reporter.wasSuccessful())
 
24
        self.failUnlessEqual(self.reporter.errors, [])
 
25
        self.failUnlessEqual(self.reporter.failures, [])
 
26
        self.failUnlessEqual(self.reporter.skips, [])
 
27
 
 
28
    def assertCount(self, numTests):
 
29
        self.failUnlessEqual(self.suite.countTestCases(), numTests)
 
30
        self.suite(self.reporter)
 
31
        self.failUnlessEqual(self.reporter.testsRun, numTests)
 
32
 
 
33
 
 
34
 
 
35
class TestSuccess(unittest.TestCase):
 
36
    """
 
37
    Test that successful tests are reported as such.
 
38
    """
 
39
 
 
40
    def setUp(self):
 
41
        self.result = reporter.TestResult()
 
42
 
 
43
 
 
44
    def test_successful(self):
 
45
        """
 
46
        A successful test, used by other tests.
 
47
        """
 
48
 
 
49
 
 
50
    def assertSuccessful(self, test, result):
 
51
        self.assertEqual(result.successes, 1)
 
52
        self.assertEqual(result.failures, [])
 
53
        self.assertEqual(result.errors, [])
 
54
        self.assertEqual(result.expectedFailures, [])
 
55
        self.assertEqual(result.unexpectedSuccesses, [])
 
56
        self.assertEqual(result.skips, [])
 
57
 
 
58
 
 
59
    def test_successfulIsReported(self):
 
60
        """
 
61
        Test that when a successful test is run, it is reported as a success,
 
62
        and not as any other kind of result.
 
63
        """
 
64
        test = TestSuccess('test_successful')
 
65
        test.run(self.result)
 
66
        self.assertSuccessful(test, self.result)
 
67
 
 
68
 
 
69
    def test_defaultIsSuccessful(self):
 
70
        """
 
71
        Test that L{unittest.TestCase} itself can be instantiated, run, and
 
72
        reported as being successful.
 
73
        """
 
74
        test = unittest.TestCase()
 
75
        test.run(self.result)
 
76
        self.assertSuccessful(test, self.result)
 
77
 
 
78
 
 
79
    def test_noReference(self):
 
80
        """
 
81
        Test that no reference is kept on a successful test.
 
82
        """
 
83
        test = TestSuccess('test_successful')
 
84
        ref = weakref.ref(test)
 
85
        test.run(self.result)
 
86
        self.assertSuccessful(test, self.result)
 
87
        del test
 
88
        gc.collect()
 
89
        self.assertIdentical(ref(), None)
 
90
 
 
91
 
 
92
 
 
93
class TestSkipMethods(unittest.TestCase, ResultsTestMixin):
 
94
    class SkippingTests(unittest.TestCase):
 
95
        def test_skip1(self):
 
96
            raise unittest.SkipTest('skip1')
 
97
 
 
98
        def test_skip2(self):
 
99
            raise RuntimeError("I should not get raised")
 
100
        test_skip2.skip = 'skip2'
 
101
 
 
102
        def test_skip3(self):
 
103
            self.fail('I should not fail')
 
104
        test_skip3.skip = 'skip3'
 
105
 
 
106
    class SkippingSetUp(unittest.TestCase):
 
107
        def setUp(self):
 
108
            raise unittest.SkipTest('skipSetUp')
 
109
 
 
110
        def test_1(self):
 
111
            pass
 
112
 
 
113
        def test_2(self):
 
114
            pass
 
115
 
 
116
    def setUp(self):
 
117
        self.loadSuite(TestSkipMethods.SkippingTests)
 
118
 
 
119
    def test_counting(self):
 
120
        self.assertCount(3)
 
121
 
 
122
    def test_results(self):
 
123
        self.suite(self.reporter)
 
124
        self.failUnless(self.reporter.wasSuccessful())
 
125
        self.failUnlessEqual(self.reporter.errors, [])
 
126
        self.failUnlessEqual(self.reporter.failures, [])
 
127
        self.failUnlessEqual(len(self.reporter.skips), 3)
 
128
 
 
129
    def test_setUp(self):
 
130
        self.loadSuite(TestSkipMethods.SkippingSetUp)
 
131
        self.suite(self.reporter)
 
132
        self.failUnless(self.reporter.wasSuccessful())
 
133
        self.failUnlessEqual(self.reporter.errors, [])
 
134
        self.failUnlessEqual(self.reporter.failures, [])
 
135
        self.failUnlessEqual(len(self.reporter.skips), 2)
 
136
 
 
137
    def test_reasons(self):
 
138
        self.suite(self.reporter)
 
139
        prefix = 'test_'
 
140
        # whiteboxing reporter
 
141
        for test, reason in self.reporter.skips:
 
142
            self.failUnlessEqual(test.shortDescription()[len(prefix):],
 
143
                                 str(reason))
 
144
 
 
145
 
 
146
class TestSkipClasses(unittest.TestCase, ResultsTestMixin):
 
147
    class SkippedClass(unittest.TestCase):
 
148
        skip = 'class'
 
149
        def setUp(self):
 
150
            self.__class__._setUpRan = True
 
151
        def test_skip1(self):
 
152
            raise unittest.SkipTest('skip1')
 
153
        def test_skip2(self):
 
154
            raise RuntimeError("Ought to skip me")
 
155
        test_skip2.skip = 'skip2'
 
156
        def test_skip3(self):
 
157
            pass
 
158
        def test_skip4(self):
 
159
            raise RuntimeError("Skip me too")
 
160
 
 
161
 
 
162
    def setUp(self):
 
163
        self.loadSuite(TestSkipClasses.SkippedClass)
 
164
        TestSkipClasses.SkippedClass._setUpRan = False
 
165
 
 
166
 
 
167
    def test_counting(self):
 
168
        """
 
169
        Skipped test methods still contribute to the total test count.
 
170
        """
 
171
        self.assertCount(4)
 
172
 
 
173
 
 
174
    def test_setUpRan(self):
 
175
        """
 
176
        The C{setUp} method is not called if the class is set to skip.
 
177
        """
 
178
        self.suite(self.reporter)
 
179
        self.assertFalse(TestSkipClasses.SkippedClass._setUpRan)
 
180
 
 
181
 
 
182
    def test_results(self):
 
183
        """
 
184
        Skipped test methods don't cause C{wasSuccessful} to return C{False},
 
185
        nor do they contribute to the C{errors} or C{failures} of the reporter.
 
186
        They do, however, add elements to the reporter's C{skips} list.
 
187
        """
 
188
        self.suite(self.reporter)
 
189
        self.failUnless(self.reporter.wasSuccessful())
 
190
        self.failUnlessEqual(self.reporter.errors, [])
 
191
        self.failUnlessEqual(self.reporter.failures, [])
 
192
        self.failUnlessEqual(len(self.reporter.skips), 4)
 
193
 
 
194
 
 
195
    def test_reasons(self):
 
196
        """
 
197
        Test methods which raise L{unittest.SkipTest} or have their C{skip}
 
198
        attribute set to something are skipped.
 
199
        """
 
200
        self.suite(self.reporter)
 
201
        expectedReasons = ['class', 'skip2', 'class', 'class']
 
202
        # whitebox reporter
 
203
        reasonsGiven = [reason for test, reason in self.reporter.skips]
 
204
        self.assertEquals(expectedReasons, reasonsGiven)
 
205
 
 
206
 
 
207
 
 
208
class TestTodo(unittest.TestCase, ResultsTestMixin):
 
209
    class TodoTests(unittest.TestCase):
 
210
        def test_todo1(self):
 
211
            self.fail("deliberate failure")
 
212
        test_todo1.todo = "todo1"
 
213
 
 
214
        def test_todo2(self):
 
215
            raise RuntimeError("deliberate error")
 
216
        test_todo2.todo = "todo2"
 
217
 
 
218
        def test_todo3(self):
 
219
            """unexpected success"""
 
220
        test_todo3.todo = 'todo3'
 
221
 
 
222
    def setUp(self):
 
223
        self.loadSuite(TestTodo.TodoTests)
 
224
 
 
225
    def test_counting(self):
 
226
        self.assertCount(3)
 
227
 
 
228
    def test_results(self):
 
229
        self.suite(self.reporter)
 
230
        self.failUnless(self.reporter.wasSuccessful())
 
231
        self.failUnlessEqual(self.reporter.errors, [])
 
232
        self.failUnlessEqual(self.reporter.failures, [])
 
233
        self.failUnlessEqual(self.reporter.skips, [])
 
234
        self.failUnlessEqual(len(self.reporter.expectedFailures), 2)
 
235
        self.failUnlessEqual(len(self.reporter.unexpectedSuccesses), 1)
 
236
 
 
237
    def test_expectedFailures(self):
 
238
        self.suite(self.reporter)
 
239
        expectedReasons = ['todo1', 'todo2']
 
240
        reasonsGiven = [ r.reason
 
241
                         for t, e, r in self.reporter.expectedFailures ]
 
242
        self.failUnlessEqual(expectedReasons, reasonsGiven)
 
243
 
 
244
    def test_unexpectedSuccesses(self):
 
245
        self.suite(self.reporter)
 
246
        expectedReasons = ['todo3']
 
247
        reasonsGiven = [ r.reason
 
248
                         for t, r in self.reporter.unexpectedSuccesses ]
 
249
        self.failUnlessEqual(expectedReasons, reasonsGiven)
 
250
 
 
251
 
 
252
class TestTodoClass(unittest.TestCase, ResultsTestMixin):
 
253
    class TodoClass(unittest.TestCase):
 
254
        def test_todo1(self):
 
255
            pass
 
256
        test_todo1.todo = "method"
 
257
        def test_todo2(self):
 
258
            pass
 
259
        def test_todo3(self):
 
260
            self.fail("Deliberate Failure")
 
261
        test_todo3.todo = "method"
 
262
        def test_todo4(self):
 
263
            self.fail("Deliberate Failure")
 
264
    TodoClass.todo = "class"
 
265
 
 
266
    def setUp(self):
 
267
        self.loadSuite(TestTodoClass.TodoClass)
 
268
 
 
269
    def test_counting(self):
 
270
        self.assertCount(4)
 
271
 
 
272
    def test_results(self):
 
273
        self.suite(self.reporter)
 
274
        self.failUnless(self.reporter.wasSuccessful())
 
275
        self.failUnlessEqual(self.reporter.errors, [])
 
276
        self.failUnlessEqual(self.reporter.failures, [])
 
277
        self.failUnlessEqual(self.reporter.skips, [])
 
278
        self.failUnlessEqual(len(self.reporter.expectedFailures), 2)
 
279
        self.failUnlessEqual(len(self.reporter.unexpectedSuccesses), 2)
 
280
 
 
281
    def test_expectedFailures(self):
 
282
        self.suite(self.reporter)
 
283
        expectedReasons = ['method', 'class']
 
284
        reasonsGiven = [ r.reason
 
285
                         for t, e, r in self.reporter.expectedFailures ]
 
286
        self.failUnlessEqual(expectedReasons, reasonsGiven)
 
287
 
 
288
    def test_unexpectedSuccesses(self):
 
289
        self.suite(self.reporter)
 
290
        expectedReasons = ['method', 'class']
 
291
        reasonsGiven = [ r.reason
 
292
                         for t, r in self.reporter.unexpectedSuccesses ]
 
293
        self.failUnlessEqual(expectedReasons, reasonsGiven)
 
294
 
 
295
 
 
296
class TestStrictTodo(unittest.TestCase, ResultsTestMixin):
 
297
    class Todos(unittest.TestCase):
 
298
        def test_todo1(self):
 
299
            raise RuntimeError, "expected failure"
 
300
        test_todo1.todo = (RuntimeError, "todo1")
 
301
 
 
302
        def test_todo2(self):
 
303
            raise RuntimeError, "expected failure"
 
304
        test_todo2.todo = ((RuntimeError, OSError), "todo2")
 
305
 
 
306
        def test_todo3(self):
 
307
            raise RuntimeError, "we had no idea!"
 
308
        test_todo3.todo = (OSError, "todo3")
 
309
 
 
310
        def test_todo4(self):
 
311
            raise RuntimeError, "we had no idea!"
 
312
        test_todo4.todo = ((OSError, SyntaxError), "todo4")
 
313
 
 
314
        def test_todo5(self):
 
315
            self.fail("deliberate failure")
 
316
        test_todo5.todo = (unittest.FailTest, "todo5")
 
317
 
 
318
        def test_todo6(self):
 
319
            self.fail("deliberate failure")
 
320
        test_todo6.todo = (RuntimeError, "todo6")
 
321
 
 
322
        def test_todo7(self):
 
323
            pass
 
324
        test_todo7.todo = (RuntimeError, "todo7")
 
325
 
 
326
    def setUp(self):
 
327
        self.loadSuite(TestStrictTodo.Todos)
 
328
 
 
329
    def test_counting(self):
 
330
        self.assertCount(7)
 
331
 
 
332
    def test_results(self):
 
333
        self.suite(self.reporter)
 
334
        self.failIf(self.reporter.wasSuccessful())
 
335
        self.failUnlessEqual(len(self.reporter.errors), 2)
 
336
        self.failUnlessEqual(len(self.reporter.failures), 1)
 
337
        self.failUnlessEqual(len(self.reporter.expectedFailures), 3)
 
338
        self.failUnlessEqual(len(self.reporter.unexpectedSuccesses), 1)
 
339
        self.failUnlessEqual(self.reporter.skips, [])
 
340
 
 
341
    def test_expectedFailures(self):
 
342
        self.suite(self.reporter)
 
343
        expectedReasons = ['todo1', 'todo2', 'todo5']
 
344
        reasonsGotten = [ r.reason
 
345
                          for t, e, r in self.reporter.expectedFailures ]
 
346
        self.failUnlessEqual(expectedReasons, reasonsGotten)
 
347
 
 
348
    def test_unexpectedSuccesses(self):
 
349
        self.suite(self.reporter)
 
350
        expectedReasons = [([RuntimeError], 'todo7')]
 
351
        reasonsGotten = [ (r.errors, r.reason)
 
352
                          for t, r in self.reporter.unexpectedSuccesses ]
 
353
        self.failUnlessEqual(expectedReasons, reasonsGotten)
 
354
 
 
355
 
 
356
 
 
357
class TestCleanup(unittest.TestCase):
 
358
 
 
359
    def setUp(self):
 
360
        self.result = reporter.Reporter(StringIO.StringIO())
 
361
        self.loader = runner.TestLoader()
 
362
 
 
363
 
 
364
    def testLeftoverSockets(self):
 
365
        """
 
366
        Trial reports a L{util.DirtyReactorAggregateError} if a test leaves
 
367
        sockets behind.
 
368
        """
 
369
        suite = self.loader.loadMethod(
 
370
            erroneous.SocketOpenTest.test_socketsLeftOpen)
 
371
        suite.run(self.result)
 
372
        self.failIf(self.result.wasSuccessful())
 
373
        # socket cleanup happens at end of class's tests.
 
374
        # all the tests in the class are successful, even if the suite
 
375
        # fails
 
376
        self.assertEqual(self.result.successes, 1)
 
377
        failure = self.result.errors[0][1]
 
378
        self.failUnless(failure.check(util.DirtyReactorAggregateError))
 
379
 
 
380
 
 
381
    def testLeftoverPendingCalls(self):
 
382
        """
 
383
        Trial reports a L{util.DirtyReactorAggregateError} and fails the test
 
384
        if a test leaves a L{DelayedCall} hanging.
 
385
        """
 
386
        suite = erroneous.ReactorCleanupTests('test_leftoverPendingCalls')
 
387
        suite.run(self.result)
 
388
        self.failIf(self.result.wasSuccessful())
 
389
        failure = self.result.errors[0][1]
 
390
        self.assertEqual(self.result.successes, 0)
 
391
        self.failUnless(failure.check(util.DirtyReactorAggregateError))
 
392
 
 
393
 
 
394
 
 
395
class FixtureTest(unittest.TestCase):
 
396
    """
 
397
    Tests for broken fixture helper methods (e.g. setUp, tearDown).
 
398
    """
 
399
 
 
400
    def setUp(self):
 
401
        self.reporter = reporter.Reporter()
 
402
        self.loader = runner.TestLoader()
 
403
 
 
404
 
 
405
    def testBrokenSetUp(self):
 
406
        """
 
407
        When setUp fails, the error is recorded in the result object.
 
408
        """
 
409
        self.loader.loadClass(erroneous.TestFailureInSetUp).run(self.reporter)
 
410
        self.assert_(len(self.reporter.errors) > 0)
 
411
        self.assert_(isinstance(self.reporter.errors[0][1].value,
 
412
                                erroneous.FoolishError))
 
413
 
 
414
 
 
415
    def testBrokenTearDown(self):
 
416
        """
 
417
        When tearDown fails, the error is recorded in the result object.
 
418
        """
 
419
        suite = self.loader.loadClass(erroneous.TestFailureInTearDown)
 
420
        suite.run(self.reporter)
 
421
        errors = self.reporter.errors
 
422
        self.assert_(len(errors) > 0)
 
423
        self.assert_(isinstance(errors[0][1].value, erroneous.FoolishError))
 
424
 
 
425
 
 
426
 
 
427
class SuppressionTest(unittest.TestCase):
 
428
 
 
429
    def runTests(self, suite):
 
430
        suite.run(reporter.TestResult())
 
431
 
 
432
 
 
433
    def setUp(self):
 
434
        self.loader = runner.TestLoader()
 
435
 
 
436
 
 
437
    def test_suppressMethod(self):
 
438
        """
 
439
        A suppression set on a test method prevents warnings emitted by that
 
440
        test method which the suppression matches from being emitted.
 
441
        """
 
442
        self.runTests(self.loader.loadMethod(
 
443
            suppression.TestSuppression.testSuppressMethod))
 
444
        warningsShown = self.flushWarnings([
 
445
                suppression.TestSuppression._emit])
 
446
        self.assertEqual(
 
447
            warningsShown[0]['message'], suppression.CLASS_WARNING_MSG)
 
448
        self.assertEqual(
 
449
            warningsShown[1]['message'], suppression.MODULE_WARNING_MSG)
 
450
        self.assertEqual(len(warningsShown), 2)
 
451
 
 
452
 
 
453
    def test_suppressClass(self):
 
454
        """
 
455
        A suppression set on a L{TestCase} subclass prevents warnings emitted
 
456
        by any test methods defined on that class which match the suppression
 
457
        from being emitted.
 
458
        """
 
459
        self.runTests(self.loader.loadMethod(
 
460
            suppression.TestSuppression.testSuppressClass))
 
461
        warningsShown = self.flushWarnings([
 
462
                suppression.TestSuppression._emit])
 
463
        self.assertEqual(
 
464
            warningsShown[0]['message'], suppression.METHOD_WARNING_MSG)
 
465
        self.assertEqual(
 
466
            warningsShown[1]['message'], suppression.MODULE_WARNING_MSG)
 
467
        self.assertEqual(len(warningsShown), 2)
 
468
 
 
469
 
 
470
    def test_suppressModule(self):
 
471
        """
 
472
        A suppression set on a module prevents warnings emitted by any test
 
473
        mewthods defined in that module which match the suppression from being
 
474
        emitted.
 
475
        """
 
476
        self.runTests(self.loader.loadMethod(
 
477
            suppression.TestSuppression2.testSuppressModule))
 
478
        warningsShown = self.flushWarnings([
 
479
                suppression.TestSuppression._emit])
 
480
        self.assertEqual(
 
481
            warningsShown[0]['message'], suppression.METHOD_WARNING_MSG)
 
482
        self.assertEqual(
 
483
            warningsShown[1]['message'], suppression.CLASS_WARNING_MSG)
 
484
        self.assertEqual(len(warningsShown), 2)
 
485
 
 
486
 
 
487
    def test_overrideSuppressClass(self):
 
488
        """
 
489
        The suppression set on a test method completely overrides a suppression
 
490
        with wider scope; if it does not match a warning emitted by that test
 
491
        method, the warning is emitted, even if a wider suppression matches.
 
492
        """
 
493
        case = self.loader.loadMethod(
 
494
            suppression.TestSuppression.testOverrideSuppressClass)
 
495
        self.runTests(case)
 
496
        warningsShown = self.flushWarnings([
 
497
                suppression.TestSuppression._emit])
 
498
        self.assertEqual(
 
499
            warningsShown[0]['message'], suppression.METHOD_WARNING_MSG)
 
500
        self.assertEqual(
 
501
            warningsShown[1]['message'], suppression.CLASS_WARNING_MSG)
 
502
        self.assertEqual(
 
503
            warningsShown[2]['message'], suppression.MODULE_WARNING_MSG)
 
504
        self.assertEqual(len(warningsShown), 3)
 
505
 
 
506
 
 
507
 
 
508
class GCMixin:
 
509
    """
 
510
    I provide a few mock tests that log setUp, tearDown, test execution and
 
511
    garbage collection. I'm used to test whether gc.collect gets called.
 
512
    """
 
513
 
 
514
    class BasicTest(unittest.TestCase):
 
515
        def setUp(self):
 
516
            self._log('setUp')
 
517
        def test_foo(self):
 
518
            self._log('test')
 
519
        def tearDown(self):
 
520
            self._log('tearDown')
 
521
 
 
522
    class ClassTest(unittest.TestCase):
 
523
        def test_1(self):
 
524
            self._log('test1')
 
525
        def test_2(self):
 
526
            self._log('test2')
 
527
 
 
528
    def _log(self, msg):
 
529
        self._collectCalled.append(msg)
 
530
 
 
531
    def collect(self):
 
532
        """Fake gc.collect"""
 
533
        self._log('collect')
 
534
 
 
535
    def setUp(self):
 
536
        self._collectCalled = []
 
537
        self.BasicTest._log = self.ClassTest._log = self._log
 
538
        self._oldCollect = gc.collect
 
539
        gc.collect = self.collect
 
540
 
 
541
    def tearDown(self):
 
542
        gc.collect = self._oldCollect
 
543
 
 
544
 
 
545
 
 
546
class TestGarbageCollectionDefault(GCMixin, unittest.TestCase):
 
547
 
 
548
    def test_collectNotDefault(self):
 
549
        """
 
550
        By default, tests should not force garbage collection.
 
551
        """
 
552
        test = self.BasicTest('test_foo')
 
553
        result = reporter.TestResult()
 
554
        test.run(result)
 
555
        self.failUnlessEqual(self._collectCalled, ['setUp', 'test', 'tearDown'])
 
556
 
 
557
 
 
558
 
 
559
class TestGarbageCollection(GCMixin, unittest.TestCase):
 
560
 
 
561
    def test_collectCalled(self):
 
562
        """
 
563
        test gc.collect is called before and after each test.
 
564
        """
 
565
        test = TestGarbageCollection.BasicTest('test_foo')
 
566
        test = unittest._ForceGarbageCollectionDecorator(test)
 
567
        result = reporter.TestResult()
 
568
        test.run(result)
 
569
        self.failUnlessEqual(
 
570
            self._collectCalled,
 
571
            ['collect', 'setUp', 'test', 'tearDown', 'collect'])
 
572
 
 
573
 
 
574
 
 
575
class TestUnhandledDeferred(unittest.TestCase):
 
576
 
 
577
    def setUp(self):
 
578
        from twisted.trial.test import weird
 
579
        # test_unhandledDeferred creates a cycle. we need explicit control of gc
 
580
        gc.disable()
 
581
        self.test1 = unittest._ForceGarbageCollectionDecorator(
 
582
            weird.TestBleeding('test_unhandledDeferred'))
 
583
 
 
584
    def test_isReported(self):
 
585
        """
 
586
        Forcing garbage collection should cause unhandled Deferreds to be
 
587
        reported as errors.
 
588
        """
 
589
        result = reporter.TestResult()
 
590
        self.test1(result)
 
591
        self.assertEqual(len(result.errors), 1,
 
592
                         'Unhandled deferred passed without notice')
 
593
 
 
594
    def test_doesntBleed(self):
 
595
        """
 
596
        Forcing garbage collection in the test should mean that there are
 
597
        no unreachable cycles immediately after the test completes.
 
598
        """
 
599
        result = reporter.TestResult()
 
600
        self.test1(result)
 
601
        self.flushLoggedErrors() # test1 logs errors that get caught be us.
 
602
        # test1 created unreachable cycle.
 
603
        # it & all others should have been collected by now.
 
604
        n = gc.collect()
 
605
        self.assertEqual(n, 0, 'unreachable cycle still existed')
 
606
        # check that last gc.collect didn't log more errors
 
607
        x = self.flushLoggedErrors()
 
608
        self.assertEqual(len(x), 0, 'Errors logged after gc.collect')
 
609
 
 
610
    def tearDown(self):
 
611
        gc.collect()
 
612
        gc.enable()
 
613
        self.flushLoggedErrors()
 
614
 
 
615
 
 
616
 
 
617
class TestAddCleanup(unittest.TestCase):
 
618
    """
 
619
    Test the addCleanup method of TestCase.
 
620
    """
 
621
 
 
622
    class MockTest(unittest.TestCase):
 
623
 
 
624
        def setUp(self):
 
625
            self.log = ['setUp']
 
626
 
 
627
        def brokenSetUp(self):
 
628
            self.log = ['setUp']
 
629
            raise RuntimeError("Deliberate failure")
 
630
 
 
631
        def skippingSetUp(self):
 
632
            self.log = ['setUp']
 
633
            raise unittest.SkipTest("Don't do this")
 
634
 
 
635
        def append(self, thing):
 
636
            self.log.append(thing)
 
637
 
 
638
        def tearDown(self):
 
639
            self.log.append('tearDown')
 
640
 
 
641
        def runTest(self):
 
642
            self.log.append('runTest')
 
643
 
 
644
 
 
645
    def setUp(self):
 
646
        unittest.TestCase.setUp(self)
 
647
        self.result = reporter.TestResult()
 
648
        self.test = TestAddCleanup.MockTest()
 
649
 
 
650
 
 
651
    def test_addCleanupCalledIfSetUpFails(self):
 
652
        """
 
653
        Callables added with C{addCleanup} are run even if setUp fails.
 
654
        """
 
655
        self.test.setUp = self.test.brokenSetUp
 
656
        self.test.addCleanup(self.test.append, 'foo')
 
657
        self.test.run(self.result)
 
658
        self.assertEqual(['setUp', 'foo'], self.test.log)
 
659
 
 
660
 
 
661
    def test_addCleanupCalledIfSetUpSkips(self):
 
662
        """
 
663
        Callables added with C{addCleanup} are run even if setUp raises
 
664
        L{SkipTest}. This allows test authors to reliably provide clean up
 
665
        code using C{addCleanup}.
 
666
        """
 
667
        self.test.setUp = self.test.skippingSetUp
 
668
        self.test.addCleanup(self.test.append, 'foo')
 
669
        self.test.run(self.result)
 
670
        self.assertEqual(['setUp', 'foo'], self.test.log)
 
671
 
 
672
 
 
673
    def test_addCleanupCalledInReverseOrder(self):
 
674
        """
 
675
        Callables added with C{addCleanup} should be called before C{tearDown}
 
676
        in reverse order of addition.
 
677
        """
 
678
        self.test.addCleanup(self.test.append, "foo")
 
679
        self.test.addCleanup(self.test.append, 'bar')
 
680
        self.test.run(self.result)
 
681
        self.assertEqual(['setUp', 'runTest', 'bar', 'foo', 'tearDown'],
 
682
                         self.test.log)
 
683
 
 
684
 
 
685
    def test_addCleanupWaitsForDeferreds(self):
 
686
        """
 
687
        If an added callable returns a L{Deferred}, then the test should wait
 
688
        until that L{Deferred} has fired before running the next cleanup
 
689
        method.
 
690
        """
 
691
        def cleanup(message):
 
692
            d = defer.Deferred()
 
693
            reactor.callLater(0, d.callback, message)
 
694
            return d.addCallback(self.test.append)
 
695
        self.test.addCleanup(self.test.append, 'foo')
 
696
        self.test.addCleanup(cleanup, 'bar')
 
697
        self.test.run(self.result)
 
698
        self.assertEqual(['setUp', 'runTest', 'bar', 'foo', 'tearDown'],
 
699
                         self.test.log)
 
700
 
 
701
 
 
702
    def test_errorInCleanupIsCaptured(self):
 
703
        """
 
704
        Errors raised in cleanup functions should be treated like errors in
 
705
        C{tearDown}. They should be added as errors and fail the test. Skips,
 
706
        todos and failures are all treated as errors.
 
707
        """
 
708
        self.test.addCleanup(self.test.fail, 'foo')
 
709
        self.test.run(self.result)
 
710
        self.failIf(self.result.wasSuccessful())
 
711
        self.assertEqual(1, len(self.result.errors))
 
712
        [(test, error)] = self.result.errors
 
713
        self.assertEqual(test, self.test)
 
714
        self.assertEqual(error.getErrorMessage(), 'foo')
 
715
 
 
716
 
 
717
    def test_cleanupsContinueRunningAfterError(self):
 
718
        """
 
719
        If a cleanup raises an error then that does not stop the other
 
720
        cleanups from being run.
 
721
        """
 
722
        self.test.addCleanup(self.test.append, 'foo')
 
723
        self.test.addCleanup(self.test.fail, 'bar')
 
724
        self.test.run(self.result)
 
725
        self.assertEqual(['setUp', 'runTest', 'foo', 'tearDown'],
 
726
                         self.test.log)
 
727
        self.assertEqual(1, len(self.result.errors))
 
728
        [(test, error)] = self.result.errors
 
729
        self.assertEqual(test, self.test)
 
730
        self.assertEqual(error.getErrorMessage(), 'bar')
 
731
 
 
732
 
 
733
    def test_multipleErrorsReported(self):
 
734
        """
 
735
        If more than one cleanup fails, then the test should fail with more
 
736
        than one error.
 
737
        """
 
738
        self.test.addCleanup(self.test.fail, 'foo')
 
739
        self.test.addCleanup(self.test.fail, 'bar')
 
740
        self.test.run(self.result)
 
741
        self.assertEqual(['setUp', 'runTest', 'tearDown'],
 
742
                         self.test.log)
 
743
        self.assertEqual(2, len(self.result.errors))
 
744
        [(test1, error1), (test2, error2)] = self.result.errors
 
745
        self.assertEqual(test1, self.test)
 
746
        self.assertEqual(test2, self.test)
 
747
        self.assertEqual(error1.getErrorMessage(), 'bar')
 
748
        self.assertEqual(error2.getErrorMessage(), 'foo')
 
749
 
 
750
 
 
751
 
 
752
class TestSuiteClearing(unittest.TestCase):
 
753
    """
 
754
    Tests for our extension that allows us to clear out a L{TestSuite}.
 
755
    """
 
756
 
 
757
 
 
758
    def test_clearSuite(self):
 
759
        """
 
760
        Calling L{unittest._clearSuite} on a populated L{TestSuite} removes
 
761
        all tests.
 
762
        """
 
763
        suite = unittest.TestSuite()
 
764
        suite.addTest(unittest.TestCase())
 
765
        # Double check that the test suite actually has something in it.
 
766
        self.assertEqual(1, suite.countTestCases())
 
767
        unittest._clearSuite(suite)
 
768
        self.assertEqual(0, suite.countTestCases())
 
769
 
 
770
 
 
771
    def test_clearPyunitSuite(self):
 
772
        """
 
773
        Calling L{unittest._clearSuite} on a populated standard library
 
774
        L{TestSuite} removes all tests.
 
775
 
 
776
        This test is important since C{_clearSuite} operates by mutating
 
777
        internal variables.
 
778
        """
 
779
        pyunit = __import__('unittest')
 
780
        suite = pyunit.TestSuite()
 
781
        suite.addTest(unittest.TestCase())
 
782
        # Double check that the test suite actually has something in it.
 
783
        self.assertEqual(1, suite.countTestCases())
 
784
        unittest._clearSuite(suite)
 
785
        self.assertEqual(0, suite.countTestCases())
 
786
 
 
787
 
 
788
 
 
789
class TestTestDecorator(unittest.TestCase):
 
790
    """
 
791
    Tests for our test decoration features.
 
792
    """
 
793
 
 
794
 
 
795
    def assertTestsEqual(self, observed, expected):
 
796
        """
 
797
        Assert that the given decorated tests are equal.
 
798
        """
 
799
        self.assertEqual(observed.__class__, expected.__class__,
 
800
                         "Different class")
 
801
        observedOriginal = getattr(observed, '_originalTest', None)
 
802
        expectedOriginal = getattr(expected, '_originalTest', None)
 
803
        self.assertIdentical(observedOriginal, expectedOriginal)
 
804
        if observedOriginal is expectedOriginal is None:
 
805
            self.assertIdentical(observed, expected)
 
806
 
 
807
 
 
808
    def assertSuitesEqual(self, observed, expected):
 
809
        """
 
810
        Assert that the given test suites with decorated tests are equal.
 
811
        """
 
812
        self.assertEqual(observed.__class__, expected.__class__,
 
813
                         "Different class")
 
814
        self.assertEqual(len(observed._tests), len(expected._tests),
 
815
                         "Different number of tests.")
 
816
        for observedTest, expectedTest in zip(observed._tests,
 
817
                                              expected._tests):
 
818
            if getattr(observedTest, '_tests', None) is not None:
 
819
                self.assertSuitesEqual(observedTest, expectedTest)
 
820
            else:
 
821
                self.assertTestsEqual(observedTest, expectedTest)
 
822
 
 
823
 
 
824
    def test_usesAdaptedReporterWithRun(self):
 
825
        """
 
826
        For decorated tests, C{run} uses a result adapter that preserves the
 
827
        test decoration for calls to C{addError}, C{startTest} and the like.
 
828
 
 
829
        See L{reporter._AdaptedReporter}.
 
830
        """
 
831
        test = unittest.TestCase()
 
832
        decoratedTest = unittest.TestDecorator(test)
 
833
        result = LoggingReporter()
 
834
        decoratedTest.run(result)
 
835
        self.assertTestsEqual(result.test, decoratedTest)
 
836
 
 
837
 
 
838
    def test_usesAdaptedReporterWithCall(self):
 
839
        """
 
840
        For decorated tests, C{__call__} uses a result adapter that preserves
 
841
        the test decoration for calls to C{addError}, C{startTest} and the
 
842
        like.
 
843
 
 
844
        See L{reporter._AdaptedReporter}.
 
845
        """
 
846
        test = unittest.TestCase()
 
847
        decoratedTest = unittest.TestDecorator(test)
 
848
        result = LoggingReporter()
 
849
        decoratedTest(result)
 
850
        self.assertTestsEqual(result.test, decoratedTest)
 
851
 
 
852
 
 
853
    def test_decorateSingleTest(self):
 
854
        """
 
855
        Calling L{decorate} on a single test case returns the test case
 
856
        decorated with the provided decorator.
 
857
        """
 
858
        test = unittest.TestCase()
 
859
        decoratedTest = unittest.decorate(test, unittest.TestDecorator)
 
860
        self.assertTestsEqual(unittest.TestDecorator(test), decoratedTest)
 
861
 
 
862
 
 
863
    def test_decorateTestSuite(self):
 
864
        """
 
865
        Calling L{decorate} on a test suite will return a test suite with
 
866
        each test decorated with the provided decorator.
 
867
        """
 
868
        test = unittest.TestCase()
 
869
        suite = unittest.TestSuite([test])
 
870
        decoratedTest = unittest.decorate(suite, unittest.TestDecorator)
 
871
        self.assertSuitesEqual(
 
872
            decoratedTest, unittest.TestSuite([unittest.TestDecorator(test)]))
 
873
 
 
874
 
 
875
    def test_decorateInPlaceMutatesOriginal(self):
 
876
        """
 
877
        Calling L{decorate} on a test suite will mutate the original suite.
 
878
        """
 
879
        test = unittest.TestCase()
 
880
        suite = unittest.TestSuite([test])
 
881
        decoratedTest = unittest.decorate(
 
882
            suite, unittest.TestDecorator)
 
883
        self.assertSuitesEqual(
 
884
            decoratedTest, unittest.TestSuite([unittest.TestDecorator(test)]))
 
885
        self.assertSuitesEqual(
 
886
            suite, unittest.TestSuite([unittest.TestDecorator(test)]))
 
887
 
 
888
 
 
889
    def test_decorateTestSuiteReferences(self):
 
890
        """
 
891
        When decorating a test suite in-place, the number of references to the
 
892
        test objects in that test suite should stay the same.
 
893
 
 
894
        Previously, L{unittest.decorate} recreated a test suite, so the
 
895
        original suite kept references to the test objects. This test is here
 
896
        to ensure the problem doesn't reappear again.
 
897
        """
 
898
        getrefcount = getattr(sys, 'getrefcount', None)
 
899
        if getrefcount is None:
 
900
            raise unittest.SkipTest(
 
901
                "getrefcount not supported on this platform")
 
902
        test = unittest.TestCase()
 
903
        suite = unittest.TestSuite([test])
 
904
        count1 = getrefcount(test)
 
905
        decoratedTest = unittest.decorate(suite, unittest.TestDecorator)
 
906
        count2 = getrefcount(test)
 
907
        self.assertEquals(count1, count2)
 
908
 
 
909
 
 
910
    def test_decorateNestedTestSuite(self):
 
911
        """
 
912
        Calling L{decorate} on a test suite with nested suites will return a
 
913
        test suite that maintains the same structure, but with all tests
 
914
        decorated.
 
915
        """
 
916
        test = unittest.TestCase()
 
917
        suite = unittest.TestSuite([unittest.TestSuite([test])])
 
918
        decoratedTest = unittest.decorate(suite, unittest.TestDecorator)
 
919
        expected = unittest.TestSuite(
 
920
            [unittest.TestSuite([unittest.TestDecorator(test)])])
 
921
        self.assertSuitesEqual(decoratedTest, expected)
 
922
 
 
923
 
 
924
    def test_decorateDecoratedSuite(self):
 
925
        """
 
926
        Calling L{decorate} on a test suite with already-decorated tests
 
927
        decorates all of the tests in the suite again.
 
928
        """
 
929
        test = unittest.TestCase()
 
930
        decoratedTest = unittest.decorate(test, unittest.TestDecorator)
 
931
        redecoratedTest = unittest.decorate(decoratedTest,
 
932
                                            unittest.TestDecorator)
 
933
        self.assertTestsEqual(redecoratedTest,
 
934
                              unittest.TestDecorator(decoratedTest))
 
935
 
 
936
 
 
937
    def test_decoratePreservesSuite(self):
 
938
        """
 
939
        Tests can be in non-standard suites. L{decorate} preserves the
 
940
        non-standard suites when it decorates the tests.
 
941
        """
 
942
        test = unittest.TestCase()
 
943
        suite = runner.DestructiveTestSuite([test])
 
944
        decorated = unittest.decorate(suite, unittest.TestDecorator)
 
945
        self.assertSuitesEqual(
 
946
            decorated,
 
947
            runner.DestructiveTestSuite([unittest.TestDecorator(test)]))
 
948
 
 
949
 
 
950
class TestMonkeyPatchSupport(unittest.TestCase):
 
951
    """
 
952
    Tests for the patch() helper method in L{unittest.TestCase}.
 
953
    """
 
954
 
 
955
 
 
956
    def setUp(self):
 
957
        self.originalValue = 'original'
 
958
        self.patchedValue = 'patched'
 
959
        self.objectToPatch = self.originalValue
 
960
        self.test = unittest.TestCase()
 
961
 
 
962
 
 
963
    def test_patch(self):
 
964
        """
 
965
        Calling C{patch()} on a test monkey patches the specified object and
 
966
        attribute.
 
967
        """
 
968
        self.test.patch(self, 'objectToPatch', self.patchedValue)
 
969
        self.assertEqual(self.objectToPatch, self.patchedValue)
 
970
 
 
971
 
 
972
    def test_patchRestoredAfterRun(self):
 
973
        """
 
974
        Any monkey patches introduced by a test using C{patch()} are reverted
 
975
        after the test has run.
 
976
        """
 
977
        self.test.patch(self, 'objectToPatch', self.patchedValue)
 
978
        self.test.run(reporter.Reporter())
 
979
        self.assertEqual(self.objectToPatch, self.originalValue)
 
980
 
 
981
 
 
982
    def test_revertDuringTest(self):
 
983
        """
 
984
        C{patch()} return a L{monkey.MonkeyPatcher} object that can be used to
 
985
        restore the original values before the end of the test.
 
986
        """
 
987
        patch = self.test.patch(self, 'objectToPatch', self.patchedValue)
 
988
        patch.restore()
 
989
        self.assertEqual(self.objectToPatch, self.originalValue)
 
990
 
 
991
 
 
992
    def test_revertAndRepatch(self):
 
993
        """
 
994
        The returned L{monkey.MonkeyPatcher} object can re-apply the patch
 
995
        during the test run.
 
996
        """
 
997
        patch = self.test.patch(self, 'objectToPatch', self.patchedValue)
 
998
        patch.restore()
 
999
        patch.patch()
 
1000
        self.assertEqual(self.objectToPatch, self.patchedValue)
 
1001
 
 
1002
 
 
1003
    def test_successivePatches(self):
 
1004
        """
 
1005
        Successive patches are applied and reverted just like a single patch.
 
1006
        """
 
1007
        self.test.patch(self, 'objectToPatch', self.patchedValue)
 
1008
        self.assertEqual(self.objectToPatch, self.patchedValue)
 
1009
        self.test.patch(self, 'objectToPatch', 'second value')
 
1010
        self.assertEqual(self.objectToPatch, 'second value')
 
1011
        self.test.run(reporter.Reporter())
 
1012
        self.assertEqual(self.objectToPatch, self.originalValue)
 
1013
 
 
1014
 
 
1015
 
 
1016
class TestIterateTests(unittest.TestCase):
 
1017
    """
 
1018
    L{_iterateTests} returns a list of all test cases in a test suite or test
 
1019
    case.
 
1020
    """
 
1021
 
 
1022
    def test_iterateTestCase(self):
 
1023
        """
 
1024
        L{_iterateTests} on a single test case returns a list containing that
 
1025
        test case.
 
1026
        """
 
1027
        test = unittest.TestCase()
 
1028
        self.assertEqual([test], list(unittest._iterateTests(test)))
 
1029
 
 
1030
 
 
1031
    def test_iterateSingletonTestSuite(self):
 
1032
        """
 
1033
        L{_iterateTests} on a test suite that contains a single test case
 
1034
        returns a list containing that test case.
 
1035
        """
 
1036
        test = unittest.TestCase()
 
1037
        suite = runner.TestSuite([test])
 
1038
        self.assertEqual([test], list(unittest._iterateTests(suite)))
 
1039
 
 
1040
 
 
1041
    def test_iterateNestedTestSuite(self):
 
1042
        """
 
1043
        L{_iterateTests} returns tests that are in nested test suites.
 
1044
        """
 
1045
        test = unittest.TestCase()
 
1046
        suite = runner.TestSuite([runner.TestSuite([test])])
 
1047
        self.assertEqual([test], list(unittest._iterateTests(suite)))
 
1048
 
 
1049
 
 
1050
    def test_iterateIsLeftToRightDepthFirst(self):
 
1051
        """
 
1052
        L{_iterateTests} returns tests in left-to-right, depth-first order.
 
1053
        """
 
1054
        test = unittest.TestCase()
 
1055
        suite = runner.TestSuite([runner.TestSuite([test]), self])
 
1056
        self.assertEqual([test, self], list(unittest._iterateTests(suite)))