1import sys
2import textwrap
3from StringIO import StringIO
4
5import unittest2
6
7
8class Test_TestResult(unittest2.TestCase):
9    # Note: there are not separate tests for TestResult.wasSuccessful(),
10    # TestResult.errors, TestResult.failures, TestResult.testsRun or
11    # TestResult.shouldStop because these only have meaning in terms of
12    # other TestResult methods.
13    #
14    # Accordingly, tests for the aforenamed attributes are incorporated
15    # in with the tests for the defining methods.
16    ################################################################
17
18    def test_init(self):
19        result = unittest2.TestResult()
20
21        self.assertTrue(result.wasSuccessful())
22        self.assertEqual(len(result.errors), 0)
23        self.assertEqual(len(result.failures), 0)
24        self.assertEqual(result.testsRun, 0)
25        self.assertEqual(result.shouldStop, False)
26        self.assertIsNone(result._stdout_buffer)
27        self.assertIsNone(result._stderr_buffer)
28
29    # "This method can be called to signal that the set of tests being
30    # run should be aborted by setting the TestResult's shouldStop
31    # attribute to True."
32    def test_stop(self):
33        result = unittest2.TestResult()
34
35        result.stop()
36
37        self.assertEqual(result.shouldStop, True)
38
39    # "Called when the test case test is about to be run. The default
40    # implementation simply increments the instance's testsRun counter."
41    def test_startTest(self):
42        class Foo(unittest2.TestCase):
43            def test_1(self):
44                pass
45
46        test = Foo('test_1')
47
48        result = unittest2.TestResult()
49
50        result.startTest(test)
51
52        self.assertTrue(result.wasSuccessful())
53        self.assertEqual(len(result.errors), 0)
54        self.assertEqual(len(result.failures), 0)
55        self.assertEqual(result.testsRun, 1)
56        self.assertEqual(result.shouldStop, False)
57
58        result.stopTest(test)
59
60    # "Called after the test case test has been executed, regardless of
61    # the outcome. The default implementation does nothing."
62    def test_stopTest(self):
63        class Foo(unittest2.TestCase):
64            def test_1(self):
65                pass
66
67        test = Foo('test_1')
68
69        result = unittest2.TestResult()
70
71        result.startTest(test)
72
73        self.assertTrue(result.wasSuccessful())
74        self.assertEqual(len(result.errors), 0)
75        self.assertEqual(len(result.failures), 0)
76        self.assertEqual(result.testsRun, 1)
77        self.assertEqual(result.shouldStop, False)
78
79        result.stopTest(test)
80
81        # Same tests as above; make sure nothing has changed
82        self.assertTrue(result.wasSuccessful())
83        self.assertEqual(len(result.errors), 0)
84        self.assertEqual(len(result.failures), 0)
85        self.assertEqual(result.testsRun, 1)
86        self.assertEqual(result.shouldStop, False)
87
88    # "Called before and after tests are run. The default implementation does nothing."
89    def test_startTestRun_stopTestRun(self):
90        result = unittest2.TestResult()
91        result.startTestRun()
92        result.stopTestRun()
93
94    # "addSuccess(test)"
95    # ...
96    # "Called when the test case test succeeds"
97    # ...
98    # "wasSuccessful() - Returns True if all tests run so far have passed,
99    # otherwise returns False"
100    # ...
101    # "testsRun - The total number of tests run so far."
102    # ...
103    # "errors - A list containing 2-tuples of TestCase instances and
104    # formatted tracebacks. Each tuple represents a test which raised an
105    # unexpected exception. Contains formatted
106    # tracebacks instead of sys.exc_info() results."
107    # ...
108    # "failures - A list containing 2-tuples of TestCase instances and
109    # formatted tracebacks. Each tuple represents a test where a failure was
110    # explicitly signalled using the TestCase.fail*() or TestCase.assert*()
111    # methods. Contains formatted tracebacks instead
112    # of sys.exc_info() results."
113    def test_addSuccess(self):
114        class Foo(unittest2.TestCase):
115            def test_1(self):
116                pass
117
118        test = Foo('test_1')
119
120        result = unittest2.TestResult()
121
122        result.startTest(test)
123        result.addSuccess(test)
124        result.stopTest(test)
125
126        self.assertTrue(result.wasSuccessful())
127        self.assertEqual(len(result.errors), 0)
128        self.assertEqual(len(result.failures), 0)
129        self.assertEqual(result.testsRun, 1)
130        self.assertEqual(result.shouldStop, False)
131
132    # "addFailure(test, err)"
133    # ...
134    # "Called when the test case test signals a failure. err is a tuple of
135    # the form returned by sys.exc_info(): (type, value, traceback)"
136    # ...
137    # "wasSuccessful() - Returns True if all tests run so far have passed,
138    # otherwise returns False"
139    # ...
140    # "testsRun - The total number of tests run so far."
141    # ...
142    # "errors - A list containing 2-tuples of TestCase instances and
143    # formatted tracebacks. Each tuple represents a test which raised an
144    # unexpected exception. Contains formatted
145    # tracebacks instead of sys.exc_info() results."
146    # ...
147    # "failures - A list containing 2-tuples of TestCase instances and
148    # formatted tracebacks. Each tuple represents a test where a failure was
149    # explicitly signalled using the TestCase.fail*() or TestCase.assert*()
150    # methods. Contains formatted tracebacks instead
151    # of sys.exc_info() results."
152    def test_addFailure(self):
153        class Foo(unittest2.TestCase):
154            def test_1(self):
155                pass
156
157        test = Foo('test_1')
158        try:
159            test.fail("foo")
160        except:
161            exc_info_tuple = sys.exc_info()
162
163        result = unittest2.TestResult()
164
165        result.startTest(test)
166        result.addFailure(test, exc_info_tuple)
167        result.stopTest(test)
168
169        self.assertFalse(result.wasSuccessful())
170        self.assertEqual(len(result.errors), 0)
171        self.assertEqual(len(result.failures), 1)
172        self.assertEqual(result.testsRun, 1)
173        self.assertEqual(result.shouldStop, False)
174
175        test_case, formatted_exc = result.failures[0]
176        self.assertTrue(test_case is test)
177        self.assertIsInstance(formatted_exc, str)
178
179    # "addError(test, err)"
180    # ...
181    # "Called when the test case test raises an unexpected exception err
182    # is a tuple of the form returned by sys.exc_info():
183    # (type, value, traceback)"
184    # ...
185    # "wasSuccessful() - Returns True if all tests run so far have passed,
186    # otherwise returns False"
187    # ...
188    # "testsRun - The total number of tests run so far."
189    # ...
190    # "errors - A list containing 2-tuples of TestCase instances and
191    # formatted tracebacks. Each tuple represents a test which raised an
192    # unexpected exception. Contains formatted
193    # tracebacks instead of sys.exc_info() results."
194    # ...
195    # "failures - A list containing 2-tuples of TestCase instances and
196    # formatted tracebacks. Each tuple represents a test where a failure was
197    # explicitly signalled using the TestCase.fail*() or TestCase.assert*()
198    # methods. Contains formatted tracebacks instead
199    # of sys.exc_info() results."
200    def test_addError(self):
201        class Foo(unittest2.TestCase):
202            def test_1(self):
203                pass
204
205        test = Foo('test_1')
206        try:
207            raise TypeError()
208        except:
209            exc_info_tuple = sys.exc_info()
210
211        result = unittest2.TestResult()
212
213        result.startTest(test)
214        result.addError(test, exc_info_tuple)
215        result.stopTest(test)
216
217        self.assertFalse(result.wasSuccessful())
218        self.assertEqual(len(result.errors), 1)
219        self.assertEqual(len(result.failures), 0)
220        self.assertEqual(result.testsRun, 1)
221        self.assertEqual(result.shouldStop, False)
222
223        test_case, formatted_exc = result.errors[0]
224        self.assertTrue(test_case is test)
225        self.assertIsInstance(formatted_exc, str)
226
227    def testGetDescriptionWithoutDocstring(self):
228        result = unittest2.TextTestResult(None, True, 1)
229        self.assertEqual(
230                result.getDescription(self),
231                'testGetDescriptionWithoutDocstring (' + __name__ +
232                '.Test_TestResult)')
233
234    def testGetDescriptionWithOneLineDocstring(self):
235        """Tests getDescription() for a method with a docstring."""
236        result = unittest2.TextTestResult(None, True, 1)
237        self.assertEqual(
238                result.getDescription(self),
239               ('testGetDescriptionWithOneLineDocstring '
240                '(' + __name__ + '.Test_TestResult)\n'
241                'Tests getDescription() for a method with a docstring.'))
242
243    def testGetDescriptionWithMultiLineDocstring(self):
244        """Tests getDescription() for a method with a longer docstring.
245        The second line of the docstring.
246        """
247        result = unittest2.TextTestResult(None, True, 1)
248        self.assertEqual(
249                result.getDescription(self),
250               ('testGetDescriptionWithMultiLineDocstring '
251                '(' + __name__ + '.Test_TestResult)\n'
252                'Tests getDescription() for a method with a longer '
253                'docstring.'))
254
255    def testStackFrameTrimming(self):
256        class Frame(object):
257            class tb_frame(object):
258                f_globals = {}
259        result = unittest2.TestResult()
260        self.assertFalse(result._is_relevant_tb_level(Frame))
261
262        Frame.tb_frame.f_globals['__unittest'] = True
263        self.assertTrue(result._is_relevant_tb_level(Frame))
264
265    def testFailFast(self):
266        result = unittest2.TestResult()
267        result._exc_info_to_string = lambda *_: ''
268        result.failfast = True
269        result.addError(None, None)
270        self.assertTrue(result.shouldStop)
271
272        result = unittest2.TestResult()
273        result._exc_info_to_string = lambda *_: ''
274        result.failfast = True
275        result.addFailure(None, None)
276        self.assertTrue(result.shouldStop)
277
278        result = unittest2.TestResult()
279        result._exc_info_to_string = lambda *_: ''
280        result.failfast = True
281        result.addUnexpectedSuccess(None)
282        self.assertTrue(result.shouldStop)
283
284    def testFailFastSetByRunner(self):
285        runner = unittest2.TextTestRunner(stream=StringIO(), failfast=True)
286        self.testRan = False
287        def test(result):
288            self.testRan = True
289            self.assertTrue(result.failfast)
290        runner.run(test)
291        self.assertTrue(self.testRan)
292
293
294class TestOutputBuffering(unittest2.TestCase):
295
296    def setUp(self):
297        self._real_out = sys.stdout
298        self._real_err = sys.stderr
299
300    def tearDown(self):
301        sys.stdout = self._real_out
302        sys.stderr = self._real_err
303
304    def testBufferOutputOff(self):
305        real_out = self._real_out
306        real_err = self._real_err
307
308        result = unittest2.TestResult()
309        self.assertFalse(result.buffer)
310
311        self.assertIs(real_out, sys.stdout)
312        self.assertIs(real_err, sys.stderr)
313
314        result.startTest(self)
315
316        self.assertIs(real_out, sys.stdout)
317        self.assertIs(real_err, sys.stderr)
318
319    def testBufferOutputStartTestAddSuccess(self):
320        real_out = self._real_out
321        real_err = self._real_err
322
323        result = unittest2.TestResult()
324        self.assertFalse(result.buffer)
325
326        result.buffer = True
327
328        self.assertIs(real_out, sys.stdout)
329        self.assertIs(real_err, sys.stderr)
330
331        result.startTest(self)
332
333        self.assertIsNot(real_out, sys.stdout)
334        self.assertIsNot(real_err, sys.stderr)
335        self.assertIsInstance(sys.stdout, StringIO)
336        self.assertIsInstance(sys.stderr, StringIO)
337        self.assertIsNot(sys.stdout, sys.stderr)
338
339        out_stream = sys.stdout
340        err_stream = sys.stderr
341
342        result._original_stdout = StringIO()
343        result._original_stderr = StringIO()
344
345        print 'foo'
346        print >> sys.stderr, 'bar'
347
348        self.assertEqual(out_stream.getvalue(), 'foo\n')
349        self.assertEqual(err_stream.getvalue(), 'bar\n')
350
351        self.assertEqual(result._original_stdout.getvalue(), '')
352        self.assertEqual(result._original_stderr.getvalue(), '')
353
354        result.addSuccess(self)
355        result.stopTest(self)
356
357        self.assertIs(sys.stdout, result._original_stdout)
358        self.assertIs(sys.stderr, result._original_stderr)
359
360        self.assertEqual(result._original_stdout.getvalue(), '')
361        self.assertEqual(result._original_stderr.getvalue(), '')
362
363        self.assertEqual(out_stream.getvalue(), '')
364        self.assertEqual(err_stream.getvalue(), '')
365
366
367    def getStartedResult(self):
368        result = unittest2.TestResult()
369        result.buffer = True
370        result.startTest(self)
371        return result
372
373    def testBufferOutputAddErrorOrFailure(self):
374        for message_attr, add_attr, include_error in [
375            ('errors', 'addError', True),
376            ('failures', 'addFailure', False),
377            ('errors', 'addError', True),
378            ('failures', 'addFailure', False)
379        ]:
380            result = self.getStartedResult()
381            result._original_stderr = StringIO()
382            result._original_stdout = StringIO()
383
384            print >> sys.stdout, 'foo'
385            if include_error:
386                print >> sys.stderr, 'bar'
387
388            addFunction = getattr(result, add_attr)
389            addFunction(self, (None, None, None))
390            result.stopTest(self)
391
392            result_list = getattr(result, message_attr)
393            self.assertEqual(len(result_list), 1)
394
395            test, message = result_list[0]
396            expectedOutMessage = textwrap.dedent("""
397                Stdout:
398                foo
399            """)
400            expectedErrMessage = ''
401            if include_error:
402                expectedErrMessage = textwrap.dedent("""
403                Stderr:
404                bar
405            """)
406            expectedFullMessage = 'None\n%s%s' % (expectedOutMessage, expectedErrMessage)
407
408            self.assertIs(test, self)
409            self.assertEqual(result._original_stdout.getvalue(), expectedOutMessage)
410            self.assertEqual(result._original_stderr.getvalue(), expectedErrMessage)
411            self.assertMultiLineEqual(message, expectedFullMessage)
412
413
414
415if __name__ == '__main__':
416    unittest2.main()
417