blob: 7c0bd51d7985cb40303c831af9e0f816999aa01b [file] [log] [blame]
Michael Foord2560e5c2010-03-27 12:34:21 +00001import io
Ezio Melotti60901872010-12-01 00:56:10 +00002import os
3import sys
Michael Foord2560e5c2010-03-27 12:34:21 +00004import pickle
Ezio Melotti60901872010-12-01 00:56:10 +00005import subprocess
Michael Foord2560e5c2010-03-27 12:34:21 +00006
7import unittest
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +01008from unittest.case import _Outcome
Michael Foord2560e5c2010-03-27 12:34:21 +00009
Ezio Melotti1241c472014-08-07 03:20:22 +030010from unittest.test.support import (LoggingResult,
11 ResultWithNoStartTestRunStopTestRun)
Michael Foord2560e5c2010-03-27 12:34:21 +000012
13
14class TestCleanUp(unittest.TestCase):
15
16 def testCleanUp(self):
17 class TestableTest(unittest.TestCase):
18 def testNothing(self):
19 pass
20
21 test = TestableTest('testNothing')
22 self.assertEqual(test._cleanups, [])
23
24 cleanups = []
25
26 def cleanup1(*args, **kwargs):
27 cleanups.append((1, args, kwargs))
28
29 def cleanup2(*args, **kwargs):
30 cleanups.append((2, args, kwargs))
31
32 test.addCleanup(cleanup1, 1, 2, 3, four='hello', five='goodbye')
33 test.addCleanup(cleanup2)
34
35 self.assertEqual(test._cleanups,
36 [(cleanup1, (1, 2, 3), dict(four='hello', five='goodbye')),
37 (cleanup2, (), {})])
38
Michael Foordb3468f72010-12-19 03:19:47 +000039 self.assertTrue(test.doCleanups())
Michael Foord2560e5c2010-03-27 12:34:21 +000040 self.assertEqual(cleanups, [(2, (), {}), (1, (1, 2, 3), dict(four='hello', five='goodbye'))])
41
42 def testCleanUpWithErrors(self):
43 class TestableTest(unittest.TestCase):
44 def testNothing(self):
45 pass
46
Michael Foord2560e5c2010-03-27 12:34:21 +000047 test = TestableTest('testNothing')
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010048 outcome = test._outcome = _Outcome()
Michael Foord2560e5c2010-03-27 12:34:21 +000049
50 exc1 = Exception('foo')
51 exc2 = Exception('bar')
52 def cleanup1():
53 raise exc1
54
55 def cleanup2():
56 raise exc2
57
58 test.addCleanup(cleanup1)
59 test.addCleanup(cleanup2)
60
61 self.assertFalse(test.doCleanups())
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010062 self.assertFalse(outcome.success)
Michael Foord2560e5c2010-03-27 12:34:21 +000063
Antoine Pitrouc9b3ef22013-03-20 20:16:47 +010064 ((_, (Type1, instance1, _)),
65 (_, (Type2, instance2, _))) = reversed(outcome.errors)
Michael Foordb3468f72010-12-19 03:19:47 +000066 self.assertEqual((Type1, instance1), (Exception, exc1))
67 self.assertEqual((Type2, instance2), (Exception, exc2))
Michael Foord2560e5c2010-03-27 12:34:21 +000068
69 def testCleanupInRun(self):
70 blowUp = False
71 ordering = []
72
73 class TestableTest(unittest.TestCase):
74 def setUp(self):
75 ordering.append('setUp')
76 if blowUp:
77 raise Exception('foo')
78
79 def testNothing(self):
80 ordering.append('test')
81
82 def tearDown(self):
83 ordering.append('tearDown')
84
85 test = TestableTest('testNothing')
86
87 def cleanup1():
88 ordering.append('cleanup1')
89 def cleanup2():
90 ordering.append('cleanup2')
91 test.addCleanup(cleanup1)
92 test.addCleanup(cleanup2)
93
94 def success(some_test):
95 self.assertEqual(some_test, test)
96 ordering.append('success')
97
98 result = unittest.TestResult()
99 result.addSuccess = success
100
101 test.run(result)
102 self.assertEqual(ordering, ['setUp', 'test', 'tearDown',
103 'cleanup2', 'cleanup1', 'success'])
104
105 blowUp = True
106 ordering = []
107 test = TestableTest('testNothing')
108 test.addCleanup(cleanup1)
109 test.run(result)
110 self.assertEqual(ordering, ['setUp', 'cleanup1'])
111
Michael Foordb8748742010-06-10 16:16:08 +0000112 def testTestCaseDebugExecutesCleanups(self):
113 ordering = []
114
115 class TestableTest(unittest.TestCase):
116 def setUp(self):
117 ordering.append('setUp')
118 self.addCleanup(cleanup1)
119
120 def testNothing(self):
121 ordering.append('test')
122
123 def tearDown(self):
124 ordering.append('tearDown')
125
126 test = TestableTest('testNothing')
127
128 def cleanup1():
129 ordering.append('cleanup1')
130 test.addCleanup(cleanup2)
131 def cleanup2():
132 ordering.append('cleanup2')
133
134 test.debug()
135 self.assertEqual(ordering, ['setUp', 'test', 'tearDown', 'cleanup1', 'cleanup2'])
136
Michael Foord2560e5c2010-03-27 12:34:21 +0000137
138class Test_TextTestRunner(unittest.TestCase):
139 """Tests for TextTestRunner."""
140
Łukasz Langa6ae46672013-04-24 01:49:52 +0200141 def setUp(self):
142 # clean the environment from pre-existing PYTHONWARNINGS to make
143 # test_warnings results consistent
144 self.pythonwarnings = os.environ.get('PYTHONWARNINGS')
145 if self.pythonwarnings:
146 del os.environ['PYTHONWARNINGS']
147
148 def tearDown(self):
149 # bring back pre-existing PYTHONWARNINGS if present
150 if self.pythonwarnings:
151 os.environ['PYTHONWARNINGS'] = self.pythonwarnings
152
Michael Foord56fdb752010-05-07 16:00:30 +0000153 def test_init(self):
154 runner = unittest.TextTestRunner()
155 self.assertFalse(runner.failfast)
156 self.assertFalse(runner.buffer)
157 self.assertEqual(runner.verbosity, 1)
Ezio Melotti60901872010-12-01 00:56:10 +0000158 self.assertEqual(runner.warnings, None)
Michael Foord56fdb752010-05-07 16:00:30 +0000159 self.assertTrue(runner.descriptions)
160 self.assertEqual(runner.resultclass, unittest.TextTestResult)
161
162
Michael Foord7a1901f2012-09-28 14:14:03 +0100163 def test_multiple_inheritance(self):
164 class AResult(unittest.TestResult):
165 def __init__(self, stream, descriptions, verbosity):
166 super(AResult, self).__init__(stream, descriptions, verbosity)
167
168 class ATextResult(unittest.TextTestResult, AResult):
169 pass
170
171 # This used to raise an exception due to TextTestResult not passing
172 # on arguments in its __init__ super call
173 ATextResult(None, None, 1)
174
175
Michael Foord56fdb752010-05-07 16:00:30 +0000176 def testBufferAndFailfast(self):
177 class Test(unittest.TestCase):
178 def testFoo(self):
179 pass
180 result = unittest.TestResult()
181 runner = unittest.TextTestRunner(stream=io.StringIO(), failfast=True,
182 buffer=True)
183 # Use our result object
184 runner._makeResult = lambda: result
185 runner.run(Test('testFoo'))
186
187 self.assertTrue(result.failfast)
188 self.assertTrue(result.buffer)
189
190 def testRunnerRegistersResult(self):
191 class Test(unittest.TestCase):
192 def testFoo(self):
193 pass
194 originalRegisterResult = unittest.runner.registerResult
195 def cleanup():
196 unittest.runner.registerResult = originalRegisterResult
197 self.addCleanup(cleanup)
198
199 result = unittest.TestResult()
200 runner = unittest.TextTestRunner(stream=io.StringIO())
201 # Use our result object
202 runner._makeResult = lambda: result
203
204 self.wasRegistered = 0
205 def fakeRegisterResult(thisResult):
206 self.wasRegistered += 1
207 self.assertEqual(thisResult, result)
208 unittest.runner.registerResult = fakeRegisterResult
209
210 runner.run(unittest.TestSuite())
211 self.assertEqual(self.wasRegistered, 1)
212
Michael Foord2560e5c2010-03-27 12:34:21 +0000213 def test_works_with_result_without_startTestRun_stopTestRun(self):
214 class OldTextResult(ResultWithNoStartTestRunStopTestRun):
215 separator2 = ''
216 def printErrors(self):
217 pass
218
219 class Runner(unittest.TextTestRunner):
220 def __init__(self):
221 super(Runner, self).__init__(io.StringIO())
222
223 def _makeResult(self):
224 return OldTextResult()
225
226 runner = Runner()
227 runner.run(unittest.TestSuite())
228
229 def test_startTestRun_stopTestRun_called(self):
230 class LoggingTextResult(LoggingResult):
231 separator2 = ''
232 def printErrors(self):
233 pass
234
235 class LoggingRunner(unittest.TextTestRunner):
236 def __init__(self, events):
237 super(LoggingRunner, self).__init__(io.StringIO())
238 self._events = events
239
240 def _makeResult(self):
241 return LoggingTextResult(self._events)
242
243 events = []
244 runner = LoggingRunner(events)
245 runner.run(unittest.TestSuite())
246 expected = ['startTestRun', 'stopTestRun']
247 self.assertEqual(events, expected)
248
249 def test_pickle_unpickle(self):
250 # Issue #7197: a TextTestRunner should be (un)pickleable. This is
251 # required by test_multiprocessing under Windows (in verbose mode).
252 stream = io.StringIO("foo")
253 runner = unittest.TextTestRunner(stream)
254 for protocol in range(2, pickle.HIGHEST_PROTOCOL + 1):
255 s = pickle.dumps(runner, protocol)
256 obj = pickle.loads(s)
257 # StringIO objects never compare equal, a cheap test instead.
258 self.assertEqual(obj.stream.getvalue(), stream.getvalue())
259
260 def test_resultclass(self):
261 def MockResultClass(*args):
262 return args
263 STREAM = object()
264 DESCRIPTIONS = object()
265 VERBOSITY = object()
266 runner = unittest.TextTestRunner(STREAM, DESCRIPTIONS, VERBOSITY,
267 resultclass=MockResultClass)
268 self.assertEqual(runner.resultclass, MockResultClass)
269
270 expectedresult = (runner.stream, DESCRIPTIONS, VERBOSITY)
271 self.assertEqual(runner._makeResult(), expectedresult)
Ezio Melotti60901872010-12-01 00:56:10 +0000272
273 def test_warnings(self):
274 """
275 Check that warnings argument of TextTestRunner correctly affects the
276 behavior of the warnings.
277 """
278 # see #10535 and the _test_warnings file for more information
279
280 def get_parse_out_err(p):
281 return [b.splitlines() for b in p.communicate()]
282 opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE,
283 cwd=os.path.dirname(__file__))
284 ae_msg = b'Please use assertEqual instead.'
285 at_msg = b'Please use assertTrue instead.'
286
287 # no args -> all the warnings are printed, unittest warnings only once
288 p = subprocess.Popen([sys.executable, '_test_warnings.py'], **opts)
289 out, err = get_parse_out_err(p)
Ezio Melottif10c4002010-12-01 01:45:53 +0000290 self.assertIn(b'OK', err)
Ezio Melotti60901872010-12-01 00:56:10 +0000291 # check that the total number of warnings in the output is correct
292 self.assertEqual(len(out), 12)
293 # check that the numbers of the different kind of warnings is correct
294 for msg in [b'dw', b'iw', b'uw']:
295 self.assertEqual(out.count(msg), 3)
296 for msg in [ae_msg, at_msg, b'rw']:
297 self.assertEqual(out.count(msg), 1)
298
299 args_list = (
300 # passing 'ignore' as warnings arg -> no warnings
301 [sys.executable, '_test_warnings.py', 'ignore'],
302 # -W doesn't affect the result if the arg is passed
303 [sys.executable, '-Wa', '_test_warnings.py', 'ignore'],
304 # -W affects the result if the arg is not passed
305 [sys.executable, '-Wi', '_test_warnings.py']
306 )
307 # in all these cases no warnings are printed
308 for args in args_list:
309 p = subprocess.Popen(args, **opts)
310 out, err = get_parse_out_err(p)
Ezio Melottif10c4002010-12-01 01:45:53 +0000311 self.assertIn(b'OK', err)
Ezio Melotti60901872010-12-01 00:56:10 +0000312 self.assertEqual(len(out), 0)
313
314
315 # passing 'always' as warnings arg -> all the warnings printed,
316 # unittest warnings only once
317 p = subprocess.Popen([sys.executable, '_test_warnings.py', 'always'],
318 **opts)
319 out, err = get_parse_out_err(p)
Ezio Melottif10c4002010-12-01 01:45:53 +0000320 self.assertIn(b'OK', err)
Ezio Melotti60901872010-12-01 00:56:10 +0000321 self.assertEqual(len(out), 14)
322 for msg in [b'dw', b'iw', b'uw', b'rw']:
323 self.assertEqual(out.count(msg), 3)
324 for msg in [ae_msg, at_msg]:
325 self.assertEqual(out.count(msg), 1)
Michael Foord6f17e2d2010-12-30 19:36:29 +0000326
327 def testStdErrLookedUpAtInstantiationTime(self):
328 # see issue 10786
329 old_stderr = sys.stderr
330 f = io.StringIO()
331 sys.stderr = f
332 try:
333 runner = unittest.TextTestRunner()
334 self.assertTrue(runner.stream.stream is f)
335 finally:
336 sys.stderr = old_stderr
337
338 def testSpecifiedStreamUsed(self):
339 # see issue 10786
340 f = io.StringIO()
341 runner = unittest.TextTestRunner(f)
342 self.assertTrue(runner.stream.stream is f)
Antoine Pitrou1d7c8c92013-09-13 23:52:46 +0200343
344
345if __name__ == "__main__":
346 unittest.main()