Merge support for time: tags in the python bindings, and --times in subunit-ls.
[third_party/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 #  This program is free software; you can redistribute it and/or modify
6 #  it under the terms of the GNU General Public License as published by
7 #  the Free Software Foundation; either version 2 of the License, or
8 #  (at your option) any later version.
9 #
10 #  This program is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #  GNU General Public License for more details.
14 #
15 #  You should have received a copy of the GNU General Public License
16 #  along with this program; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 #
19
20 import datetime
21 import unittest
22 from StringIO import StringIO
23 import os
24 import subunit.test_results
25 import sys
26
27 import subunit.iso8601 as iso8601
28
29
30 class LoggingDecorator(subunit.test_results.HookedTestResultDecorator):
31
32     def __init__(self, decorated):
33         self._calls = 0
34         super(LoggingDecorator, self).__init__(decorated)
35
36     def _before_event(self):
37         self._calls += 1
38
39
40 class AssertBeforeTestResult(LoggingDecorator):
41     """A TestResult for checking preconditions."""
42
43     def __init__(self, decorated, test):
44         self.test = test
45         super(AssertBeforeTestResult, self).__init__(decorated)
46
47     def _before_event(self):
48         self.test.assertEqual(1, self.earlier._calls)
49         super(AssertBeforeTestResult, self)._before_event()
50
51
52 class TimeCapturingResult(unittest.TestResult):
53
54     def __init__(self):
55         super(TimeCapturingResult, self).__init__()
56         self._calls = []
57
58     def time(self, a_datetime):
59         self._calls.append(a_datetime)
60
61
62 class TestHookedTestResultDecorator(unittest.TestCase):
63
64     def setUp(self):
65         # And end to the chain
66         terminal = unittest.TestResult()
67         # Asserts that the call was made to self.result before asserter was
68         # called.
69         asserter = AssertBeforeTestResult(terminal, self)
70         # The result object we call, which much increase its call count.
71         self.result = LoggingDecorator(asserter)
72         asserter.earlier = self.result
73
74     def tearDown(self):
75         # The hook in self.result must have been called
76         self.assertEqual(1, self.result._calls)
77         # The hook in asserter must have been called too, otherwise the
78         # assertion about ordering won't have completed.
79         self.assertEqual(1, self.result.decorated._calls)
80
81     def test_startTest(self):
82         self.result.startTest(self)
83         
84     def test_startTestRun(self):
85         self.result.startTestRun()
86         
87     def test_stopTest(self):
88         self.result.stopTest(self)
89         
90     def test_stopTestRun(self):
91         self.result.stopTestRun()
92
93     def test_addError(self):
94         self.result.addError(self, subunit.RemoteError())
95         
96     def test_addFailure(self):
97         self.result.addFailure(self, subunit.RemoteError())
98
99     def test_addSuccess(self):
100         self.result.addSuccess(self)
101
102     def test_addSkip(self):
103         self.result.addSkip(self, "foo")
104
105     def test_addExpectedFailure(self):
106         self.result.addExpectedFailure(self, subunit.RemoteError())
107
108     def test_addUnexpectedSuccess(self):
109         self.result.addUnexpectedSuccess(self)
110
111     def test_wasSuccessful(self):
112         self.result.wasSuccessful()
113
114     def test_shouldStop(self):
115         self.result.shouldStop
116
117     def test_stop(self):
118         self.result.stop()
119
120     def test_time(self):
121         self.result.time(None)
122  
123
124 class TestAutoTimingTestResultDecorator(unittest.TestCase):
125
126     def setUp(self):
127         # And end to the chain which captures time events.
128         terminal = TimeCapturingResult()
129         # The result object under test.
130         self.result = subunit.test_results.AutoTimingTestResultDecorator(
131             terminal)
132
133     def test_without_time_calls_time_is_called_and_not_None(self):
134         self.result.startTest(self)
135         self.assertEqual(1, len(self.result.decorated._calls))
136         self.assertNotEqual(None, self.result.decorated._calls[0])
137
138     def test_no_time_from_shouldStop(self):
139         self.result.decorated.stop()
140         self.result.shouldStop
141         self.assertEqual(0, len(self.result.decorated._calls))
142
143     def test_calling_time_inhibits_automatic_time(self):
144         # Calling time() outputs a time signal immediately and prevents
145         # automatically adding one when other methods are called.
146         time = datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc())
147         self.result.time(time)
148         self.result.startTest(self)
149         self.result.stopTest(self)
150         self.assertEqual(1, len(self.result.decorated._calls))
151         self.assertEqual(time, self.result.decorated._calls[0])
152
153     def test_calling_time_None_enables_automatic_time(self):
154         time = datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc())
155         self.result.time(time)
156         self.assertEqual(1, len(self.result.decorated._calls))
157         self.assertEqual(time, self.result.decorated._calls[0])
158         # Calling None passes the None through, in case other results care.
159         self.result.time(None)
160         self.assertEqual(2, len(self.result.decorated._calls))
161         self.assertEqual(None, self.result.decorated._calls[1])
162         # Calling other methods doesn't generate an automatic time event.
163         self.result.startTest(self)
164         self.assertEqual(3, len(self.result.decorated._calls))
165         self.assertNotEqual(None, self.result.decorated._calls[2])
166
167
168 def test_suite():
169     loader = subunit.tests.TestUtil.TestLoader()
170     result = loader.loadTestsFromName(__name__)
171     return result