Merge lp:~lifeless/subunit/addSkip into lp:~subunit/subunit/trunk
- addSkip
- Merge into trunk
Proposed by
Robert Collins
Status: | Merged |
---|---|
Approved by: | Jonathan Lange |
Approved revision: | 58 |
Merged at revision: | not available |
Proposed branch: | lp:~lifeless/subunit/addSkip |
Merge into: | lp:~subunit/subunit/trunk |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~lifeless/subunit/addSkip |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jonathan Lange | Approve | ||
Review via email: mp+4033@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote : | # |
lp:~lifeless/subunit/addSkip
updated
- 58. By Robert Collins
-
subunit-filter can now filter skips too.
Revision history for this message
Jonathan Lange (jml) wrote : | # |
Fine to land, along with the tweaks suggested for lp:~lifeless/subunit/filter.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'README' |
2 | --- README 2009-02-15 11:55:00 +0000 |
3 | +++ README 2009-02-28 09:27:25 +0000 |
4 | @@ -40,6 +40,8 @@ |
5 | stream on-the-fly. Currently subunit provides: |
6 | * tap2subunit - convert perl's TestAnythingProtocol to subunit. |
7 | * subunit2pyunit - convert a subunit stream to pyunit test results. |
8 | + * subunit-filter - filter out tests from a subunit stream. |
9 | + * subunit-ls - list the tests present in a subunit stream. |
10 | * subunit-stats - generate a summary of a subunit stream. |
11 | * subunit-tags - add or remove tags from a stream. |
12 | |
13 | @@ -200,8 +202,10 @@ |
14 | Currently this is not exposed at the python API layer. |
15 | |
16 | The skip result is used to indicate a test that was found by the runner but not |
17 | -fully executed due to some policy or dependency issue. Currently this is |
18 | -represented in Python as a successful test. |
19 | +fully executed due to some policy or dependency issue. This is represented in |
20 | +python using the addSkip interface that testtools |
21 | +(https://edge.launchpad.net/testtools) defines. When communicating with a non |
22 | +skip aware test result, the test is reported as an error. |
23 | The xfail result is used to indicate a test that was expected to fail failing |
24 | in the expected manner. As this is a normal condition for such tests it is |
25 | represented as a successful test in Python. |
26 | |
27 | === added file 'filters/subunit-filter' |
28 | --- filters/subunit-filter 1970-01-01 00:00:00 +0000 |
29 | +++ filters/subunit-filter 2009-02-22 07:51:04 +0000 |
30 | @@ -0,0 +1,50 @@ |
31 | +#!/usr/bin/env python |
32 | +# subunit: extensions to python unittest to get test results from subprocesses. |
33 | +# Copyright (C) 2008 Robert Collins <robertc@robertcollins.net> |
34 | +# |
35 | +# This program is free software; you can redistribute it and/or modify |
36 | +# it under the terms of the GNU General Public License as published by |
37 | +# the Free Software Foundation; either version 2 of the License, or |
38 | +# (at your option) any later version. |
39 | +# |
40 | +# This program is distributed in the hope that it will be useful, |
41 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
42 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
43 | +# GNU General Public License for more details. |
44 | +# |
45 | +# You should have received a copy of the GNU General Public License |
46 | +# along with this program; if not, write to the Free Software |
47 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
48 | +# |
49 | + |
50 | +"""Filter a subunit stream to include/exclude tests. |
51 | + |
52 | +The default is to strip successful tests. |
53 | +""" |
54 | + |
55 | +from optparse import OptionParser |
56 | +import sys |
57 | +import unittest |
58 | + |
59 | +from subunit import ProtocolTestCase, TestResultFilter, TestProtocolClient |
60 | + |
61 | +parser = OptionParser(description=__doc__) |
62 | +parser.add_option("--error", action="store_false", |
63 | + help="include errors", default=False, dest="error") |
64 | +parser.add_option("-e", "--no-error", action="store_true", |
65 | + help="exclude errors", dest="error") |
66 | +parser.add_option("--failure", action="store_false", |
67 | + help="include failures", default=False, dest="failure") |
68 | +parser.add_option("-f", "--no-failure", action="store_true", |
69 | + help="include failures", dest="failure") |
70 | +parser.add_option("-s", "--success", action="store_false", |
71 | + help="include successes", dest="success") |
72 | +parser.add_option("--no-success", action="store_true", |
73 | + help="exclude successes", default=True, dest="success") |
74 | +(options, args) = parser.parse_args() |
75 | +result = TestProtocolClient(sys.stdout) |
76 | +result = TestResultFilter(result, filter_error=options.error, filter_failure=options.failure, |
77 | + filter_success=options.success) |
78 | +test = ProtocolTestCase(sys.stdin) |
79 | +test.run(result) |
80 | +sys.exit(0) |
81 | |
82 | === added file 'filters/subunit-ls' |
83 | --- filters/subunit-ls 1970-01-01 00:00:00 +0000 |
84 | +++ filters/subunit-ls 2009-02-23 10:54:28 +0000 |
85 | @@ -0,0 +1,62 @@ |
86 | +#!/usr/bin/env python |
87 | +# subunit: extensions to python unittest to get test results from subprocesses. |
88 | +# Copyright (C) 2008 Robert Collins <robertc@robertcollins.net> |
89 | +# |
90 | +# This program is free software; you can redistribute it and/or modify |
91 | +# it under the terms of the GNU General Public License as published by |
92 | +# the Free Software Foundation; either version 2 of the License, or |
93 | +# (at your option) any later version. |
94 | +# |
95 | +# This program is distributed in the hope that it will be useful, |
96 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
97 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
98 | +# GNU General Public License for more details. |
99 | +# |
100 | +# You should have received a copy of the GNU General Public License |
101 | +# along with this program; if not, write to the Free Software |
102 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
103 | +# |
104 | + |
105 | +"""List tests in a subunit stream.""" |
106 | + |
107 | +import sys |
108 | +import unittest |
109 | + |
110 | +from subunit import ProtocolTestCase |
111 | + |
112 | +class FilterResult(unittest.TestResult): |
113 | + """Filter test objects for display.""" |
114 | + |
115 | + def __init__(self, stream): |
116 | + """Create a FilterResult object outputting to stream.""" |
117 | + unittest.TestResult.__init__(self) |
118 | + self._stream = stream |
119 | + self.failed_tests = 0 |
120 | + |
121 | + def addError(self, test, err): |
122 | + self.failed_tests += 1 |
123 | + self.reportTest(test) |
124 | + |
125 | + def addFailure(self, test, err): |
126 | + self.failed_tests += 1 |
127 | + self.reportTest(test) |
128 | + |
129 | + def addSuccess(self, test): |
130 | + self.reportTest(test) |
131 | + |
132 | + def reportTest(self, test): |
133 | + self._stream.write(test.id() + '\n') |
134 | + |
135 | + def wasSuccessful(self): |
136 | + "Tells whether or not this result was a success" |
137 | + return self.failed_tests == 0 |
138 | + |
139 | + |
140 | +result = FilterResult(sys.stdout) |
141 | +test = ProtocolTestCase(sys.stdin) |
142 | +test.run(result) |
143 | +if result.wasSuccessful(): |
144 | + exit_code = 0 |
145 | +else: |
146 | + exit_code = 1 |
147 | +sys.exit(exit_code) |
148 | |
149 | === modified file 'python/subunit/__init__.py' |
150 | --- python/subunit/__init__.py 2009-02-15 11:55:00 +0000 |
151 | +++ python/subunit/__init__.py 2009-02-28 09:27:25 +0000 |
152 | @@ -133,7 +133,7 @@ |
153 | self.current_test_description == line[offset:-1]): |
154 | self.state = TestProtocolServer.OUTSIDE_TEST |
155 | self.current_test_description = None |
156 | - self.client.addSuccess(self._current_test) |
157 | + self._skip_or_error() |
158 | self.client.stopTest(self._current_test) |
159 | elif (self.state == TestProtocolServer.TEST_STARTED and |
160 | self.current_test_description + " [" == line[offset:-1]): |
161 | @@ -142,6 +142,16 @@ |
162 | else: |
163 | self.stdOutLineReceived(line) |
164 | |
165 | + def _skip_or_error(self, message=None): |
166 | + """Report the current test as a skip if possible, or else an error.""" |
167 | + addSkip = getattr(self.client, 'addSkip', None) |
168 | + if not callable(addSkip): |
169 | + self.client.addError(self._current_test, RemoteError(message)) |
170 | + else: |
171 | + if not message: |
172 | + message = "No reason given" |
173 | + addSkip(self._current_test, message) |
174 | + |
175 | def _addSuccess(self, offset, line): |
176 | if (self.state == TestProtocolServer.TEST_STARTED and |
177 | self.current_test_description == line[offset:-1]): |
178 | @@ -173,8 +183,12 @@ |
179 | self.client.addError(self._current_test, |
180 | RemoteError(self._message)) |
181 | self.client.stopTest(self._current_test) |
182 | + elif self.state == TestProtocolServer.READING_SKIP: |
183 | + self.state = TestProtocolServer.OUTSIDE_TEST |
184 | + self.current_test_description = None |
185 | + self._skip_or_error(self._message) |
186 | + self.client.stopTest(self._current_test) |
187 | elif self.state in ( |
188 | - TestProtocolServer.READING_SKIP, |
189 | TestProtocolServer.READING_SUCCESS, |
190 | TestProtocolServer.READING_XFAIL, |
191 | ): |
192 | @@ -314,6 +328,12 @@ |
193 | self._stream.write("%s\n" % line) |
194 | self._stream.write("]\n") |
195 | |
196 | + def addSkip(self, test, reason): |
197 | + """Report a skipped test.""" |
198 | + self._stream.write("skip: %s [\n" % test.id()) |
199 | + self._stream.write("%s\n" % reason) |
200 | + self._stream.write("]\n") |
201 | + |
202 | def addSuccess(self, test): |
203 | """Report a success in a test.""" |
204 | self._stream.write("successful: %s\n" % test.id()) |
205 | @@ -363,7 +383,7 @@ |
206 | return self.__description |
207 | |
208 | def id(self): |
209 | - return "%s.%s" % (self._strclass(), self.__description) |
210 | + return "%s" % (self.__description,) |
211 | |
212 | def __str__(self): |
213 | return "%s (%s)" % (self.__description, self._strclass()) |
214 | @@ -651,6 +671,7 @@ |
215 | unittest.TestResult.__init__(self) |
216 | self._stream = stream |
217 | self.failed_tests = 0 |
218 | + self.skipped_tests = 0 |
219 | self.tags = set() |
220 | |
221 | @property |
222 | @@ -663,16 +684,20 @@ |
223 | def addFailure(self, test, err): |
224 | self.failed_tests += 1 |
225 | |
226 | + def addSkip(self, test, reason): |
227 | + self.skipped_tests += 1 |
228 | + |
229 | def formatStats(self): |
230 | - self._stream.write("Total tests: %5d\n" % self.total_tests) |
231 | - self._stream.write("Passed tests: %5d\n" % self.passed_tests) |
232 | - self._stream.write("Failed tests: %5d\n" % self.failed_tests) |
233 | + self._stream.write("Total tests: %5d\n" % self.total_tests) |
234 | + self._stream.write("Passed tests: %5d\n" % self.passed_tests) |
235 | + self._stream.write("Failed tests: %5d\n" % self.failed_tests) |
236 | + self._stream.write("Skipped tests: %5d\n" % self.skipped_tests) |
237 | tags = sorted(self.tags) |
238 | self._stream.write("Tags: %s\n" % (", ".join(tags))) |
239 | |
240 | @property |
241 | def passed_tests(self): |
242 | - return self.total_tests - self.failed_tests |
243 | + return self.total_tests - self.failed_tests - self.skipped_tests |
244 | |
245 | def stopTest(self, test): |
246 | unittest.TestResult.stopTest(self, test) |
247 | @@ -681,3 +706,66 @@ |
248 | def wasSuccessful(self): |
249 | """Tells whether or not this result was a success""" |
250 | return self.failed_tests == 0 |
251 | + |
252 | + |
253 | +class TestResultFilter(unittest.TestResult): |
254 | + """A pyunit TestResult interface implementation which filters tests. |
255 | + |
256 | + Tests that pass the filter are handed on to another TestResult instance |
257 | + for further processing/reporting. To obtain the filtered results, |
258 | + the other instance must be interrogated. |
259 | + |
260 | + :ivar result: The result that tests are passed to after filtering. |
261 | + """ |
262 | + |
263 | + def __init__(self, result, filter_error=False, filter_failure=False, |
264 | + filter_success=True, filter_skip=False): |
265 | + """Create a FilterResult object filtering to result. |
266 | + |
267 | + :param filter_error: Filter out errors. |
268 | + :param filter_failure: Filter out failures. |
269 | + :param filter_success: Filter out successful tests. |
270 | + :param filter_skip: Filter out skipped tests. |
271 | + """ |
272 | + unittest.TestResult.__init__(self) |
273 | + self.result = result |
274 | + self._filter_error = filter_error |
275 | + self._filter_failure = filter_failure |
276 | + self._filter_success = filter_success |
277 | + self._filter_skip = filter_skip |
278 | + |
279 | + def addError(self, test, err): |
280 | + if not self._filter_error: |
281 | + self.result.startTest(test) |
282 | + self.result.addError(test, err) |
283 | + self.result.stopTest(test) |
284 | + |
285 | + def addFailure(self, test, err): |
286 | + if not self._filter_failure: |
287 | + self.result.startTest(test) |
288 | + self.result.addFailure(test, err) |
289 | + self.result.stopTest(test) |
290 | + |
291 | + def addSkip(self, test, reason): |
292 | + if not self._filter_skip: |
293 | + self.result.startTest(test) |
294 | + # This is duplicated, it would be nice to have on a 'calls |
295 | + # TestResults' mixin perhaps. |
296 | + addSkip = getattr(self.result, 'addSkip', None) |
297 | + if not callable(addSkip): |
298 | + self.result.addError(test, RemoteError(reason)) |
299 | + else: |
300 | + self.result.addSkip(test, reason) |
301 | + self.result.stopTest(test) |
302 | + |
303 | + def addSuccess(self, test): |
304 | + if not self._filter_success: |
305 | + self.result.startTest(test) |
306 | + self.result.addSuccess(test) |
307 | + self.result.stopTest(test) |
308 | + |
309 | + def id_to_orig_id(self, id): |
310 | + if id.startswith("subunit.RemotedTestCase."): |
311 | + return id[len("subunit.RemotedTestCase."):] |
312 | + return id |
313 | + |
314 | |
315 | === modified file 'python/subunit/tests/__init__.py' |
316 | --- python/subunit/tests/__init__.py 2008-12-09 01:00:03 +0000 |
317 | +++ python/subunit/tests/__init__.py 2009-02-22 06:28:08 +0000 |
318 | @@ -19,6 +19,7 @@ |
319 | |
320 | from subunit.tests import ( |
321 | TestUtil, |
322 | + test_subunit_filter, |
323 | test_subunit_stats, |
324 | test_subunit_tags, |
325 | test_tap2subunit, |
326 | @@ -29,6 +30,7 @@ |
327 | result = TestUtil.TestSuite() |
328 | result.addTest(test_test_protocol.test_suite()) |
329 | result.addTest(test_tap2subunit.test_suite()) |
330 | + result.addTest(test_subunit_filter.test_suite()) |
331 | result.addTest(test_subunit_tags.test_suite()) |
332 | result.addTest(test_subunit_stats.test_suite()) |
333 | return result |
334 | |
335 | === added file 'python/subunit/tests/test_subunit_filter.py' |
336 | --- python/subunit/tests/test_subunit_filter.py 1970-01-01 00:00:00 +0000 |
337 | +++ python/subunit/tests/test_subunit_filter.py 2009-02-28 09:27:25 +0000 |
338 | @@ -0,0 +1,125 @@ |
339 | +# |
340 | +# subunit: extensions to python unittest to get test results from subprocesses. |
341 | +# Copyright (C) 2005 Robert Collins <robertc@robertcollins.net> |
342 | +# |
343 | +# This program is free software; you can redistribute it and/or modify |
344 | +# it under the terms of the GNU General Public License as published by |
345 | +# the Free Software Foundation; either version 2 of the License, or |
346 | +# (at your option) any later version. |
347 | +# |
348 | +# This program is distributed in the hope that it will be useful, |
349 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
350 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
351 | +# GNU General Public License for more details. |
352 | +# |
353 | +# You should have received a copy of the GNU General Public License |
354 | +# along with this program; if not, write to the Free Software |
355 | +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
356 | +# |
357 | + |
358 | +"""Tests for subunit.TestResultFilter.""" |
359 | + |
360 | +import unittest |
361 | +from StringIO import StringIO |
362 | + |
363 | +import subunit |
364 | + |
365 | + |
366 | +class TestTestResultFilter(unittest.TestCase): |
367 | + """Test for TestResultFilter, a TestResult object which filters tests.""" |
368 | + |
369 | + def _setUp(self): |
370 | + self.output = StringIO() |
371 | + |
372 | + def test_default(self): |
373 | + """The default is to exclude success and include everything else.""" |
374 | + self.filtered_result = unittest.TestResult() |
375 | + self.filter = subunit.TestResultFilter(self.filtered_result) |
376 | + self.run_tests() |
377 | + # skips are seen as errors by default python TestResult. |
378 | + self.assertEqual(['error', 'skipped'], |
379 | + [error[0].id() for error in self.filtered_result.errors]) |
380 | + self.assertEqual(['failed'], |
381 | + [failure[0].id() for failure in |
382 | + self.filtered_result.failures]) |
383 | + self.assertEqual(3, self.filtered_result.testsRun) |
384 | + |
385 | + def test_exclude_errors(self): |
386 | + self.filtered_result = unittest.TestResult() |
387 | + self.filter = subunit.TestResultFilter(self.filtered_result, |
388 | + filter_error=True) |
389 | + self.run_tests() |
390 | + # skips are seen as errors by default python TestResult. |
391 | + self.assertEqual(['skipped'], |
392 | + [error[0].id() for error in self.filtered_result.errors]) |
393 | + self.assertEqual(['failed'], |
394 | + [failure[0].id() for failure in |
395 | + self.filtered_result.failures]) |
396 | + self.assertEqual(2, self.filtered_result.testsRun) |
397 | + |
398 | + def test_exclude_failure(self): |
399 | + self.filtered_result = unittest.TestResult() |
400 | + self.filter = subunit.TestResultFilter(self.filtered_result, |
401 | + filter_failure=True) |
402 | + self.run_tests() |
403 | + self.assertEqual(['error', 'skipped'], |
404 | + [error[0].id() for error in self.filtered_result.errors]) |
405 | + self.assertEqual([], |
406 | + [failure[0].id() for failure in |
407 | + self.filtered_result.failures]) |
408 | + self.assertEqual(2, self.filtered_result.testsRun) |
409 | + |
410 | + def test_exclude_skips(self): |
411 | + self.filtered_result = subunit.TestResultStats(None) |
412 | + self.filter = subunit.TestResultFilter(self.filtered_result, |
413 | + filter_skip=True) |
414 | + self.run_tests() |
415 | + self.assertEqual(0, self.filtered_result.skipped_tests) |
416 | + self.assertEqual(2, self.filtered_result.failed_tests) |
417 | + self.assertEqual(2, self.filtered_result.testsRun) |
418 | + |
419 | + def test_include_success(self): |
420 | + """Success's can be included if requested.""" |
421 | + self.filtered_result = unittest.TestResult() |
422 | + self.filter = subunit.TestResultFilter(self.filtered_result, |
423 | + filter_success=False) |
424 | + self.run_tests() |
425 | + self.assertEqual(['error', 'skipped'], |
426 | + [error[0].id() for error in self.filtered_result.errors]) |
427 | + self.assertEqual(['failed'], |
428 | + [failure[0].id() for failure in |
429 | + self.filtered_result.failures]) |
430 | + self.assertEqual(5, self.filtered_result.testsRun) |
431 | + |
432 | + def run_tests(self): |
433 | + self.setUpTestStream() |
434 | + self.test = subunit.ProtocolTestCase(self.input_stream) |
435 | + self.test.run(self.filter) |
436 | + |
437 | + def setUpTestStream(self): |
438 | + # While TestResultFilter works on python objects, using a subunit |
439 | + # stream is an easy pithy way of getting a series of test objects to |
440 | + # call into the TestResult, and as TestResultFilter is intended for use |
441 | + # with subunit also has the benefit of detecting any interface skew issues. |
442 | + self.input_stream = StringIO() |
443 | + self.input_stream.write("""tags: global |
444 | +test passed |
445 | +success passed |
446 | +test failed |
447 | +tags: local |
448 | +failure failed |
449 | +test error |
450 | +error error |
451 | +test skipped |
452 | +skip skipped |
453 | +test todo |
454 | +xfail todo |
455 | +""") |
456 | + self.input_stream.seek(0) |
457 | + |
458 | + |
459 | + |
460 | +def test_suite(): |
461 | + loader = subunit.tests.TestUtil.TestLoader() |
462 | + result = loader.loadTestsFromName(__name__) |
463 | + return result |
464 | |
465 | === modified file 'python/subunit/tests/test_subunit_stats.py' |
466 | --- python/subunit/tests/test_subunit_stats.py 2008-12-09 01:00:03 +0000 |
467 | +++ python/subunit/tests/test_subunit_stats.py 2009-02-28 09:27:25 +0000 |
468 | @@ -62,15 +62,17 @@ |
469 | # Statistics are calculated usefully. |
470 | self.setUpUsedStream() |
471 | self.assertEqual(5, self.result.total_tests) |
472 | - self.assertEqual(3, self.result.passed_tests) |
473 | + self.assertEqual(2, self.result.passed_tests) |
474 | self.assertEqual(2, self.result.failed_tests) |
475 | + self.assertEqual(1, self.result.skipped_tests) |
476 | self.assertEqual(set(["global", "local"]), self.result.tags) |
477 | |
478 | def test_stat_formatting(self): |
479 | expected = (""" |
480 | -Total tests: 5 |
481 | -Passed tests: 3 |
482 | -Failed tests: 2 |
483 | +Total tests: 5 |
484 | +Passed tests: 2 |
485 | +Failed tests: 2 |
486 | +Skipped tests: 1 |
487 | Tags: global, local |
488 | """)[1:] |
489 | self.setUpUsedStream() |
490 | |
491 | === modified file 'python/subunit/tests/test_test_protocol.py' |
492 | --- python/subunit/tests/test_test_protocol.py 2008-12-14 18:37:08 +0000 |
493 | +++ python/subunit/tests/test_test_protocol.py 2009-02-28 09:27:25 +0000 |
494 | @@ -32,6 +32,7 @@ |
495 | self.end_calls = [] |
496 | self.error_calls = [] |
497 | self.failure_calls = [] |
498 | + self.skip_calls = [] |
499 | self.start_calls = [] |
500 | self.success_calls = [] |
501 | super(MockTestProtocolServerClient, self).__init__() |
502 | @@ -42,6 +43,9 @@ |
503 | def addFailure(self, test, error): |
504 | self.failure_calls.append((test, error)) |
505 | |
506 | + def addSkip(self, test, reason): |
507 | + self.skip_calls.append((test, reason)) |
508 | + |
509 | def addSuccess(self, test): |
510 | self.success_calls.append(test) |
511 | |
512 | @@ -589,8 +593,8 @@ |
513 | class TestTestProtocolServerAddSkip(unittest.TestCase): |
514 | """Tests for the skip keyword. |
515 | |
516 | - In Python this thunks through to Success due to stdlib limitations. (See |
517 | - README). |
518 | + In python this meets the testtools extended TestResult contract. |
519 | + (See https://launchpad.net/testtools). |
520 | """ |
521 | |
522 | def setUp(self): |
523 | @@ -606,7 +610,9 @@ |
524 | self.assertEqual(self.client.end_calls, [self.test]) |
525 | self.assertEqual(self.client.error_calls, []) |
526 | self.assertEqual(self.client.failure_calls, []) |
527 | - self.assertEqual(self.client.success_calls, [self.test]) |
528 | + self.assertEqual(self.client.success_calls, []) |
529 | + self.assertEqual(self.client.skip_calls, |
530 | + [(self.test, 'No reason given')]) |
531 | |
532 | def test_simple_skip(self): |
533 | self.simple_skip_keyword("skip") |
534 | @@ -621,7 +627,9 @@ |
535 | self.assertEqual(self.client.end_calls, [self.test]) |
536 | self.assertEqual(self.client.error_calls, []) |
537 | self.assertEqual(self.client.failure_calls, []) |
538 | - self.assertEqual(self.client.success_calls, [self.test]) |
539 | + self.assertEqual(self.client.success_calls, []) |
540 | + self.assertEqual(self.client.skip_calls, |
541 | + [(self.test, "No reason given")]) |
542 | |
543 | def skip_quoted_bracket(self, keyword): |
544 | # This tests it is accepted, but cannot test it is used today, because |
545 | @@ -633,7 +641,9 @@ |
546 | self.assertEqual(self.client.end_calls, [self.test]) |
547 | self.assertEqual(self.client.error_calls, []) |
548 | self.assertEqual(self.client.failure_calls, []) |
549 | - self.assertEqual(self.client.success_calls, [self.test]) |
550 | + self.assertEqual(self.client.success_calls, []) |
551 | + self.assertEqual(self.client.skip_calls, |
552 | + [(self.test, "]\n")]) |
553 | |
554 | def test_skip_quoted_bracket(self): |
555 | self.skip_quoted_bracket("skip") |
556 | @@ -772,7 +782,7 @@ |
557 | self.assertRaises(NotImplementedError, test.tearDown) |
558 | self.assertEqual("A test description", |
559 | test.shortDescription()) |
560 | - self.assertEqual("subunit.RemotedTestCase.A test description", |
561 | + self.assertEqual("A test description", |
562 | test.id()) |
563 | self.assertEqual("A test description (subunit.RemotedTestCase)", "%s" % test) |
564 | self.assertEqual("<subunit.RemotedTestCase description=" |
565 | @@ -933,7 +943,6 @@ |
566 | self.protocol = subunit.TestProtocolClient(self.io) |
567 | self.test = TestTestProtocolClient("test_start_test") |
568 | |
569 | - |
570 | def test_start_test(self): |
571 | """Test startTest on a TestProtocolClient.""" |
572 | self.protocol.startTest(self.test) |
573 | @@ -968,6 +977,14 @@ |
574 | "RemoteException: phwoar crikey\n" |
575 | "]\n" % self.test.id()) |
576 | |
577 | + def test_add_skip(self): |
578 | + """Test addSkip on a TestProtocolClient.""" |
579 | + self.protocol.addSkip( |
580 | + self.test, "Has it really?") |
581 | + self.assertEqual( |
582 | + self.io.getvalue(), |
583 | + 'skip: %s [\nHas it really?\n]\n' % self.test.id()) |
584 | + |
585 | |
586 | def test_suite(): |
587 | loader = subunit.tests.TestUtil.TestLoader() |
This includes filters; best to review after that is reviewed. Also when is that getting reviewed ? :)