2 # subunit: extensions to Python unittest to get test results from subprocesses.
3 # Copyright (C) 2009 Robert Collins <robertc@robertcollins.net>
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.
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.
19 from StringIO import StringIO
23 from testtools.content_type import ContentType
24 from testtools.content import Content
27 import subunit.iso8601 as iso8601
28 import subunit.test_results
31 class LoggingDecorator(subunit.test_results.HookedTestResultDecorator):
33 def __init__(self, decorated):
35 super(LoggingDecorator, self).__init__(decorated)
37 def _before_event(self):
41 class AssertBeforeTestResult(LoggingDecorator):
42 """A TestResult for checking preconditions."""
44 def __init__(self, decorated, test):
46 super(AssertBeforeTestResult, self).__init__(decorated)
48 def _before_event(self):
49 self.test.assertEqual(1, self.earlier._calls)
50 super(AssertBeforeTestResult, self)._before_event()
53 class TimeCapturingResult(unittest.TestResult):
56 super(TimeCapturingResult, self).__init__()
59 def time(self, a_datetime):
60 self._calls.append(a_datetime)
63 class TestHookedTestResultDecorator(unittest.TestCase):
67 terminal = unittest.TestResult()
68 # Asserts that the call was made to self.result before asserter was
70 asserter = AssertBeforeTestResult(terminal, self)
71 # The result object we call, which much increase its call count.
72 self.result = LoggingDecorator(asserter)
73 asserter.earlier = self.result
74 self.decorated = asserter
77 # The hook in self.result must have been called
78 self.assertEqual(1, self.result._calls)
79 # The hook in asserter must have been called too, otherwise the
80 # assertion about ordering won't have completed.
81 self.assertEqual(1, self.decorated._calls)
83 def test_startTest(self):
84 self.result.startTest(self)
86 def test_startTestRun(self):
87 self.result.startTestRun()
89 def test_stopTest(self):
90 self.result.stopTest(self)
92 def test_stopTestRun(self):
93 self.result.stopTestRun()
95 def test_addError(self):
96 self.result.addError(self, subunit.RemoteError())
98 def test_addError_details(self):
99 self.result.addError(self, details={})
101 def test_addFailure(self):
102 self.result.addFailure(self, subunit.RemoteError())
104 def test_addFailure_details(self):
105 self.result.addFailure(self, details={})
107 def test_addSuccess(self):
108 self.result.addSuccess(self)
110 def test_addSuccess_details(self):
111 self.result.addSuccess(self, details={})
113 def test_addSkip(self):
114 self.result.addSkip(self, "foo")
116 def test_addSkip_details(self):
117 self.result.addSkip(self, details={})
119 def test_addExpectedFailure(self):
120 self.result.addExpectedFailure(self, subunit.RemoteError())
122 def test_addExpectedFailure_details(self):
123 self.result.addExpectedFailure(self, details={})
125 def test_addUnexpectedSuccess(self):
126 self.result.addUnexpectedSuccess(self)
128 def test_addUnexpectedSuccess_details(self):
129 self.result.addUnexpectedSuccess(self, details={})
131 def test_progress(self):
132 self.result.progress(1, subunit.PROGRESS_SET)
134 def test_wasSuccessful(self):
135 self.result.wasSuccessful()
137 def test_shouldStop(self):
138 self.result.shouldStop
144 self.result.time(None)
147 class TestAutoTimingTestResultDecorator(unittest.TestCase):
150 # And end to the chain which captures time events.
151 terminal = TimeCapturingResult()
152 # The result object under test.
153 self.result = subunit.test_results.AutoTimingTestResultDecorator(
155 self.decorated = terminal
157 def test_without_time_calls_time_is_called_and_not_None(self):
158 self.result.startTest(self)
159 self.assertEqual(1, len(self.decorated._calls))
160 self.assertNotEqual(None, self.decorated._calls[0])
162 def test_no_time_from_progress(self):
163 self.result.progress(1, subunit.PROGRESS_CUR)
164 self.assertEqual(0, len(self.decorated._calls))
166 def test_no_time_from_shouldStop(self):
167 self.decorated.stop()
168 self.result.shouldStop
169 self.assertEqual(0, len(self.decorated._calls))
171 def test_calling_time_inhibits_automatic_time(self):
172 # Calling time() outputs a time signal immediately and prevents
173 # automatically adding one when other methods are called.
174 time = datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc())
175 self.result.time(time)
176 self.result.startTest(self)
177 self.result.stopTest(self)
178 self.assertEqual(1, len(self.decorated._calls))
179 self.assertEqual(time, self.decorated._calls[0])
181 def test_calling_time_None_enables_automatic_time(self):
182 time = datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc())
183 self.result.time(time)
184 self.assertEqual(1, len(self.decorated._calls))
185 self.assertEqual(time, self.decorated._calls[0])
186 # Calling None passes the None through, in case other results care.
187 self.result.time(None)
188 self.assertEqual(2, len(self.decorated._calls))
189 self.assertEqual(None, self.decorated._calls[1])
190 # Calling other methods doesn't generate an automatic time event.
191 self.result.startTest(self)
192 self.assertEqual(3, len(self.decorated._calls))
193 self.assertNotEqual(None, self.decorated._calls[2])
197 loader = subunit.tests.TestUtil.TestLoader()
198 result = loader.loadTestsFromName(__name__)