2 # subunit: extensions to Python unittest to get test results from subprocesses.
3 # Copyright (C) 2005 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
24 from subunit.content import Content, TracebackContent
25 from subunit.content_type import ContentType
26 import subunit.iso8601 as iso8601
27 from subunit.tests.test_test_results import (
34 class TestTestImports(unittest.TestCase):
36 def test_imports(self):
37 from subunit import DiscardStream
38 from subunit import TestProtocolServer
39 from subunit import RemotedTestCase
40 from subunit import RemoteError
41 from subunit import ExecTestCase
42 from subunit import IsolatedTestCase
43 from subunit import TestProtocolClient
46 class TestDiscardStream(unittest.TestCase):
49 subunit.DiscardStream().write("content")
52 class TestTestProtocolServerPipe(unittest.TestCase):
55 client = unittest.TestResult()
56 protocol = subunit.TestProtocolServer(client)
57 pipe = StringIO("test old mcdonald\n"
58 "success old mcdonald\n"
60 "failure bing crosby [\n"
61 "foo.c:53:ERROR invalid state\n"
65 protocol.readFrom(pipe)
66 mcdonald = subunit.RemotedTestCase("old mcdonald")
67 bing = subunit.RemotedTestCase("bing crosby")
68 an_error = subunit.RemotedTestCase("an error")
69 self.assertEqual(client.errors,
70 [(an_error, 'RemoteException: \n\n')])
73 [(bing, "RemoteException: Text attachment: traceback\n"
74 "------------\nfoo.c:53:ERROR invalid state\n"
76 self.assertEqual(client.testsRun, 3)
79 class TestTestProtocolServerStartTest(unittest.TestCase):
82 self.client = Python26TestResult()
83 self.protocol = subunit.TestProtocolServer(self.client)
85 def test_start_test(self):
86 self.protocol.lineReceived("test old mcdonald\n")
87 self.assertEqual(self.client._calls,
88 [('startTest', subunit.RemotedTestCase("old mcdonald"))])
90 def test_start_testing(self):
91 self.protocol.lineReceived("testing old mcdonald\n")
92 self.assertEqual(self.client._calls,
93 [('startTest', subunit.RemotedTestCase("old mcdonald"))])
95 def test_start_test_colon(self):
96 self.protocol.lineReceived("test: old mcdonald\n")
97 self.assertEqual(self.client._calls,
98 [('startTest', subunit.RemotedTestCase("old mcdonald"))])
100 def test_start_testing_colon(self):
101 self.protocol.lineReceived("testing: old mcdonald\n")
102 self.assertEqual(self.client._calls,
103 [('startTest', subunit.RemotedTestCase("old mcdonald"))])
106 class TestTestProtocolServerPassThrough(unittest.TestCase):
109 self.stdout = StringIO()
110 self.test = subunit.RemotedTestCase("old mcdonald")
111 self.client = ExtendedTestResult()
112 self.protocol = subunit.TestProtocolServer(self.client, self.stdout)
114 def keywords_before_test(self):
115 self.protocol.lineReceived("failure a\n")
116 self.protocol.lineReceived("failure: a\n")
117 self.protocol.lineReceived("error a\n")
118 self.protocol.lineReceived("error: a\n")
119 self.protocol.lineReceived("success a\n")
120 self.protocol.lineReceived("success: a\n")
121 self.protocol.lineReceived("successful a\n")
122 self.protocol.lineReceived("successful: a\n")
123 self.protocol.lineReceived("]\n")
124 self.assertEqual(self.stdout.getvalue(), "failure a\n"
134 def test_keywords_before_test(self):
135 self.keywords_before_test()
136 self.assertEqual(self.client._calls, [])
138 def test_keywords_after_error(self):
139 self.protocol.lineReceived("test old mcdonald\n")
140 self.protocol.lineReceived("error old mcdonald\n")
141 self.keywords_before_test()
143 ('startTest', self.test),
144 ('addError', self.test, {}),
145 ('stopTest', self.test),
146 ], self.client._calls)
148 def test_keywords_after_failure(self):
149 self.protocol.lineReceived("test old mcdonald\n")
150 self.protocol.lineReceived("failure old mcdonald\n")
151 self.keywords_before_test()
152 self.assertEqual(self.client._calls, [
153 ('startTest', self.test),
154 ('addFailure', self.test, {}),
155 ('stopTest', self.test),
158 def test_keywords_after_success(self):
159 self.protocol.lineReceived("test old mcdonald\n")
160 self.protocol.lineReceived("success old mcdonald\n")
161 self.keywords_before_test()
163 ('startTest', self.test),
164 ('addSuccess', self.test),
165 ('stopTest', self.test),
166 ], self.client._calls)
168 def test_keywords_after_test(self):
169 self.protocol.lineReceived("test old mcdonald\n")
170 self.protocol.lineReceived("test old mcdonald\n")
171 self.protocol.lineReceived("failure a\n")
172 self.protocol.lineReceived("failure: a\n")
173 self.protocol.lineReceived("error a\n")
174 self.protocol.lineReceived("error: a\n")
175 self.protocol.lineReceived("success a\n")
176 self.protocol.lineReceived("success: a\n")
177 self.protocol.lineReceived("successful a\n")
178 self.protocol.lineReceived("successful: a\n")
179 self.protocol.lineReceived("]\n")
180 self.protocol.lineReceived("failure old mcdonald\n")
181 self.assertEqual(self.stdout.getvalue(), "test old mcdonald\n"
191 self.assertEqual(self.client._calls, [
192 ('startTest', self.test),
193 ('addFailure', self.test, {}),
194 ('stopTest', self.test),
197 def test_keywords_during_failure(self):
198 # A smoke test to make sure that the details parsers have control
200 self.protocol.lineReceived("test old mcdonald\n")
201 self.protocol.lineReceived("failure: old mcdonald [\n")
202 self.protocol.lineReceived("test old mcdonald\n")
203 self.protocol.lineReceived("failure a\n")
204 self.protocol.lineReceived("failure: a\n")
205 self.protocol.lineReceived("error a\n")
206 self.protocol.lineReceived("error: a\n")
207 self.protocol.lineReceived("success a\n")
208 self.protocol.lineReceived("success: a\n")
209 self.protocol.lineReceived("successful a\n")
210 self.protocol.lineReceived("successful: a\n")
211 self.protocol.lineReceived(" ]\n")
212 self.protocol.lineReceived("]\n")
213 self.assertEqual(self.stdout.getvalue(), "")
215 details['traceback'] = Content(ContentType("text", "x-traceback"),
217 "test old mcdonald\n"
227 self.assertEqual(self.client._calls, [
228 ('startTest', self.test),
229 ('addFailure', self.test, details),
230 ('stopTest', self.test),
233 def test_stdout_passthrough(self):
234 """Lines received which cannot be interpreted as any protocol action
235 should be passed through to sys.stdout.
237 bytes = "randombytes\n"
238 self.protocol.lineReceived(bytes)
239 self.assertEqual(self.stdout.getvalue(), bytes)
242 class TestTestProtocolServerLostConnection(unittest.TestCase):
245 self.client = Python26TestResult()
246 self.protocol = subunit.TestProtocolServer(self.client)
247 self.test = subunit.RemotedTestCase("old mcdonald")
249 def test_lost_connection_no_input(self):
250 self.protocol.lostConnection()
251 self.assertEqual([], self.client._calls)
253 def test_lost_connection_after_start(self):
254 self.protocol.lineReceived("test old mcdonald\n")
255 self.protocol.lostConnection()
256 failure = subunit.RemoteError(
257 "lost connection during test 'old mcdonald'")
259 ('startTest', self.test),
260 ('addError', self.test, failure),
261 ('stopTest', self.test),
262 ], self.client._calls)
264 def test_lost_connected_after_error(self):
265 self.protocol.lineReceived("test old mcdonald\n")
266 self.protocol.lineReceived("error old mcdonald\n")
267 self.protocol.lostConnection()
269 ('startTest', self.test),
270 ('addError', self.test, subunit.RemoteError("")),
271 ('stopTest', self.test),
272 ], self.client._calls)
274 def do_connection_lost(self, outcome, opening):
275 self.protocol.lineReceived("test old mcdonald\n")
276 self.protocol.lineReceived("%s old mcdonald %s" % (outcome, opening))
277 self.protocol.lostConnection()
278 failure = subunit.RemoteError(
279 "lost connection during %s report of test 'old mcdonald'" %
282 ('startTest', self.test),
283 ('addError', self.test, failure),
284 ('stopTest', self.test),
285 ], self.client._calls)
287 def test_lost_connection_during_error(self):
288 self.do_connection_lost("error", "[\n")
290 def test_lost_connection_during_error_details(self):
291 self.do_connection_lost("error", "[ multipart\n")
293 def test_lost_connected_after_failure(self):
294 self.protocol.lineReceived("test old mcdonald\n")
295 self.protocol.lineReceived("failure old mcdonald\n")
296 self.protocol.lostConnection()
298 ('startTest', self.test),
299 ('addFailure', self.test, subunit.RemoteError("")),
300 ('stopTest', self.test),
301 ], self.client._calls)
303 def test_lost_connection_during_failure(self):
304 self.do_connection_lost("failure", "[\n")
306 def test_lost_connection_during_failure_details(self):
307 self.do_connection_lost("failure", "[ multipart\n")
309 def test_lost_connection_after_success(self):
310 self.protocol.lineReceived("test old mcdonald\n")
311 self.protocol.lineReceived("success old mcdonald\n")
312 self.protocol.lostConnection()
314 ('startTest', self.test),
315 ('addSuccess', self.test),
316 ('stopTest', self.test),
317 ], self.client._calls)
319 def test_lost_connection_during_success(self):
320 self.do_connection_lost("success", "[\n")
322 def test_lost_connection_during_success_details(self):
323 self.do_connection_lost("success", "[ multipart\n")
325 def test_lost_connection_during_skip(self):
326 self.do_connection_lost("skip", "[\n")
328 def test_lost_connection_during_skip_details(self):
329 self.do_connection_lost("skip", "[ multipart\n")
331 def test_lost_connection_during_xfail(self):
332 self.do_connection_lost("xfail", "[\n")
334 def test_lost_connection_during_xfail_details(self):
335 self.do_connection_lost("xfail", "[ multipart\n")
338 class TestInTestMultipart(unittest.TestCase):
341 self.client = ExtendedTestResult()
342 self.protocol = subunit.TestProtocolServer(self.client)
343 self.protocol.lineReceived("test mcdonalds farm\n")
344 self.test = subunit.RemotedTestCase("mcdonalds farm")
346 def test__outcome_sets_details_parser(self):
347 self.protocol._reading_success_details.details_parser = None
348 self.protocol._state._outcome(0, "mcdonalds farm [ multipart\n",
349 None, self.protocol._reading_success_details)
350 parser = self.protocol._reading_success_details.details_parser
351 self.assertNotEqual(None, parser)
352 self.assertTrue(isinstance(parser,
353 subunit.details.MultipartDetailsParser))
356 class TestTestProtocolServerAddError(unittest.TestCase):
359 self.client = ExtendedTestResult()
360 self.protocol = subunit.TestProtocolServer(self.client)
361 self.protocol.lineReceived("test mcdonalds farm\n")
362 self.test = subunit.RemotedTestCase("mcdonalds farm")
364 def simple_error_keyword(self, keyword):
365 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
368 ('startTest', self.test),
369 ('addError', self.test, details),
370 ('stopTest', self.test),
371 ], self.client._calls)
373 def test_simple_error(self):
374 self.simple_error_keyword("error")
376 def test_simple_error_colon(self):
377 self.simple_error_keyword("error:")
379 def test_error_empty_message(self):
380 self.protocol.lineReceived("error mcdonalds farm [\n")
381 self.protocol.lineReceived("]\n")
383 details['traceback'] = Content(ContentType("text", "x-traceback"),
386 ('startTest', self.test),
387 ('addError', self.test, details),
388 ('stopTest', self.test),
389 ], self.client._calls)
391 def error_quoted_bracket(self, keyword):
392 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
393 self.protocol.lineReceived(" ]\n")
394 self.protocol.lineReceived("]\n")
396 details['traceback'] = Content(ContentType("text", "x-traceback"),
399 ('startTest', self.test),
400 ('addError', self.test, details),
401 ('stopTest', self.test),
402 ], self.client._calls)
404 def test_error_quoted_bracket(self):
405 self.error_quoted_bracket("error")
407 def test_error_colon_quoted_bracket(self):
408 self.error_quoted_bracket("error:")
411 class TestTestProtocolServerAddFailure(unittest.TestCase):
414 self.client = ExtendedTestResult()
415 self.protocol = subunit.TestProtocolServer(self.client)
416 self.protocol.lineReceived("test mcdonalds farm\n")
417 self.test = subunit.RemotedTestCase("mcdonalds farm")
419 def assertFailure(self, details):
421 ('startTest', self.test),
422 ('addFailure', self.test, details),
423 ('stopTest', self.test),
424 ], self.client._calls)
426 def simple_failure_keyword(self, keyword):
427 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
429 self.assertFailure(details)
431 def test_simple_failure(self):
432 self.simple_failure_keyword("failure")
434 def test_simple_failure_colon(self):
435 self.simple_failure_keyword("failure:")
437 def test_failure_empty_message(self):
438 self.protocol.lineReceived("failure mcdonalds farm [\n")
439 self.protocol.lineReceived("]\n")
441 details['traceback'] = Content(ContentType("text", "x-traceback"),
443 self.assertFailure(details)
445 def failure_quoted_bracket(self, keyword):
446 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
447 self.protocol.lineReceived(" ]\n")
448 self.protocol.lineReceived("]\n")
450 details['traceback'] = Content(ContentType("text", "x-traceback"),
452 self.assertFailure(details)
454 def test_failure_quoted_bracket(self):
455 self.failure_quoted_bracket("failure")
457 def test_failure_colon_quoted_bracket(self):
458 self.failure_quoted_bracket("failure:")
461 class TestTestProtocolServerAddxFail(unittest.TestCase):
462 """Tests for the xfail keyword.
464 In Python this can thunk through to Success due to stdlib limitations (see
468 def capture_expected_failure(self, test, err):
469 self._calls.append((test, err))
471 def setup_python26(self):
472 """Setup a test object ready to be xfailed and thunk to success."""
473 self.client = Python26TestResult()
474 self.setup_protocol()
476 def setup_python27(self):
477 """Setup a test object ready to be xfailed."""
478 self.client = Python27TestResult()
479 self.setup_protocol()
481 def setup_python_ex(self):
482 """Setup a test object ready to be xfailed with details."""
483 self.client = ExtendedTestResult()
484 self.setup_protocol()
486 def setup_protocol(self):
487 """Setup the protocol based on self.client."""
488 self.protocol = subunit.TestProtocolServer(self.client)
489 self.protocol.lineReceived("test mcdonalds farm\n")
490 self.test = self.client._calls[-1][-1]
492 def simple_xfail_keyword(self, keyword, as_success):
493 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
494 self.check_success_or_xfail(as_success)
496 def check_success_or_xfail(self, as_success, error_message=None):
499 ('startTest', self.test),
500 ('addSuccess', self.test),
501 ('stopTest', self.test),
502 ], self.client._calls)
505 if error_message is not None:
506 details['traceback'] = Content(
507 ContentType("text", "x-traceback"), lambda:[error_message])
508 if isinstance(self.client, ExtendedTestResult):
511 if error_message is not None:
512 value = subunit.RemoteError('Text attachment: traceback\n'
513 '------------\n' + error_message + '------------\n')
515 value = subunit.RemoteError()
517 ('startTest', self.test),
518 ('addExpectedFailure', self.test, value),
519 ('stopTest', self.test),
520 ], self.client._calls)
522 def test_simple_xfail(self):
523 self.setup_python26()
524 self.simple_xfail_keyword("xfail", True)
525 self.setup_python27()
526 self.simple_xfail_keyword("xfail", False)
527 self.setup_python_ex()
528 self.simple_xfail_keyword("xfail", False)
530 def test_simple_xfail_colon(self):
531 self.setup_python26()
532 self.simple_xfail_keyword("xfail:", True)
533 self.setup_python27()
534 self.simple_xfail_keyword("xfail:", False)
535 self.setup_python_ex()
536 self.simple_xfail_keyword("xfail:", False)
538 def test_xfail_empty_message(self):
539 self.setup_python26()
540 self.empty_message(True)
541 self.setup_python27()
542 self.empty_message(False)
543 self.setup_python_ex()
544 self.empty_message(False, error_message="")
546 def empty_message(self, as_success, error_message="\n"):
547 self.protocol.lineReceived("xfail mcdonalds farm [\n")
548 self.protocol.lineReceived("]\n")
549 self.check_success_or_xfail(as_success, error_message)
551 def xfail_quoted_bracket(self, keyword, as_success):
552 # This tests it is accepted, but cannot test it is used today, because
553 # of not having a way to expose it in Python so far.
554 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
555 self.protocol.lineReceived(" ]\n")
556 self.protocol.lineReceived("]\n")
557 self.check_success_or_xfail(as_success, "]\n")
559 def test_xfail_quoted_bracket(self):
560 self.setup_python26()
561 self.xfail_quoted_bracket("xfail", True)
562 self.setup_python27()
563 self.xfail_quoted_bracket("xfail", False)
564 self.setup_python_ex()
565 self.xfail_quoted_bracket("xfail", False)
567 def test_xfail_colon_quoted_bracket(self):
568 self.setup_python26()
569 self.xfail_quoted_bracket("xfail:", True)
570 self.setup_python27()
571 self.xfail_quoted_bracket("xfail:", False)
572 self.setup_python_ex()
573 self.xfail_quoted_bracket("xfail:", False)
576 class TestTestProtocolServerAddSkip(unittest.TestCase):
577 """Tests for the skip keyword.
579 In Python this meets the testtools extended TestResult contract.
580 (See https://launchpad.net/testtools).
584 """Setup a test object ready to be skipped."""
585 self.client = ExtendedTestResult()
586 self.protocol = subunit.TestProtocolServer(self.client)
587 self.protocol.lineReceived("test mcdonalds farm\n")
588 self.test = self.client._calls[-1][-1]
590 def assertSkip(self, reason):
592 if reason is not None:
593 details['reason'] = Content(
594 ContentType("text", "plain"), lambda:[reason])
596 ('startTest', self.test),
597 ('addSkip', self.test, details),
598 ('stopTest', self.test),
599 ], self.client._calls)
601 def simple_skip_keyword(self, keyword):
602 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
603 self.assertSkip(None)
605 def test_simple_skip(self):
606 self.simple_skip_keyword("skip")
608 def test_simple_skip_colon(self):
609 self.simple_skip_keyword("skip:")
611 def test_skip_empty_message(self):
612 self.protocol.lineReceived("skip mcdonalds farm [\n")
613 self.protocol.lineReceived("]\n")
616 def skip_quoted_bracket(self, keyword):
617 # This tests it is accepted, but cannot test it is used today, because
618 # of not having a way to expose it in Python so far.
619 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
620 self.protocol.lineReceived(" ]\n")
621 self.protocol.lineReceived("]\n")
622 self.assertSkip("]\n")
624 def test_skip_quoted_bracket(self):
625 self.skip_quoted_bracket("skip")
627 def test_skip_colon_quoted_bracket(self):
628 self.skip_quoted_bracket("skip:")
631 class TestTestProtocolServerAddSuccess(unittest.TestCase):
634 self.client = Python26TestResult()
635 self.protocol = subunit.TestProtocolServer(self.client)
636 self.protocol.lineReceived("test mcdonalds farm\n")
637 self.test = subunit.RemotedTestCase("mcdonalds farm")
639 def simple_success_keyword(self, keyword):
640 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
642 ('startTest', self.test),
643 ('addSuccess', self.test),
644 ('stopTest', self.test),
645 ], self.client._calls)
647 def test_simple_success(self):
648 self.simple_success_keyword("failure")
650 def test_simple_success_colon(self):
651 self.simple_success_keyword("failure:")
653 def test_simple_success(self):
654 self.simple_success_keyword("successful")
656 def test_simple_success_colon(self):
657 self.simple_success_keyword("successful:")
659 def test_success_empty_message(self):
660 self.protocol.lineReceived("success mcdonalds farm [\n")
661 self.protocol.lineReceived("]\n")
663 ('startTest', self.test),
664 ('addSuccess', self.test),
665 ('stopTest', self.test),
666 ], self.client._calls)
668 def success_quoted_bracket(self, keyword):
669 # This tests it is accepted, but cannot test it is used today, because
670 # of not having a way to expose it in Python so far.
671 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
672 self.protocol.lineReceived(" ]\n")
673 self.protocol.lineReceived("]\n")
675 ('startTest', self.test),
676 ('addSuccess', self.test),
677 ('stopTest', self.test),
678 ], self.client._calls)
680 def test_success_quoted_bracket(self):
681 self.success_quoted_bracket("success")
683 def test_success_colon_quoted_bracket(self):
684 self.success_quoted_bracket("success:")
687 class TestTestProtocolServerProgress(unittest.TestCase):
688 """Test receipt of progress: directives."""
690 def test_progress_accepted_stdlib(self):
691 self.result = Python26TestResult()
692 self.stream = StringIO()
693 self.protocol = subunit.TestProtocolServer(self.result,
695 self.protocol.lineReceived("progress: 23")
696 self.protocol.lineReceived("progress: -2")
697 self.protocol.lineReceived("progress: +4")
698 self.assertEqual("", self.stream.getvalue())
700 def test_progress_accepted_extended(self):
701 # With a progress capable TestResult, progress events are emitted.
702 self.result = ExtendedTestResult()
703 self.stream = StringIO()
704 self.protocol = subunit.TestProtocolServer(self.result,
706 self.protocol.lineReceived("progress: 23")
707 self.protocol.lineReceived("progress: push")
708 self.protocol.lineReceived("progress: -2")
709 self.protocol.lineReceived("progress: pop")
710 self.protocol.lineReceived("progress: +4")
711 self.assertEqual("", self.stream.getvalue())
713 ('progress', 23, subunit.PROGRESS_SET),
714 ('progress', None, subunit.PROGRESS_PUSH),
715 ('progress', -2, subunit.PROGRESS_CUR),
716 ('progress', None, subunit.PROGRESS_POP),
717 ('progress', 4, subunit.PROGRESS_CUR),
718 ], self.result._calls)
721 class TestTestProtocolServerStreamTags(unittest.TestCase):
722 """Test managing tags on the protocol level."""
725 self.client = ExtendedTestResult()
726 self.protocol = subunit.TestProtocolServer(self.client)
728 def test_initial_tags(self):
729 self.protocol.lineReceived("tags: foo bar:baz quux\n")
731 ('tags', set(["foo", "bar:baz", "quux"]), set()),
732 ], self.client._calls)
734 def test_minus_removes_tags(self):
735 self.protocol.lineReceived("tags: -bar quux\n")
737 ('tags', set(["quux"]), set(["bar"])),
738 ], self.client._calls)
740 def test_tags_do_not_get_set_on_test(self):
741 self.protocol.lineReceived("test mcdonalds farm\n")
742 test = self.client._calls[0][-1]
743 self.assertEqual(None, getattr(test, 'tags', None))
745 def test_tags_do_not_get_set_on_global_tags(self):
746 self.protocol.lineReceived("tags: foo bar\n")
747 self.protocol.lineReceived("test mcdonalds farm\n")
748 test = self.client._calls[-1][-1]
749 self.assertEqual(None, getattr(test, 'tags', None))
751 def test_tags_get_set_on_test_tags(self):
752 self.protocol.lineReceived("test mcdonalds farm\n")
753 test = self.client._calls[-1][-1]
754 self.protocol.lineReceived("tags: foo bar\n")
755 self.protocol.lineReceived("success mcdonalds farm\n")
756 self.assertEqual(None, getattr(test, 'tags', None))
759 class TestTestProtocolServerStreamTime(unittest.TestCase):
760 """Test managing time information at the protocol level."""
762 def test_time_accepted_stdlib(self):
763 self.result = Python26TestResult()
764 self.stream = StringIO()
765 self.protocol = subunit.TestProtocolServer(self.result,
767 self.protocol.lineReceived("time: 2001-12-12 12:59:59Z\n")
768 self.assertEqual("", self.stream.getvalue())
770 def test_time_accepted_extended(self):
771 self.result = ExtendedTestResult()
772 self.stream = StringIO()
773 self.protocol = subunit.TestProtocolServer(self.result,
775 self.protocol.lineReceived("time: 2001-12-12 12:59:59Z\n")
776 self.assertEqual("", self.stream.getvalue())
778 ('time', datetime.datetime(2001, 12, 12, 12, 59, 59, 0,
780 ], self.result._calls)
783 class TestRemotedTestCase(unittest.TestCase):
785 def test_simple(self):
786 test = subunit.RemotedTestCase("A test description")
787 self.assertRaises(NotImplementedError, test.setUp)
788 self.assertRaises(NotImplementedError, test.tearDown)
789 self.assertEqual("A test description",
790 test.shortDescription())
791 self.assertEqual("A test description",
793 self.assertEqual("A test description (subunit.RemotedTestCase)", "%s" % test)
794 self.assertEqual("<subunit.RemotedTestCase description="
795 "'A test description'>", "%r" % test)
796 result = unittest.TestResult()
798 self.assertEqual([(test, "RemoteException: "
799 "Cannot run RemotedTestCases.\n\n")],
801 self.assertEqual(1, result.testsRun)
802 another_test = subunit.RemotedTestCase("A test description")
803 self.assertEqual(test, another_test)
804 different_test = subunit.RemotedTestCase("ofo")
805 self.assertNotEqual(test, different_test)
806 self.assertNotEqual(another_test, different_test)
809 class TestRemoteError(unittest.TestCase):
812 error = subunit.RemoteError("Something went wrong")
813 another_error = subunit.RemoteError("Something went wrong")
814 different_error = subunit.RemoteError("boo!")
815 self.assertEqual(error, another_error)
816 self.assertNotEqual(error, different_error)
817 self.assertNotEqual(different_error, another_error)
819 def test_empty_constructor(self):
820 self.assertEqual(subunit.RemoteError(), subunit.RemoteError(""))
823 class TestExecTestCase(unittest.TestCase):
825 class SampleExecTestCase(subunit.ExecTestCase):
827 def test_sample_method(self):
828 """sample-script.py"""
829 # the sample script runs three tests, one each
830 # that fails, errors and succeeds
832 def test_sample_method_args(self):
833 """sample-script.py foo"""
834 # sample that will run just one test.
836 def test_construct(self):
837 test = self.SampleExecTestCase("test_sample_method")
838 self.assertEqual(test.script,
839 subunit.join_dir(__file__, 'sample-script.py'))
842 result = unittest.TestResult()
843 test = self.SampleExecTestCase("test_sample_method_args")
845 self.assertEqual(1, result.testsRun)
848 result = ExtendedTestResult()
849 test = self.SampleExecTestCase("test_sample_method")
851 mcdonald = subunit.RemotedTestCase("old mcdonald")
852 bing = subunit.RemotedTestCase("bing crosby")
854 bing_details['traceback'] = Content(ContentType("text", "x-traceback"),
855 lambda:["foo.c:53:ERROR invalid state\n"])
856 an_error = subunit.RemotedTestCase("an error")
859 ('startTest', mcdonald),
860 ('addSuccess', mcdonald),
861 ('stopTest', mcdonald),
863 ('addFailure', bing, bing_details),
865 ('startTest', an_error),
866 ('addError', an_error, error_details),
867 ('stopTest', an_error),
870 def test_debug(self):
871 test = self.SampleExecTestCase("test_sample_method")
874 def test_count_test_cases(self):
875 """TODO run the child process and count responses to determine the count."""
877 def test_join_dir(self):
878 sibling = subunit.join_dir(__file__, 'foo')
879 expected = '%s/foo' % (os.path.split(__file__)[0],)
880 self.assertEqual(sibling, expected)
883 class DoExecTestCase(subunit.ExecTestCase):
885 def test_working_script(self):
886 """sample-two-script.py"""
889 class TestIsolatedTestCase(unittest.TestCase):
891 class SampleIsolatedTestCase(subunit.IsolatedTestCase):
898 TestIsolatedTestCase.SampleIsolatedTestCase.SETUP = True
901 TestIsolatedTestCase.SampleIsolatedTestCase.TEARDOWN = True
903 def test_sets_global_state(self):
904 TestIsolatedTestCase.SampleIsolatedTestCase.TEST = True
907 def test_construct(self):
908 test = self.SampleIsolatedTestCase("test_sets_global_state")
911 result = unittest.TestResult()
912 test = self.SampleIsolatedTestCase("test_sets_global_state")
914 self.assertEqual(result.testsRun, 1)
915 self.assertEqual(self.SampleIsolatedTestCase.SETUP, False)
916 self.assertEqual(self.SampleIsolatedTestCase.TEARDOWN, False)
917 self.assertEqual(self.SampleIsolatedTestCase.TEST, False)
919 def test_debug(self):
921 #test = self.SampleExecTestCase("test_sample_method")
925 class TestIsolatedTestSuite(unittest.TestCase):
927 class SampleTestToIsolate(unittest.TestCase):
934 TestIsolatedTestSuite.SampleTestToIsolate.SETUP = True
937 TestIsolatedTestSuite.SampleTestToIsolate.TEARDOWN = True
939 def test_sets_global_state(self):
940 TestIsolatedTestSuite.SampleTestToIsolate.TEST = True
943 def test_construct(self):
944 suite = subunit.IsolatedTestSuite()
947 result = unittest.TestResult()
948 suite = subunit.IsolatedTestSuite()
949 sub_suite = unittest.TestSuite()
950 sub_suite.addTest(self.SampleTestToIsolate("test_sets_global_state"))
951 sub_suite.addTest(self.SampleTestToIsolate("test_sets_global_state"))
952 suite.addTest(sub_suite)
953 suite.addTest(self.SampleTestToIsolate("test_sets_global_state"))
955 self.assertEqual(result.testsRun, 3)
956 self.assertEqual(self.SampleTestToIsolate.SETUP, False)
957 self.assertEqual(self.SampleTestToIsolate.TEARDOWN, False)
958 self.assertEqual(self.SampleTestToIsolate.TEST, False)
961 class TestTestProtocolClient(unittest.TestCase):
965 self.protocol = subunit.TestProtocolClient(self.io)
966 self.test = TestTestProtocolClient("test_start_test")
967 self.sample_details = {'something':Content(
968 ContentType('text', 'plain'), lambda:['serialised\nform'])}
969 self.sample_tb_details = dict(self.sample_details)
970 self.sample_tb_details['traceback'] = TracebackContent(
971 subunit.RemoteError("boo qux"))
973 def test_start_test(self):
974 """Test startTest on a TestProtocolClient."""
975 self.protocol.startTest(self.test)
976 self.assertEqual(self.io.getvalue(), "test: %s\n" % self.test.id())
978 def test_stop_test(self):
979 # stopTest doesn't output anything.
980 self.protocol.stopTest(self.test)
981 self.assertEqual(self.io.getvalue(), "")
983 def test_add_success(self):
984 """Test addSuccess on a TestProtocolClient."""
985 self.protocol.addSuccess(self.test)
987 self.io.getvalue(), "successful: %s\n" % self.test.id())
989 def test_add_success_details(self):
990 """Test addSuccess on a TestProtocolClient with details."""
991 self.protocol.addSuccess(self.test, details=self.sample_details)
993 self.io.getvalue(), "successful: %s [ multipart\n"
994 "Content-Type: text/plain\n"
996 "F\r\nserialised\nform0\r\n]\n" % self.test.id())
998 def test_add_failure(self):
999 """Test addFailure on a TestProtocolClient."""
1000 self.protocol.addFailure(
1001 self.test, subunit.RemoteError("boo qux"))
1004 'failure: %s [\nRemoteException: boo qux\n]\n' % self.test.id())
1006 def test_add_failure_details(self):
1007 """Test addFailure on a TestProtocolClient with details."""
1008 self.protocol.addFailure(
1009 self.test, details=self.sample_tb_details)
1012 "failure: %s [ multipart\n"
1013 "Content-Type: text/plain\n"
1015 "F\r\nserialised\nform0\r\n"
1016 "Content-Type: text/x-traceback;language=python\n"
1018 "19\r\nRemoteException: boo qux\n0\r\n"
1019 "]\n" % self.test.id())
1021 def test_add_error(self):
1022 """Test stopTest on a TestProtocolClient."""
1023 self.protocol.addError(
1024 self.test, subunit.RemoteError("phwoar crikey"))
1028 "RemoteException: phwoar crikey\n"
1029 "]\n" % self.test.id())
1031 def test_add_error_details(self):
1032 """Test stopTest on a TestProtocolClient with details."""
1033 self.protocol.addError(
1034 self.test, details=self.sample_tb_details)
1037 "error: %s [ multipart\n"
1038 "Content-Type: text/plain\n"
1040 "F\r\nserialised\nform0\r\n"
1041 "Content-Type: text/x-traceback;language=python\n"
1043 "19\r\nRemoteException: boo qux\n0\r\n"
1044 "]\n" % self.test.id())
1046 def test_add_expected_failure(self):
1047 """Test addExpectedFailure on a TestProtocolClient."""
1048 self.protocol.addExpectedFailure(
1049 self.test, subunit.RemoteError("phwoar crikey"))
1053 "RemoteException: phwoar crikey\n"
1054 "]\n" % self.test.id())
1056 def test_add_expected_failure_details(self):
1057 """Test addExpectedFailure on a TestProtocolClient with details."""
1058 self.protocol.addExpectedFailure(
1059 self.test, details=self.sample_tb_details)
1062 "xfail: %s [ multipart\n"
1063 "Content-Type: text/plain\n"
1065 "F\r\nserialised\nform0\r\n"
1066 "Content-Type: text/x-traceback;language=python\n"
1068 "19\r\nRemoteException: boo qux\n0\r\n"
1069 "]\n" % self.test.id())
1071 def test_add_skip(self):
1072 """Test addSkip on a TestProtocolClient."""
1073 self.protocol.addSkip(
1074 self.test, "Has it really?")
1077 'skip: %s [\nHas it really?\n]\n' % self.test.id())
1079 def test_add_skip_details(self):
1080 """Test addSkip on a TestProtocolClient with details."""
1081 details = {'reason':Content(
1082 ContentType('text', 'plain'), lambda:['Has it really?'])}
1083 self.protocol.addSkip(
1084 self.test, details=details)
1087 "skip: %s [ multipart\n"
1088 "Content-Type: text/plain\n"
1090 "E\r\nHas it really?0\r\n"
1091 "]\n" % self.test.id())
1093 def test_progress_set(self):
1094 self.protocol.progress(23, subunit.PROGRESS_SET)
1095 self.assertEqual(self.io.getvalue(), 'progress: 23\n')
1097 def test_progress_neg_cur(self):
1098 self.protocol.progress(-23, subunit.PROGRESS_CUR)
1099 self.assertEqual(self.io.getvalue(), 'progress: -23\n')
1101 def test_progress_pos_cur(self):
1102 self.protocol.progress(23, subunit.PROGRESS_CUR)
1103 self.assertEqual(self.io.getvalue(), 'progress: +23\n')
1105 def test_progress_pop(self):
1106 self.protocol.progress(1234, subunit.PROGRESS_POP)
1107 self.assertEqual(self.io.getvalue(), 'progress: pop\n')
1109 def test_progress_push(self):
1110 self.protocol.progress(1234, subunit.PROGRESS_PUSH)
1111 self.assertEqual(self.io.getvalue(), 'progress: push\n')
1113 def test_time(self):
1114 # Calling time() outputs a time signal immediately.
1116 datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc()))
1118 "time: 2009-10-11 12:13:14.000015Z\n",
1121 def test_add_unexpected_success(self):
1122 """Test addUnexpectedSuccess on a TestProtocolClient."""
1123 self.protocol.addUnexpectedSuccess(self.test)
1125 self.io.getvalue(), "successful: %s\n" % self.test.id())
1127 def test_add_unexpected_success_details(self):
1128 """Test addUnexpectedSuccess on a TestProtocolClient with details."""
1129 self.protocol.addUnexpectedSuccess(self.test, details=self.sample_details)
1131 self.io.getvalue(), "successful: %s [ multipart\n"
1132 "Content-Type: text/plain\n"
1134 "F\r\nserialised\nform0\r\n]\n" % self.test.id())
1138 loader = subunit.tests.TestUtil.TestLoader()
1139 result = loader.loadTestsFromName(__name__)