subunit: Update to latest upstream snapshot.
[nivanova/samba-autobuild/.git] / lib / subunit / python / subunit / tests / test_test_results.py
1 #
2 #  subunit: extensions to Python unittest to get test results from subprocesses.
3 #  Copyright (C) 2009  Robert Collins <robertc@robertcollins.net>
4 #
5 #  Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
6 #  license at the users choice. A copy of both licenses are available in the
7 #  project source as Apache-2.0 and BSD. You may not use this file except in
8 #  compliance with one of these two licences.
9 #
10 #  Unless required by applicable law or agreed to in writing, software
11 #  distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
12 #  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13 #  license you chose for the specific language governing permissions and
14 #  limitations under that license.
15 #
16
17 import datetime
18 import unittest
19
20 from testtools import TestCase
21 from testtools.testresult.doubles import ExtendedTestResult
22
23 import subunit
24 import subunit.iso8601 as iso8601
25 import subunit.test_results
26
27
28 class LoggingDecorator(subunit.test_results.HookedTestResultDecorator):
29
30     def __init__(self, decorated):
31         self._calls = 0
32         super(LoggingDecorator, self).__init__(decorated)
33
34     def _before_event(self):
35         self._calls += 1
36
37
38 class AssertBeforeTestResult(LoggingDecorator):
39     """A TestResult for checking preconditions."""
40
41     def __init__(self, decorated, test):
42         self.test = test
43         super(AssertBeforeTestResult, self).__init__(decorated)
44
45     def _before_event(self):
46         self.test.assertEqual(1, self.earlier._calls)
47         super(AssertBeforeTestResult, self)._before_event()
48
49
50 class TimeCapturingResult(unittest.TestResult):
51
52     def __init__(self):
53         super(TimeCapturingResult, self).__init__()
54         self._calls = []
55
56     def time(self, a_datetime):
57         self._calls.append(a_datetime)
58
59
60 class TestHookedTestResultDecorator(unittest.TestCase):
61
62     def setUp(self):
63         # An end to the chain
64         terminal = unittest.TestResult()
65         # Asserts that the call was made to self.result before asserter was
66         # called.
67         asserter = AssertBeforeTestResult(terminal, self)
68         # The result object we call, which much increase its call count.
69         self.result = LoggingDecorator(asserter)
70         asserter.earlier = self.result
71         self.decorated = asserter
72
73     def tearDown(self):
74         # The hook in self.result must have been called
75         self.assertEqual(1, self.result._calls)
76         # The hook in asserter must have been called too, otherwise the
77         # assertion about ordering won't have completed.
78         self.assertEqual(1, self.decorated._calls)
79
80     def test_startTest(self):
81         self.result.startTest(self)
82
83     def test_startTestRun(self):
84         self.result.startTestRun()
85
86     def test_stopTest(self):
87         self.result.stopTest(self)
88
89     def test_stopTestRun(self):
90         self.result.stopTestRun()
91
92     def test_addError(self):
93         self.result.addError(self, subunit.RemoteError())
94
95     def test_addError_details(self):
96         self.result.addError(self, details={})
97
98     def test_addFailure(self):
99         self.result.addFailure(self, subunit.RemoteError())
100
101     def test_addFailure_details(self):
102         self.result.addFailure(self, details={})
103
104     def test_addSuccess(self):
105         self.result.addSuccess(self)
106
107     def test_addSuccess_details(self):
108         self.result.addSuccess(self, details={})
109
110     def test_addSkip(self):
111         self.result.addSkip(self, "foo")
112
113     def test_addSkip_details(self):
114         self.result.addSkip(self, details={})
115
116     def test_addExpectedFailure(self):
117         self.result.addExpectedFailure(self, subunit.RemoteError())
118
119     def test_addExpectedFailure_details(self):
120         self.result.addExpectedFailure(self, details={})
121
122     def test_addUnexpectedSuccess(self):
123         self.result.addUnexpectedSuccess(self)
124
125     def test_addUnexpectedSuccess_details(self):
126         self.result.addUnexpectedSuccess(self, details={})
127
128     def test_progress(self):
129         self.result.progress(1, subunit.PROGRESS_SET)
130
131     def test_wasSuccessful(self):
132         self.result.wasSuccessful()
133
134     def test_shouldStop(self):
135         self.result.shouldStop
136
137     def test_stop(self):
138         self.result.stop()
139
140     def test_time(self):
141         self.result.time(None)
142
143
144 class TestAutoTimingTestResultDecorator(unittest.TestCase):
145
146     def setUp(self):
147         # And end to the chain which captures time events.
148         terminal = TimeCapturingResult()
149         # The result object under test.
150         self.result = subunit.test_results.AutoTimingTestResultDecorator(
151             terminal)
152         self.decorated = terminal
153
154     def test_without_time_calls_time_is_called_and_not_None(self):
155         self.result.startTest(self)
156         self.assertEqual(1, len(self.decorated._calls))
157         self.assertNotEqual(None, self.decorated._calls[0])
158
159     def test_no_time_from_progress(self):
160         self.result.progress(1, subunit.PROGRESS_CUR)
161         self.assertEqual(0, len(self.decorated._calls))
162
163     def test_no_time_from_shouldStop(self):
164         self.decorated.stop()
165         self.result.shouldStop
166         self.assertEqual(0, len(self.decorated._calls))
167
168     def test_calling_time_inhibits_automatic_time(self):
169         # Calling time() outputs a time signal immediately and prevents
170         # automatically adding one when other methods are called.
171         time = datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc())
172         self.result.time(time)
173         self.result.startTest(self)
174         self.result.stopTest(self)
175         self.assertEqual(1, len(self.decorated._calls))
176         self.assertEqual(time, self.decorated._calls[0])
177
178     def test_calling_time_None_enables_automatic_time(self):
179         time = datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc())
180         self.result.time(time)
181         self.assertEqual(1, len(self.decorated._calls))
182         self.assertEqual(time, self.decorated._calls[0])
183         # Calling None passes the None through, in case other results care.
184         self.result.time(None)
185         self.assertEqual(2, len(self.decorated._calls))
186         self.assertEqual(None, self.decorated._calls[1])
187         # Calling other methods doesn't generate an automatic time event.
188         self.result.startTest(self)
189         self.assertEqual(3, len(self.decorated._calls))
190         self.assertNotEqual(None, self.decorated._calls[2])
191
192
193 class TestTagCollapsingDecorator(TestCase):
194
195     def test_tags_forwarded_outside_of_tests(self):
196         result = ExtendedTestResult()
197         tag_collapser = subunit.test_results.TagCollapsingDecorator(result)
198         tag_collapser.tags(set(['a', 'b']), set())
199         self.assertEquals(
200             [('tags', set(['a', 'b']), set([]))], result._events)
201
202     def test_tags_collapsed_inside_of_tests(self):
203         result = ExtendedTestResult()
204         tag_collapser = subunit.test_results.TagCollapsingDecorator(result)
205         test = subunit.RemotedTestCase('foo')
206         tag_collapser.startTest(test)
207         tag_collapser.tags(set(['a']), set())
208         tag_collapser.tags(set(['b']), set(['a']))
209         tag_collapser.tags(set(['c']), set())
210         tag_collapser.stopTest(test)
211         self.assertEquals(
212             [('startTest', test),
213              ('tags', set(['b', 'c']), set(['a'])),
214              ('stopTest', test)],
215             result._events)
216
217     def test_tags_collapsed_inside_of_tests_different_ordering(self):
218         result = ExtendedTestResult()
219         tag_collapser = subunit.test_results.TagCollapsingDecorator(result)
220         test = subunit.RemotedTestCase('foo')
221         tag_collapser.startTest(test)
222         tag_collapser.tags(set(), set(['a']))
223         tag_collapser.tags(set(['a', 'b']), set())
224         tag_collapser.tags(set(['c']), set())
225         tag_collapser.stopTest(test)
226         self.assertEquals(
227             [('startTest', test),
228              ('tags', set(['a', 'b', 'c']), set()),
229              ('stopTest', test)],
230             result._events)
231
232
233 class TestTimeCollapsingDecorator(TestCase):
234
235     def make_time(self):
236         # Heh heh.
237         return datetime.datetime(
238             2000, 1, self.getUniqueInteger(), tzinfo=iso8601.UTC)
239
240     def test_initial_time_forwarded(self):
241         # We always forward the first time event we see.
242         result = ExtendedTestResult()
243         tag_collapser = subunit.test_results.TimeCollapsingDecorator(result)
244         a_time = self.make_time()
245         tag_collapser.time(a_time)
246         self.assertEquals([('time', a_time)], result._events)
247
248     def test_time_collapsed_to_first_and_last(self):
249         # If there are many consecutive time events, only the first and last
250         # are sent through.
251         result = ExtendedTestResult()
252         tag_collapser = subunit.test_results.TimeCollapsingDecorator(result)
253         times = [self.make_time() for i in range(5)]
254         for a_time in times:
255             tag_collapser.time(a_time)
256         tag_collapser.startTest(subunit.RemotedTestCase('foo'))
257         self.assertEquals(
258             [('time', times[0]), ('time', times[-1])], result._events[:-1])
259
260     def test_only_one_time_sent(self):
261         # If we receive a single time event followed by a non-time event, we
262         # send exactly one time event.
263         result = ExtendedTestResult()
264         tag_collapser = subunit.test_results.TimeCollapsingDecorator(result)
265         a_time = self.make_time()
266         tag_collapser.time(a_time)
267         tag_collapser.startTest(subunit.RemotedTestCase('foo'))
268         self.assertEquals([('time', a_time)], result._events[:-1])
269
270     def test_duplicate_times_not_sent(self):
271         # Many time events with the exact same time are collapsed into one
272         # time event.
273         result = ExtendedTestResult()
274         tag_collapser = subunit.test_results.TimeCollapsingDecorator(result)
275         a_time = self.make_time()
276         for i in range(5):
277             tag_collapser.time(a_time)
278         tag_collapser.startTest(subunit.RemotedTestCase('foo'))
279         self.assertEquals([('time', a_time)], result._events[:-1])
280
281     def test_no_times_inserted(self):
282         result = ExtendedTestResult()
283         tag_collapser = subunit.test_results.TimeCollapsingDecorator(result)
284         a_time = self.make_time()
285         tag_collapser.time(a_time)
286         foo = subunit.RemotedTestCase('foo')
287         tag_collapser.startTest(foo)
288         tag_collapser.addSuccess(foo)
289         tag_collapser.stopTest(foo)
290         self.assertEquals(
291             [('time', a_time),
292              ('startTest', foo),
293              ('addSuccess', foo),
294              ('stopTest', foo)], result._events)
295
296
297 def test_suite():
298     loader = subunit.tests.TestUtil.TestLoader()
299     result = loader.loadTestsFromName(__name__)
300     return result