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
29 class MockTestProtocolServerClient(object):
30 """A mock protocol server client to test callbacks.
32 Note that this is deliberately not Python 2.7 complete, to allow
33 testing compatibility - we need a TestResult that will not have new methods
34 like addExpectedFailure.
40 self.failure_calls = []
43 self.success_calls = []
44 self.progress_calls = []
46 super(MockTestProtocolServerClient, self).__init__()
48 def addError(self, test, error):
49 self.error_calls.append((test, error))
51 def addFailure(self, test, error):
52 self.failure_calls.append((test, error))
54 def addSkip(self, test, reason):
55 self.skip_calls.append((test, reason))
57 def addSuccess(self, test):
58 self.success_calls.append(test)
60 def stopTest(self, test):
61 self.end_calls.append(test)
63 def startTest(self, test):
64 self.start_calls.append(test)
66 def progress(self, offset, whence):
67 self.progress_calls.append((offset, whence))
73 class MockExtendedTestProtocolServerClient(MockTestProtocolServerClient):
74 """An extended TestResult for testing which implements tags() etc."""
77 MockTestProtocolServerClient.__init__(self)
79 self.gone_tags = set()
81 def tags(self, new_tags, gone_tags):
82 self.new_tags = new_tags
83 self.gone_tags = gone_tags
86 class TestMockTestProtocolServer(unittest.TestCase):
88 def test_start_test(self):
89 protocol = MockTestProtocolServerClient()
90 protocol.startTest(subunit.RemotedTestCase("test old mcdonald"))
91 self.assertEqual(protocol.start_calls,
92 [subunit.RemotedTestCase("test old mcdonald")])
93 self.assertEqual(protocol.end_calls, [])
94 self.assertEqual(protocol.error_calls, [])
95 self.assertEqual(protocol.failure_calls, [])
96 self.assertEqual(protocol.success_calls, [])
98 def test_add_error(self):
99 protocol = MockTestProtocolServerClient()
100 protocol.addError(subunit.RemotedTestCase("old mcdonald"),
101 subunit.RemoteError("omg it works"))
102 self.assertEqual(protocol.start_calls, [])
103 self.assertEqual(protocol.end_calls, [])
104 self.assertEqual(protocol.error_calls, [(
105 subunit.RemotedTestCase("old mcdonald"),
106 subunit.RemoteError("omg it works"))])
107 self.assertEqual(protocol.failure_calls, [])
108 self.assertEqual(protocol.success_calls, [])
110 def test_add_failure(self):
111 protocol = MockTestProtocolServerClient()
112 protocol.addFailure(subunit.RemotedTestCase("old mcdonald"),
113 subunit.RemoteError("omg it works"))
114 self.assertEqual(protocol.start_calls, [])
115 self.assertEqual(protocol.end_calls, [])
116 self.assertEqual(protocol.error_calls, [])
117 self.assertEqual(protocol.failure_calls, [
118 (subunit.RemotedTestCase("old mcdonald"),
119 subunit.RemoteError("omg it works"))])
120 self.assertEqual(protocol.success_calls, [])
122 def test_add_success(self):
123 protocol = MockTestProtocolServerClient()
124 protocol.addSuccess(subunit.RemotedTestCase("test old mcdonald"))
125 self.assertEqual(protocol.start_calls, [])
126 self.assertEqual(protocol.end_calls, [])
127 self.assertEqual(protocol.error_calls, [])
128 self.assertEqual(protocol.failure_calls, [])
129 self.assertEqual(protocol.success_calls,
130 [subunit.RemotedTestCase("test old mcdonald")])
132 def test_end_test(self):
133 protocol = MockTestProtocolServerClient()
134 protocol.stopTest(subunit.RemotedTestCase("test old mcdonald"))
135 self.assertEqual(protocol.end_calls,
136 [subunit.RemotedTestCase("test old mcdonald")])
137 self.assertEqual(protocol.error_calls, [])
138 self.assertEqual(protocol.failure_calls, [])
139 self.assertEqual(protocol.success_calls, [])
140 self.assertEqual(protocol.start_calls, [])
142 def test_progress(self):
143 protocol = MockTestProtocolServerClient()
144 protocol.progress(-1, subunit.PROGRESS_CUR)
145 self.assertEqual(protocol.progress_calls, [(-1, subunit.PROGRESS_CUR)])
148 class TestTestImports(unittest.TestCase):
150 def test_imports(self):
151 from subunit import DiscardStream
152 from subunit import TestProtocolServer
153 from subunit import RemotedTestCase
154 from subunit import RemoteError
155 from subunit import ExecTestCase
156 from subunit import IsolatedTestCase
157 from subunit import TestProtocolClient
160 class TestDiscardStream(unittest.TestCase):
162 def test_write(self):
163 subunit.DiscardStream().write("content")
166 class TestTestProtocolServerPipe(unittest.TestCase):
168 def test_story(self):
169 client = unittest.TestResult()
170 protocol = subunit.TestProtocolServer(client)
171 pipe = StringIO("test old mcdonald\n"
172 "success old mcdonald\n"
174 "failure bing crosby [\n"
175 "foo.c:53:ERROR invalid state\n"
179 protocol.readFrom(pipe)
180 mcdonald = subunit.RemotedTestCase("old mcdonald")
181 bing = subunit.RemotedTestCase("bing crosby")
182 an_error = subunit.RemotedTestCase("an error")
183 self.assertEqual(client.errors,
184 [(an_error, 'RemoteException: \n\n')])
187 [(bing, "RemoteException: foo.c:53:ERROR invalid state\n\n")])
188 self.assertEqual(client.testsRun, 3)
191 class TestTestProtocolServerStartTest(unittest.TestCase):
194 self.client = MockTestProtocolServerClient()
195 self.protocol = subunit.TestProtocolServer(self.client)
197 def test_start_test(self):
198 self.protocol.lineReceived("test old mcdonald\n")
199 self.assertEqual(self.client.start_calls,
200 [subunit.RemotedTestCase("old mcdonald")])
202 def test_start_testing(self):
203 self.protocol.lineReceived("testing old mcdonald\n")
204 self.assertEqual(self.client.start_calls,
205 [subunit.RemotedTestCase("old mcdonald")])
207 def test_start_test_colon(self):
208 self.protocol.lineReceived("test: old mcdonald\n")
209 self.assertEqual(self.client.start_calls,
210 [subunit.RemotedTestCase("old mcdonald")])
212 def test_start_testing_colon(self):
213 self.protocol.lineReceived("testing: old mcdonald\n")
214 self.assertEqual(self.client.start_calls,
215 [subunit.RemotedTestCase("old mcdonald")])
218 class TestTestProtocolServerPassThrough(unittest.TestCase):
221 self.stdout = StringIO()
222 self.test = subunit.RemotedTestCase("old mcdonald")
223 self.client = MockTestProtocolServerClient()
224 self.protocol = subunit.TestProtocolServer(self.client, self.stdout)
226 def keywords_before_test(self):
227 self.protocol.lineReceived("failure a\n")
228 self.protocol.lineReceived("failure: a\n")
229 self.protocol.lineReceived("error a\n")
230 self.protocol.lineReceived("error: a\n")
231 self.protocol.lineReceived("success a\n")
232 self.protocol.lineReceived("success: a\n")
233 self.protocol.lineReceived("successful a\n")
234 self.protocol.lineReceived("successful: a\n")
235 self.protocol.lineReceived("]\n")
236 self.assertEqual(self.stdout.getvalue(), "failure a\n"
246 def test_keywords_before_test(self):
247 self.keywords_before_test()
248 self.assertEqual(self.client.start_calls, [])
249 self.assertEqual(self.client.error_calls, [])
250 self.assertEqual(self.client.failure_calls, [])
251 self.assertEqual(self.client.success_calls, [])
253 def test_keywords_after_error(self):
254 self.protocol.lineReceived("test old mcdonald\n")
255 self.protocol.lineReceived("error old mcdonald\n")
256 self.keywords_before_test()
257 self.assertEqual(self.client.start_calls, [self.test])
258 self.assertEqual(self.client.end_calls, [self.test])
259 self.assertEqual(self.client.error_calls,
260 [(self.test, subunit.RemoteError(""))])
261 self.assertEqual(self.client.failure_calls, [])
262 self.assertEqual(self.client.success_calls, [])
264 def test_keywords_after_failure(self):
265 self.protocol.lineReceived("test old mcdonald\n")
266 self.protocol.lineReceived("failure old mcdonald\n")
267 self.keywords_before_test()
268 self.assertEqual(self.client.start_calls, [self.test])
269 self.assertEqual(self.client.end_calls, [self.test])
270 self.assertEqual(self.client.error_calls, [])
271 self.assertEqual(self.client.failure_calls,
272 [(self.test, subunit.RemoteError())])
273 self.assertEqual(self.client.success_calls, [])
275 def test_keywords_after_success(self):
276 self.protocol.lineReceived("test old mcdonald\n")
277 self.protocol.lineReceived("success old mcdonald\n")
278 self.keywords_before_test()
279 self.assertEqual(self.client.start_calls, [self.test])
280 self.assertEqual(self.client.end_calls, [self.test])
281 self.assertEqual(self.client.error_calls, [])
282 self.assertEqual(self.client.failure_calls, [])
283 self.assertEqual(self.client.success_calls, [self.test])
285 def test_keywords_after_test(self):
286 self.protocol.lineReceived("test old mcdonald\n")
287 self.protocol.lineReceived("test old mcdonald\n")
288 self.protocol.lineReceived("failure a\n")
289 self.protocol.lineReceived("failure: a\n")
290 self.protocol.lineReceived("error a\n")
291 self.protocol.lineReceived("error: a\n")
292 self.protocol.lineReceived("success a\n")
293 self.protocol.lineReceived("success: a\n")
294 self.protocol.lineReceived("successful a\n")
295 self.protocol.lineReceived("successful: a\n")
296 self.protocol.lineReceived("]\n")
297 self.protocol.lineReceived("failure old mcdonald\n")
298 self.assertEqual(self.stdout.getvalue(), "test old mcdonald\n"
308 self.assertEqual(self.client.start_calls, [self.test])
309 self.assertEqual(self.client.end_calls, [self.test])
310 self.assertEqual(self.client.failure_calls,
311 [(self.test, subunit.RemoteError())])
312 self.assertEqual(self.client.error_calls, [])
313 self.assertEqual(self.client.success_calls, [])
315 def test_keywords_during_failure(self):
316 self.protocol.lineReceived("test old mcdonald\n")
317 self.protocol.lineReceived("failure: old mcdonald [\n")
318 self.protocol.lineReceived("test old mcdonald\n")
319 self.protocol.lineReceived("failure a\n")
320 self.protocol.lineReceived("failure: a\n")
321 self.protocol.lineReceived("error a\n")
322 self.protocol.lineReceived("error: a\n")
323 self.protocol.lineReceived("success a\n")
324 self.protocol.lineReceived("success: a\n")
325 self.protocol.lineReceived("successful a\n")
326 self.protocol.lineReceived("successful: a\n")
327 self.protocol.lineReceived(" ]\n")
328 self.protocol.lineReceived("]\n")
329 self.assertEqual(self.stdout.getvalue(), "")
330 self.assertEqual(self.client.start_calls, [self.test])
331 self.assertEqual(self.client.failure_calls,
332 [(self.test, subunit.RemoteError("test old mcdonald\n"
342 self.assertEqual(self.client.end_calls, [self.test])
343 self.assertEqual(self.client.error_calls, [])
344 self.assertEqual(self.client.success_calls, [])
346 def test_stdout_passthrough(self):
347 """Lines received which cannot be interpreted as any protocol action
348 should be passed through to sys.stdout.
350 bytes = "randombytes\n"
351 self.protocol.lineReceived(bytes)
352 self.assertEqual(self.stdout.getvalue(), bytes)
355 class TestTestProtocolServerLostConnection(unittest.TestCase):
358 self.client = MockTestProtocolServerClient()
359 self.protocol = subunit.TestProtocolServer(self.client)
360 self.test = subunit.RemotedTestCase("old mcdonald")
362 def test_lost_connection_no_input(self):
363 self.protocol.lostConnection()
364 self.assertEqual(self.client.start_calls, [])
365 self.assertEqual(self.client.error_calls, [])
366 self.assertEqual(self.client.failure_calls, [])
367 self.assertEqual(self.client.success_calls, [])
369 def test_lost_connection_after_start(self):
370 self.protocol.lineReceived("test old mcdonald\n")
371 self.protocol.lostConnection()
372 self.assertEqual(self.client.start_calls, [self.test])
373 self.assertEqual(self.client.end_calls, [self.test])
374 self.assertEqual(self.client.error_calls, [
375 (self.test, subunit.RemoteError("lost connection during "
376 "test 'old mcdonald'"))])
377 self.assertEqual(self.client.failure_calls, [])
378 self.assertEqual(self.client.success_calls, [])
380 def test_lost_connected_after_error(self):
381 self.protocol.lineReceived("test old mcdonald\n")
382 self.protocol.lineReceived("error old mcdonald\n")
383 self.protocol.lostConnection()
384 self.assertEqual(self.client.start_calls, [self.test])
385 self.assertEqual(self.client.failure_calls, [])
386 self.assertEqual(self.client.end_calls, [self.test])
387 self.assertEqual(self.client.error_calls, [
388 (self.test, subunit.RemoteError(""))])
389 self.assertEqual(self.client.success_calls, [])
391 def test_lost_connection_during_error(self):
392 self.protocol.lineReceived("test old mcdonald\n")
393 self.protocol.lineReceived("error old mcdonald [\n")
394 self.protocol.lostConnection()
395 self.assertEqual(self.client.start_calls, [self.test])
396 self.assertEqual(self.client.end_calls, [self.test])
397 self.assertEqual(self.client.error_calls, [
398 (self.test, subunit.RemoteError("lost connection during error "
399 "report of test 'old mcdonald'"))])
400 self.assertEqual(self.client.failure_calls, [])
401 self.assertEqual(self.client.success_calls, [])
403 def test_lost_connected_after_failure(self):
404 self.protocol.lineReceived("test old mcdonald\n")
405 self.protocol.lineReceived("failure old mcdonald\n")
406 self.protocol.lostConnection()
407 test = subunit.RemotedTestCase("old mcdonald")
408 self.assertEqual(self.client.start_calls, [self.test])
409 self.assertEqual(self.client.end_calls, [self.test])
410 self.assertEqual(self.client.error_calls, [])
411 self.assertEqual(self.client.failure_calls,
412 [(self.test, subunit.RemoteError())])
413 self.assertEqual(self.client.success_calls, [])
415 def test_lost_connection_during_failure(self):
416 self.protocol.lineReceived("test old mcdonald\n")
417 self.protocol.lineReceived("failure old mcdonald [\n")
418 self.protocol.lostConnection()
419 self.assertEqual(self.client.start_calls, [self.test])
420 self.assertEqual(self.client.end_calls, [self.test])
421 self.assertEqual(self.client.error_calls,
423 subunit.RemoteError("lost connection during "
425 " of test 'old mcdonald'"))])
426 self.assertEqual(self.client.failure_calls, [])
427 self.assertEqual(self.client.success_calls, [])
429 def test_lost_connection_after_success(self):
430 self.protocol.lineReceived("test old mcdonald\n")
431 self.protocol.lineReceived("success old mcdonald\n")
432 self.protocol.lostConnection()
433 self.assertEqual(self.client.start_calls, [self.test])
434 self.assertEqual(self.client.end_calls, [self.test])
435 self.assertEqual(self.client.error_calls, [])
436 self.assertEqual(self.client.failure_calls, [])
437 self.assertEqual(self.client.success_calls, [self.test])
439 def test_lost_connection_during_skip(self):
440 self.protocol.lineReceived("test old mcdonald\n")
441 self.protocol.lineReceived("skip old mcdonald [\n")
442 self.protocol.lostConnection()
443 self.assertEqual(self.client.start_calls, [self.test])
444 self.assertEqual(self.client.end_calls, [self.test])
445 self.assertEqual(self.client.error_calls, [
446 (self.test, subunit.RemoteError("lost connection during skip "
447 "report of test 'old mcdonald'"))])
448 self.assertEqual(self.client.failure_calls, [])
449 self.assertEqual(self.client.success_calls, [])
451 def test_lost_connection_during_xfail(self):
452 self.protocol.lineReceived("test old mcdonald\n")
453 self.protocol.lineReceived("xfail old mcdonald [\n")
454 self.protocol.lostConnection()
455 self.assertEqual(self.client.start_calls, [self.test])
456 self.assertEqual(self.client.end_calls, [self.test])
457 self.assertEqual(self.client.error_calls, [
458 (self.test, subunit.RemoteError("lost connection during xfail "
459 "report of test 'old mcdonald'"))])
460 self.assertEqual(self.client.failure_calls, [])
461 self.assertEqual(self.client.success_calls, [])
463 def test_lost_connection_during_success(self):
464 self.protocol.lineReceived("test old mcdonald\n")
465 self.protocol.lineReceived("success old mcdonald [\n")
466 self.protocol.lostConnection()
467 self.assertEqual(self.client.start_calls, [self.test])
468 self.assertEqual(self.client.end_calls, [self.test])
469 self.assertEqual(self.client.error_calls, [
470 (self.test, subunit.RemoteError("lost connection during success "
471 "report of test 'old mcdonald'"))])
472 self.assertEqual(self.client.failure_calls, [])
473 self.assertEqual(self.client.success_calls, [])
476 class TestTestProtocolServerAddError(unittest.TestCase):
479 self.client = MockTestProtocolServerClient()
480 self.protocol = subunit.TestProtocolServer(self.client)
481 self.protocol.lineReceived("test mcdonalds farm\n")
482 self.test = subunit.RemotedTestCase("mcdonalds farm")
484 def simple_error_keyword(self, keyword):
485 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
486 self.assertEqual(self.client.start_calls, [self.test])
487 self.assertEqual(self.client.end_calls, [self.test])
488 self.assertEqual(self.client.error_calls, [
489 (self.test, subunit.RemoteError(""))])
490 self.assertEqual(self.client.failure_calls, [])
492 def test_simple_error(self):
493 self.simple_error_keyword("error")
495 def test_simple_error_colon(self):
496 self.simple_error_keyword("error:")
498 def test_error_empty_message(self):
499 self.protocol.lineReceived("error mcdonalds farm [\n")
500 self.protocol.lineReceived("]\n")
501 self.assertEqual(self.client.start_calls, [self.test])
502 self.assertEqual(self.client.end_calls, [self.test])
503 self.assertEqual(self.client.error_calls, [
504 (self.test, subunit.RemoteError(""))])
505 self.assertEqual(self.client.failure_calls, [])
507 def error_quoted_bracket(self, keyword):
508 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
509 self.protocol.lineReceived(" ]\n")
510 self.protocol.lineReceived("]\n")
511 self.assertEqual(self.client.start_calls, [self.test])
512 self.assertEqual(self.client.end_calls, [self.test])
513 self.assertEqual(self.client.error_calls, [
514 (self.test, subunit.RemoteError("]\n"))])
515 self.assertEqual(self.client.failure_calls, [])
517 def test_error_quoted_bracket(self):
518 self.error_quoted_bracket("error")
520 def test_error_colon_quoted_bracket(self):
521 self.error_quoted_bracket("error:")
524 class TestTestProtocolServerAddFailure(unittest.TestCase):
527 self.client = MockTestProtocolServerClient()
528 self.protocol = subunit.TestProtocolServer(self.client)
529 self.protocol.lineReceived("test mcdonalds farm\n")
530 self.test = subunit.RemotedTestCase("mcdonalds farm")
532 def simple_failure_keyword(self, keyword):
533 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
534 self.assertEqual(self.client.start_calls, [self.test])
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.test, subunit.RemoteError())])
540 def test_simple_failure(self):
541 self.simple_failure_keyword("failure")
543 def test_simple_failure_colon(self):
544 self.simple_failure_keyword("failure:")
546 def test_failure_empty_message(self):
547 self.protocol.lineReceived("failure mcdonalds farm [\n")
548 self.protocol.lineReceived("]\n")
549 self.assertEqual(self.client.start_calls, [self.test])
550 self.assertEqual(self.client.end_calls, [self.test])
551 self.assertEqual(self.client.error_calls, [])
552 self.assertEqual(self.client.failure_calls,
553 [(self.test, subunit.RemoteError())])
555 def failure_quoted_bracket(self, keyword):
556 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
557 self.protocol.lineReceived(" ]\n")
558 self.protocol.lineReceived("]\n")
559 self.assertEqual(self.client.start_calls, [self.test])
560 self.assertEqual(self.client.end_calls, [self.test])
561 self.assertEqual(self.client.error_calls, [])
562 self.assertEqual(self.client.failure_calls,
563 [(self.test, subunit.RemoteError("]\n"))])
565 def test_failure_quoted_bracket(self):
566 self.failure_quoted_bracket("failure")
568 def test_failure_colon_quoted_bracket(self):
569 self.failure_quoted_bracket("failure:")
572 class TestTestProtocolServerAddxFail(unittest.TestCase):
573 """Tests for the xfail keyword.
575 In Python this can thunk through to Success due to stdlib limitations (see
579 def capture_expected_failure(self, test, err):
580 self._calls.append((test, err))
582 def setup_python26(self):
583 """Setup a test object ready to be xfailed and thunk to success."""
584 self.client = MockTestProtocolServerClient()
585 self.setup_protocol()
587 def setup_python27(self):
588 """Setup a test object ready to be xfailed and thunk to success."""
589 self.client = MockTestProtocolServerClient()
590 self.client.addExpectedFailure = self.capture_expected_failure
592 self.setup_protocol()
594 def setup_protocol(self):
595 """Setup the protocol based on self.client."""
596 self.protocol = subunit.TestProtocolServer(self.client)
597 self.protocol.lineReceived("test mcdonalds farm\n")
598 self.test = self.client.start_calls[-1]
600 def simple_xfail_keyword(self, keyword, as_success):
601 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
602 self.assertEqual(self.client.start_calls, [self.test])
603 self.assertEqual(self.client.end_calls, [self.test])
604 self.assertEqual(self.client.error_calls, [])
605 self.assertEqual(self.client.failure_calls, [])
606 self.check_success_or_xfail(as_success)
608 def check_success_or_xfail(self, as_success):
610 self.assertEqual(self.client.success_calls, [self.test])
612 self.assertEqual(1, len(self._calls))
613 self.assertEqual(self.test, self._calls[0][0])
615 def test_simple_xfail(self):
616 self.setup_python26()
617 self.simple_xfail_keyword("xfail", True)
618 self.setup_python27()
619 self.simple_xfail_keyword("xfail", False)
621 def test_simple_xfail_colon(self):
622 self.setup_python26()
623 self.simple_xfail_keyword("xfail:", True)
624 self.setup_python27()
625 self.simple_xfail_keyword("xfail:", False)
627 def test_xfail_empty_message(self):
628 self.setup_python26()
629 self.empty_message(True)
630 self.setup_python27()
631 self.empty_message(False)
633 def empty_message(self, as_success):
634 self.protocol.lineReceived("xfail mcdonalds farm [\n")
635 self.protocol.lineReceived("]\n")
636 self.assertEqual(self.client.start_calls, [self.test])
637 self.assertEqual(self.client.end_calls, [self.test])
638 self.assertEqual(self.client.error_calls, [])
639 self.assertEqual(self.client.failure_calls, [])
640 self.check_success_or_xfail(as_success)
642 def xfail_quoted_bracket(self, keyword, as_success):
643 # This tests it is accepted, but cannot test it is used today, because
644 # of not having a way to expose it in Python so far.
645 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
646 self.protocol.lineReceived(" ]\n")
647 self.protocol.lineReceived("]\n")
648 self.assertEqual(self.client.start_calls, [self.test])
649 self.assertEqual(self.client.end_calls, [self.test])
650 self.assertEqual(self.client.error_calls, [])
651 self.assertEqual(self.client.failure_calls, [])
652 self.check_success_or_xfail(as_success)
654 def test_xfail_quoted_bracket(self):
655 self.setup_python26()
656 self.xfail_quoted_bracket("xfail", True)
657 self.setup_python27()
658 self.xfail_quoted_bracket("xfail", False)
660 def test_xfail_colon_quoted_bracket(self):
661 self.setup_python26()
662 self.xfail_quoted_bracket("xfail:", True)
663 self.setup_python27()
664 self.xfail_quoted_bracket("xfail:", False)
667 class TestTestProtocolServerAddSkip(unittest.TestCase):
668 """Tests for the skip keyword.
670 In Python this meets the testtools extended TestResult contract.
671 (See https://launchpad.net/testtools).
675 """Setup a test object ready to be skipped."""
676 self.client = MockTestProtocolServerClient()
677 self.protocol = subunit.TestProtocolServer(self.client)
678 self.protocol.lineReceived("test mcdonalds farm\n")
679 self.test = self.client.start_calls[-1]
681 def simple_skip_keyword(self, keyword):
682 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
683 self.assertEqual(self.client.start_calls, [self.test])
684 self.assertEqual(self.client.end_calls, [self.test])
685 self.assertEqual(self.client.error_calls, [])
686 self.assertEqual(self.client.failure_calls, [])
687 self.assertEqual(self.client.success_calls, [])
688 self.assertEqual(self.client.skip_calls,
689 [(self.test, 'No reason given')])
691 def test_simple_skip(self):
692 self.simple_skip_keyword("skip")
694 def test_simple_skip_colon(self):
695 self.simple_skip_keyword("skip:")
697 def test_skip_empty_message(self):
698 self.protocol.lineReceived("skip mcdonalds farm [\n")
699 self.protocol.lineReceived("]\n")
700 self.assertEqual(self.client.start_calls, [self.test])
701 self.assertEqual(self.client.end_calls, [self.test])
702 self.assertEqual(self.client.error_calls, [])
703 self.assertEqual(self.client.failure_calls, [])
704 self.assertEqual(self.client.success_calls, [])
705 self.assertEqual(self.client.skip_calls,
706 [(self.test, "No reason given")])
708 def skip_quoted_bracket(self, keyword):
709 # This tests it is accepted, but cannot test it is used today, because
710 # of not having a way to expose it in Python so far.
711 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
712 self.protocol.lineReceived(" ]\n")
713 self.protocol.lineReceived("]\n")
714 self.assertEqual(self.client.start_calls, [self.test])
715 self.assertEqual(self.client.end_calls, [self.test])
716 self.assertEqual(self.client.error_calls, [])
717 self.assertEqual(self.client.failure_calls, [])
718 self.assertEqual(self.client.success_calls, [])
719 self.assertEqual(self.client.skip_calls,
720 [(self.test, "]\n")])
722 def test_skip_quoted_bracket(self):
723 self.skip_quoted_bracket("skip")
725 def test_skip_colon_quoted_bracket(self):
726 self.skip_quoted_bracket("skip:")
729 class TestTestProtocolServerAddSuccess(unittest.TestCase):
732 self.client = MockTestProtocolServerClient()
733 self.protocol = subunit.TestProtocolServer(self.client)
734 self.protocol.lineReceived("test mcdonalds farm\n")
735 self.test = subunit.RemotedTestCase("mcdonalds farm")
737 def simple_success_keyword(self, keyword):
738 self.protocol.lineReceived("%s mcdonalds farm\n" % keyword)
739 self.assertEqual(self.client.start_calls, [self.test])
740 self.assertEqual(self.client.end_calls, [self.test])
741 self.assertEqual(self.client.error_calls, [])
742 self.assertEqual(self.client.success_calls, [self.test])
744 def test_simple_success(self):
745 self.simple_success_keyword("failure")
747 def test_simple_success_colon(self):
748 self.simple_success_keyword("failure:")
750 def test_simple_success(self):
751 self.simple_success_keyword("successful")
753 def test_simple_success_colon(self):
754 self.simple_success_keyword("successful:")
756 def test_success_empty_message(self):
757 self.protocol.lineReceived("success mcdonalds farm [\n")
758 self.protocol.lineReceived("]\n")
759 self.assertEqual(self.client.start_calls, [self.test])
760 self.assertEqual(self.client.end_calls, [self.test])
761 self.assertEqual(self.client.error_calls, [])
762 self.assertEqual(self.client.failure_calls, [])
763 self.assertEqual(self.client.success_calls, [self.test])
765 def success_quoted_bracket(self, keyword):
766 # This tests it is accepted, but cannot test it is used today, because
767 # of not having a way to expose it in Python so far.
768 self.protocol.lineReceived("%s mcdonalds farm [\n" % keyword)
769 self.protocol.lineReceived(" ]\n")
770 self.protocol.lineReceived("]\n")
771 self.assertEqual(self.client.start_calls, [self.test])
772 self.assertEqual(self.client.end_calls, [self.test])
773 self.assertEqual(self.client.error_calls, [])
774 self.assertEqual(self.client.failure_calls, [])
775 self.assertEqual(self.client.success_calls, [self.test])
777 def test_success_quoted_bracket(self):
778 self.success_quoted_bracket("success")
780 def test_success_colon_quoted_bracket(self):
781 self.success_quoted_bracket("success:")
784 class TestTestProtocolServerProgress(unittest.TestCase):
785 """Test receipt of progress: directives."""
787 def test_progress_accepted_stdlib(self):
788 # With a stdlib TestResult, progress events are swallowed.
789 self.result = unittest.TestResult()
790 self.stream = StringIO()
791 self.protocol = subunit.TestProtocolServer(self.result,
793 self.protocol.lineReceived("progress: 23")
794 self.protocol.lineReceived("progress: -2")
795 self.protocol.lineReceived("progress: +4")
796 self.assertEqual("", self.stream.getvalue())
798 def test_progress_accepted_extended(self):
799 # With a progress capable TestResult, progress events are emitted.
800 self.result = MockTestProtocolServerClient()
801 self.stream = StringIO()
802 self.protocol = subunit.TestProtocolServer(self.result,
804 self.protocol.lineReceived("progress: 23")
805 self.protocol.lineReceived("progress: push")
806 self.protocol.lineReceived("progress: -2")
807 self.protocol.lineReceived("progress: pop")
808 self.protocol.lineReceived("progress: +4")
809 self.assertEqual("", self.stream.getvalue())
811 [(23, subunit.PROGRESS_SET), (None, subunit.PROGRESS_PUSH),
812 (-2, subunit.PROGRESS_CUR), (None, subunit.PROGRESS_POP),
813 (4, subunit.PROGRESS_CUR)],
814 self.result.progress_calls)
817 class TestTestProtocolServerStreamTags(unittest.TestCase):
818 """Test managing tags on the protocol level."""
821 self.client = MockExtendedTestProtocolServerClient()
822 self.protocol = subunit.TestProtocolServer(self.client)
824 def test_initial_tags(self):
825 self.protocol.lineReceived("tags: foo bar:baz quux\n")
826 self.assertEqual(set(["foo", "bar:baz", "quux"]),
827 self.client.new_tags)
828 self.assertEqual(set(), self.client.gone_tags)
830 def test_minus_removes_tags(self):
831 self.protocol.lineReceived("tags: foo bar\n")
832 self.assertEqual(set(["foo", "bar"]),
833 self.client.new_tags)
834 self.assertEqual(set(), self.client.gone_tags)
835 self.protocol.lineReceived("tags: -bar quux\n")
836 self.assertEqual(set(["quux"]), self.client.new_tags)
837 self.assertEqual(set(["bar"]), self.client.gone_tags)
839 def test_tags_do_not_get_set_on_test(self):
840 self.protocol.lineReceived("test mcdonalds farm\n")
841 test = self.client.start_calls[-1]
842 self.assertEqual(None, getattr(test, 'tags', None))
844 def test_tags_do_not_get_set_on_global_tags(self):
845 self.protocol.lineReceived("tags: foo bar\n")
846 self.protocol.lineReceived("test mcdonalds farm\n")
847 test = self.client.start_calls[-1]
848 self.assertEqual(None, getattr(test, 'tags', None))
850 def test_tags_get_set_on_test_tags(self):
851 self.protocol.lineReceived("test mcdonalds farm\n")
852 test = self.client.start_calls[-1]
853 self.protocol.lineReceived("tags: foo bar\n")
854 self.protocol.lineReceived("success mcdonalds farm\n")
855 self.assertEqual(None, getattr(test, 'tags', None))
858 class TestTestProtocolServerStreamTime(unittest.TestCase):
859 """Test managing time information at the protocol level."""
861 def test_time_accepted_stdlib(self):
862 self.result = unittest.TestResult()
863 self.stream = StringIO()
864 self.protocol = subunit.TestProtocolServer(self.result,
866 self.protocol.lineReceived("time: 2001-12-12 12:59:59Z\n")
867 self.assertEqual("", self.stream.getvalue())
869 def test_time_accepted_extended(self):
870 self.result = MockTestProtocolServerClient()
871 self.stream = StringIO()
872 self.protocol = subunit.TestProtocolServer(self.result,
874 self.protocol.lineReceived("time: 2001-12-12 12:59:59Z\n")
875 self.assertEqual("", self.stream.getvalue())
876 self.assertEqual(datetime.datetime(2001, 12, 12, 12, 59, 59, 0,
877 iso8601.Utc()), self.result._time)
880 class TestRemotedTestCase(unittest.TestCase):
882 def test_simple(self):
883 test = subunit.RemotedTestCase("A test description")
884 self.assertRaises(NotImplementedError, test.setUp)
885 self.assertRaises(NotImplementedError, test.tearDown)
886 self.assertEqual("A test description",
887 test.shortDescription())
888 self.assertEqual("A test description",
890 self.assertEqual("A test description (subunit.RemotedTestCase)", "%s" % test)
891 self.assertEqual("<subunit.RemotedTestCase description="
892 "'A test description'>", "%r" % test)
893 result = unittest.TestResult()
895 self.assertEqual([(test, "RemoteException: "
896 "Cannot run RemotedTestCases.\n\n")],
898 self.assertEqual(1, result.testsRun)
899 another_test = subunit.RemotedTestCase("A test description")
900 self.assertEqual(test, another_test)
901 different_test = subunit.RemotedTestCase("ofo")
902 self.assertNotEqual(test, different_test)
903 self.assertNotEqual(another_test, different_test)
906 class TestRemoteError(unittest.TestCase):
909 error = subunit.RemoteError("Something went wrong")
910 another_error = subunit.RemoteError("Something went wrong")
911 different_error = subunit.RemoteError("boo!")
912 self.assertEqual(error, another_error)
913 self.assertNotEqual(error, different_error)
914 self.assertNotEqual(different_error, another_error)
916 def test_empty_constructor(self):
917 self.assertEqual(subunit.RemoteError(), subunit.RemoteError(""))
920 class TestExecTestCase(unittest.TestCase):
922 class SampleExecTestCase(subunit.ExecTestCase):
924 def test_sample_method(self):
925 """sample-script.py"""
926 # the sample script runs three tests, one each
927 # that fails, errors and succeeds
929 def test_sample_method_args(self):
930 """sample-script.py foo"""
931 # sample that will run just one test.
933 def test_construct(self):
934 test = self.SampleExecTestCase("test_sample_method")
935 self.assertEqual(test.script,
936 subunit.join_dir(__file__, 'sample-script.py'))
939 result = unittest.TestResult()
940 test = self.SampleExecTestCase("test_sample_method_args")
942 self.assertEqual(1, result.testsRun)
945 runner = MockTestProtocolServerClient()
946 test = self.SampleExecTestCase("test_sample_method")
948 mcdonald = subunit.RemotedTestCase("old mcdonald")
949 bing = subunit.RemotedTestCase("bing crosby")
950 an_error = subunit.RemotedTestCase("an error")
951 self.assertEqual(runner.error_calls,
952 [(an_error, subunit.RemoteError())])
953 self.assertEqual(runner.failure_calls,
956 "foo.c:53:ERROR invalid state\n"))])
957 self.assertEqual(runner.start_calls, [mcdonald, bing, an_error])
958 self.assertEqual(runner.end_calls, [mcdonald, bing, an_error])
960 def test_debug(self):
961 test = self.SampleExecTestCase("test_sample_method")
964 def test_count_test_cases(self):
965 """TODO run the child process and count responses to determine the count."""
967 def test_join_dir(self):
968 sibling = subunit.join_dir(__file__, 'foo')
969 expected = '%s/foo' % (os.path.split(__file__)[0],)
970 self.assertEqual(sibling, expected)
973 class DoExecTestCase(subunit.ExecTestCase):
975 def test_working_script(self):
976 """sample-two-script.py"""
979 class TestIsolatedTestCase(unittest.TestCase):
981 class SampleIsolatedTestCase(subunit.IsolatedTestCase):
988 TestIsolatedTestCase.SampleIsolatedTestCase.SETUP = True
991 TestIsolatedTestCase.SampleIsolatedTestCase.TEARDOWN = True
993 def test_sets_global_state(self):
994 TestIsolatedTestCase.SampleIsolatedTestCase.TEST = True
997 def test_construct(self):
998 test = self.SampleIsolatedTestCase("test_sets_global_state")
1001 result = unittest.TestResult()
1002 test = self.SampleIsolatedTestCase("test_sets_global_state")
1004 self.assertEqual(result.testsRun, 1)
1005 self.assertEqual(self.SampleIsolatedTestCase.SETUP, False)
1006 self.assertEqual(self.SampleIsolatedTestCase.TEARDOWN, False)
1007 self.assertEqual(self.SampleIsolatedTestCase.TEST, False)
1009 def test_debug(self):
1011 #test = self.SampleExecTestCase("test_sample_method")
1015 class TestIsolatedTestSuite(unittest.TestCase):
1017 class SampleTestToIsolate(unittest.TestCase):
1024 TestIsolatedTestSuite.SampleTestToIsolate.SETUP = True
1027 TestIsolatedTestSuite.SampleTestToIsolate.TEARDOWN = True
1029 def test_sets_global_state(self):
1030 TestIsolatedTestSuite.SampleTestToIsolate.TEST = True
1033 def test_construct(self):
1034 suite = subunit.IsolatedTestSuite()
1037 result = unittest.TestResult()
1038 suite = subunit.IsolatedTestSuite()
1039 sub_suite = unittest.TestSuite()
1040 sub_suite.addTest(self.SampleTestToIsolate("test_sets_global_state"))
1041 sub_suite.addTest(self.SampleTestToIsolate("test_sets_global_state"))
1042 suite.addTest(sub_suite)
1043 suite.addTest(self.SampleTestToIsolate("test_sets_global_state"))
1045 self.assertEqual(result.testsRun, 3)
1046 self.assertEqual(self.SampleTestToIsolate.SETUP, False)
1047 self.assertEqual(self.SampleTestToIsolate.TEARDOWN, False)
1048 self.assertEqual(self.SampleTestToIsolate.TEST, False)
1051 class TestTestProtocolClient(unittest.TestCase):
1054 self.io = StringIO()
1055 self.protocol = subunit.TestProtocolClient(self.io)
1056 self.test = TestTestProtocolClient("test_start_test")
1057 self.sample_details = {'something':Content(
1058 ContentType('text', 'plain'), lambda:['serialised\nform'])}
1059 self.sample_tb_details = dict(self.sample_details)
1060 self.sample_tb_details['traceback'] = TracebackContent(
1061 subunit.RemoteError("boo qux"))
1063 def test_start_test(self):
1064 """Test startTest on a TestProtocolClient."""
1065 self.protocol.startTest(self.test)
1066 self.assertEqual(self.io.getvalue(), "test: %s\n" % self.test.id())
1068 def test_stop_test(self):
1069 # stopTest doesn't output anything.
1070 self.protocol.stopTest(self.test)
1071 self.assertEqual(self.io.getvalue(), "")
1073 def test_add_success(self):
1074 """Test addSuccess on a TestProtocolClient."""
1075 self.protocol.addSuccess(self.test)
1077 self.io.getvalue(), "successful: %s\n" % self.test.id())
1079 def test_add_success_details(self):
1080 """Test addSuccess on a TestProtocolClient with details."""
1081 self.protocol.addSuccess(self.test, details=self.sample_details)
1083 self.io.getvalue(), "successful: %s [ multipart\n"
1084 "Content-Type: text/plain\n"
1086 "15\nserialised\nform0\n]\n" % self.test.id())
1088 def test_add_failure(self):
1089 """Test addFailure on a TestProtocolClient."""
1090 self.protocol.addFailure(
1091 self.test, subunit.RemoteError("boo qux"))
1094 'failure: %s [\nRemoteException: boo qux\n]\n' % self.test.id())
1096 def test_add_failure_details(self):
1097 """Test addFailure on a TestProtocolClient with details."""
1098 self.protocol.addFailure(
1099 self.test, details=self.sample_tb_details)
1102 "failure: %s [ multipart\n"
1103 "Content-Type: text/plain\n"
1105 "15\nserialised\nform0\n"
1106 "Content-Type: text/x-traceback;language=python\n"
1108 "25\nRemoteException: boo qux\n0\n"
1109 "]\n" % self.test.id())
1112 def test_add_error(self):
1113 """Test stopTest on a TestProtocolClient."""
1114 self.protocol.addError(
1115 self.test, subunit.RemoteError("phwoar crikey"))
1119 "RemoteException: phwoar crikey\n"
1120 "]\n" % self.test.id())
1122 def test_add_skip(self):
1123 """Test addSkip on a TestProtocolClient."""
1124 self.protocol.addSkip(
1125 self.test, "Has it really?")
1128 'skip: %s [\nHas it really?\n]\n' % self.test.id())
1130 def test_progress_set(self):
1131 self.protocol.progress(23, subunit.PROGRESS_SET)
1132 self.assertEqual(self.io.getvalue(), 'progress: 23\n')
1134 def test_progress_neg_cur(self):
1135 self.protocol.progress(-23, subunit.PROGRESS_CUR)
1136 self.assertEqual(self.io.getvalue(), 'progress: -23\n')
1138 def test_progress_pos_cur(self):
1139 self.protocol.progress(23, subunit.PROGRESS_CUR)
1140 self.assertEqual(self.io.getvalue(), 'progress: +23\n')
1142 def test_progress_pop(self):
1143 self.protocol.progress(1234, subunit.PROGRESS_POP)
1144 self.assertEqual(self.io.getvalue(), 'progress: pop\n')
1146 def test_progress_push(self):
1147 self.protocol.progress(1234, subunit.PROGRESS_PUSH)
1148 self.assertEqual(self.io.getvalue(), 'progress: push\n')
1150 def test_time(self):
1151 # Calling time() outputs a time signal immediately.
1153 datetime.datetime(2009,10,11,12,13,14,15, iso8601.Utc()))
1155 "time: 2009-10-11 12:13:14.000015Z\n",
1160 loader = subunit.tests.TestUtil.TestLoader()
1161 result = loader.loadTestsFromName(__name__)