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