OLD | NEW |
1 """TestSuite""" | 1 """TestSuite""" |
2 | 2 |
3 import sys | 3 import sys |
4 import unittest | 4 import unittest |
5 from unittest2 import case, util | 5 from unittest2 import case, util |
6 | 6 |
7 __unittest = True | 7 __unittest = True |
8 | 8 |
9 | 9 |
10 class BaseTestSuite(unittest.TestSuite): | 10 class BaseTestSuite(unittest.TestSuite): |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 | 71 |
72 class TestSuite(BaseTestSuite): | 72 class TestSuite(BaseTestSuite): |
73 """A test suite is a composite test consisting of a number of TestCases. | 73 """A test suite is a composite test consisting of a number of TestCases. |
74 | 74 |
75 For use, create an instance of TestSuite, then add test case instances. | 75 For use, create an instance of TestSuite, then add test case instances. |
76 When all tests have been added, the suite can be passed to a test | 76 When all tests have been added, the suite can be passed to a test |
77 runner, such as TextTestRunner. It will run the individual test cases | 77 runner, such as TextTestRunner. It will run the individual test cases |
78 in the order in which they were added, aggregating the results. When | 78 in the order in which they were added, aggregating the results. When |
79 subclassing, do not forget to call the base class constructor. | 79 subclassing, do not forget to call the base class constructor. |
80 """ | 80 """ |
81 | 81 |
82 | 82 |
83 def run(self, result): | 83 def run(self, result): |
84 self._wrapped_run(result) | 84 self._wrapped_run(result) |
85 self._tearDownPreviousClass(None, result) | 85 self._tearDownPreviousClass(None, result) |
86 self._handleModuleTearDown(result) | 86 self._handleModuleTearDown(result) |
87 return result | 87 return result |
88 | 88 |
89 def debug(self): | 89 def debug(self): |
90 """Run the tests without collecting errors in a TestResult""" | 90 """Run the tests without collecting errors in a TestResult""" |
91 debug = _DebugResult() | 91 debug = _DebugResult() |
92 self._wrapped_run(debug, True) | 92 self._wrapped_run(debug, True) |
93 self._tearDownPreviousClass(None, debug) | 93 self._tearDownPreviousClass(None, debug) |
94 self._handleModuleTearDown(debug) | 94 self._handleModuleTearDown(debug) |
95 | 95 |
96 ################################ | 96 ################################ |
97 # private methods | 97 # private methods |
98 def _wrapped_run(self, result, debug=False): | 98 def _wrapped_run(self, result, debug=False): |
99 for test in self: | 99 for test in self: |
100 if result.shouldStop: | 100 if result.shouldStop: |
101 break | 101 break |
102 | 102 |
103 if _isnotsuite(test): | 103 if _isnotsuite(test): |
104 self._tearDownPreviousClass(test, result) | 104 self._tearDownPreviousClass(test, result) |
105 self._handleModuleFixture(test, result) | 105 self._handleModuleFixture(test, result) |
106 self._handleClassSetUp(test, result) | 106 self._handleClassSetUp(test, result) |
107 result._previousTestClass = test.__class__ | 107 result._previousTestClass = test.__class__ |
108 | 108 |
109 if (getattr(test.__class__, '_classSetupFailed', False) or | 109 if (getattr(test.__class__, '_classSetupFailed', False) or |
110 getattr(result, '_moduleSetUpFailed', False)): | 110 getattr(result, '_moduleSetUpFailed', False)): |
111 continue | 111 continue |
112 | 112 |
113 if hasattr(test, '_wrapped_run'): | 113 if hasattr(test, '_wrapped_run'): |
114 test._wrapped_run(result, debug) | 114 test._wrapped_run(result, debug) |
115 elif not debug: | 115 elif not debug: |
116 test(result) | 116 test(result) |
117 else: | 117 else: |
118 test.debug() | 118 test.debug() |
119 | 119 |
120 def _handleClassSetUp(self, test, result): | 120 def _handleClassSetUp(self, test, result): |
121 previousClass = getattr(result, '_previousTestClass', None) | 121 previousClass = getattr(result, '_previousTestClass', None) |
122 currentClass = test.__class__ | 122 currentClass = test.__class__ |
123 if currentClass == previousClass: | 123 if currentClass == previousClass: |
124 return | 124 return |
125 if result._moduleSetUpFailed: | 125 if result._moduleSetUpFailed: |
126 return | 126 return |
127 if getattr(currentClass, "__unittest_skip__", False): | 127 if getattr(currentClass, "__unittest_skip__", False): |
128 return | 128 return |
129 | 129 |
130 try: | 130 try: |
131 currentClass._classSetupFailed = False | 131 currentClass._classSetupFailed = False |
132 except TypeError: | 132 except TypeError: |
133 # test may actually be a function | 133 # test may actually be a function |
134 # so its class will be a builtin-type | 134 # so its class will be a builtin-type |
135 pass | 135 pass |
136 | 136 |
137 setUpClass = getattr(currentClass, 'setUpClass', None) | 137 setUpClass = getattr(currentClass, 'setUpClass', None) |
138 if setUpClass is not None: | 138 if setUpClass is not None: |
139 try: | 139 try: |
140 setUpClass() | 140 setUpClass() |
141 except Exception, e: | 141 except Exception, e: |
142 if isinstance(result, _DebugResult): | 142 if isinstance(result, _DebugResult): |
143 raise | 143 raise |
144 currentClass._classSetupFailed = True | 144 currentClass._classSetupFailed = True |
145 className = util.strclass(currentClass) | 145 className = util.strclass(currentClass) |
146 errorName = 'setUpClass (%s)' % className | 146 errorName = 'setUpClass (%s)' % className |
147 self._addClassOrModuleLevelException(result, e, errorName) | 147 self._addClassOrModuleLevelException(result, e, errorName) |
148 | 148 |
149 def _get_previous_module(self, result): | 149 def _get_previous_module(self, result): |
150 previousModule = None | 150 previousModule = None |
151 previousClass = getattr(result, '_previousTestClass', None) | 151 previousClass = getattr(result, '_previousTestClass', None) |
152 if previousClass is not None: | 152 if previousClass is not None: |
153 previousModule = previousClass.__module__ | 153 previousModule = previousClass.__module__ |
154 return previousModule | 154 return previousModule |
155 | 155 |
156 | 156 |
157 def _handleModuleFixture(self, test, result): | 157 def _handleModuleFixture(self, test, result): |
158 previousModule = self._get_previous_module(result) | 158 previousModule = self._get_previous_module(result) |
159 currentModule = test.__class__.__module__ | 159 currentModule = test.__class__.__module__ |
160 if currentModule == previousModule: | 160 if currentModule == previousModule: |
161 return | 161 return |
162 | 162 |
163 self._handleModuleTearDown(result) | 163 self._handleModuleTearDown(result) |
164 | 164 |
165 | 165 |
166 result._moduleSetUpFailed = False | 166 result._moduleSetUpFailed = False |
167 try: | 167 try: |
168 module = sys.modules[currentModule] | 168 module = sys.modules[currentModule] |
169 except KeyError: | 169 except KeyError: |
170 return | 170 return |
171 setUpModule = getattr(module, 'setUpModule', None) | 171 setUpModule = getattr(module, 'setUpModule', None) |
172 if setUpModule is not None: | 172 if setUpModule is not None: |
173 try: | 173 try: |
174 setUpModule() | 174 setUpModule() |
175 except Exception, e: | 175 except Exception, e: |
176 if isinstance(result, _DebugResult): | 176 if isinstance(result, _DebugResult): |
177 raise | 177 raise |
178 result._moduleSetUpFailed = True | 178 result._moduleSetUpFailed = True |
179 errorName = 'setUpModule (%s)' % currentModule | 179 errorName = 'setUpModule (%s)' % currentModule |
180 self._addClassOrModuleLevelException(result, e, errorName) | 180 self._addClassOrModuleLevelException(result, e, errorName) |
181 | 181 |
182 def _addClassOrModuleLevelException(self, result, exception, errorName): | 182 def _addClassOrModuleLevelException(self, result, exception, errorName): |
183 error = _ErrorHolder(errorName) | 183 error = _ErrorHolder(errorName) |
184 addSkip = getattr(result, 'addSkip', None) | 184 addSkip = getattr(result, 'addSkip', None) |
185 if addSkip is not None and isinstance(exception, case.SkipTest): | 185 if addSkip is not None and isinstance(exception, case.SkipTest): |
186 addSkip(error, str(exception)) | 186 addSkip(error, str(exception)) |
187 else: | 187 else: |
188 result.addError(error, sys.exc_info()) | 188 result.addError(error, sys.exc_info()) |
189 | 189 |
190 def _handleModuleTearDown(self, result): | 190 def _handleModuleTearDown(self, result): |
191 previousModule = self._get_previous_module(result) | 191 previousModule = self._get_previous_module(result) |
192 if previousModule is None: | 192 if previousModule is None: |
193 return | 193 return |
194 if result._moduleSetUpFailed: | 194 if result._moduleSetUpFailed: |
195 return | 195 return |
196 | 196 |
197 try: | 197 try: |
198 module = sys.modules[previousModule] | 198 module = sys.modules[previousModule] |
199 except KeyError: | 199 except KeyError: |
200 return | 200 return |
201 | 201 |
202 tearDownModule = getattr(module, 'tearDownModule', None) | 202 tearDownModule = getattr(module, 'tearDownModule', None) |
203 if tearDownModule is not None: | 203 if tearDownModule is not None: |
204 try: | 204 try: |
205 tearDownModule() | 205 tearDownModule() |
206 except Exception, e: | 206 except Exception, e: |
207 if isinstance(result, _DebugResult): | 207 if isinstance(result, _DebugResult): |
208 raise | 208 raise |
209 errorName = 'tearDownModule (%s)' % previousModule | 209 errorName = 'tearDownModule (%s)' % previousModule |
210 self._addClassOrModuleLevelException(result, e, errorName) | 210 self._addClassOrModuleLevelException(result, e, errorName) |
211 | 211 |
212 def _tearDownPreviousClass(self, test, result): | 212 def _tearDownPreviousClass(self, test, result): |
213 previousClass = getattr(result, '_previousTestClass', None) | 213 previousClass = getattr(result, '_previousTestClass', None) |
214 currentClass = test.__class__ | 214 currentClass = test.__class__ |
215 if currentClass == previousClass: | 215 if currentClass == previousClass: |
216 return | 216 return |
217 if getattr(previousClass, '_classSetupFailed', False): | 217 if getattr(previousClass, '_classSetupFailed', False): |
218 return | 218 return |
219 if getattr(result, '_moduleSetUpFailed', False): | 219 if getattr(result, '_moduleSetUpFailed', False): |
220 return | 220 return |
221 if getattr(previousClass, "__unittest_skip__", False): | 221 if getattr(previousClass, "__unittest_skip__", False): |
222 return | 222 return |
223 | 223 |
224 tearDownClass = getattr(previousClass, 'tearDownClass', None) | 224 tearDownClass = getattr(previousClass, 'tearDownClass', None) |
225 if tearDownClass is not None: | 225 if tearDownClass is not None: |
226 try: | 226 try: |
227 tearDownClass() | 227 tearDownClass() |
228 except Exception, e: | 228 except Exception, e: |
229 if isinstance(result, _DebugResult): | 229 if isinstance(result, _DebugResult): |
230 raise | 230 raise |
231 className = util.strclass(previousClass) | 231 className = util.strclass(previousClass) |
232 errorName = 'tearDownClass (%s)' % className | 232 errorName = 'tearDownClass (%s)' % className |
233 self._addClassOrModuleLevelException(result, e, errorName) | 233 self._addClassOrModuleLevelException(result, e, errorName) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 except TypeError: | 278 except TypeError: |
279 return True | 279 return True |
280 return False | 280 return False |
281 | 281 |
282 | 282 |
283 class _DebugResult(object): | 283 class _DebugResult(object): |
284 "Used by the TestSuite to hold previous class when running in debug." | 284 "Used by the TestSuite to hold previous class when running in debug." |
285 _previousTestClass = None | 285 _previousTestClass = None |
286 _moduleSetUpFailed = False | 286 _moduleSetUpFailed = False |
287 shouldStop = False | 287 shouldStop = False |
OLD | NEW |