8
from cStringIO import StringIO
10
13
from testtools import (
14
ExtendedToOriginalDecorator,
14
19
ThreadsafeForwardingResult,
16
from testtools.tests.helpers import LoggingResult
22
from testtools.content import Content, ContentType
23
from testtools.matchers import DocTestMatches
24
from testtools.tests.helpers import (
19
32
class TestTestResultContract(TestCase):
20
33
"""Tests for the contract of TestResults."""
35
def test_addExpectedFailure(self):
36
# Calling addExpectedFailure(test, exc_info) completes ok.
37
result = self.makeResult()
38
result.addExpectedFailure(self, sys.exc_info())
40
def test_addExpectedFailure_details(self):
41
# Calling addExpectedFailure(test, details=xxx) completes ok.
42
result = self.makeResult()
43
result.addExpectedFailure(self, details={})
45
def test_addError_details(self):
46
# Calling addError(test, details=xxx) completes ok.
47
result = self.makeResult()
48
result.addError(self, details={})
50
def test_addFailure_details(self):
51
# Calling addFailure(test, details=xxx) completes ok.
52
result = self.makeResult()
53
result.addFailure(self, details={})
22
55
def test_addSkipped(self):
23
56
# Calling addSkip(test, reason) completes ok.
24
57
result = self.makeResult()
25
58
result.addSkip(self, u"Skipped for some reason")
60
def test_addSkipped_details(self):
61
# Calling addSkip(test, reason) completes ok.
62
result = self.makeResult()
63
result.addSkip(self, details={})
65
def test_addUnexpectedSuccess(self):
66
# Calling addUnexpectedSuccess(test) completes ok.
67
result = self.makeResult()
68
result.addUnexpectedSuccess(self)
70
def test_addUnexpectedSuccess_details(self):
71
# Calling addUnexpectedSuccess(test) completes ok.
72
result = self.makeResult()
73
result.addUnexpectedSuccess(self, details={})
75
def test_addSuccess_details(self):
76
# Calling addSuccess(test) completes ok.
77
result = self.makeResult()
78
result.addSuccess(self, details={})
80
def test_startStopTestRun(self):
81
# Calling startTestRun completes ok.
82
result = self.makeResult()
28
87
class TestTestResultContract(TestTestResultContract):
144
232
self.multiResult.addError(self, exc_info)
145
233
self.assertResultLogsEqual([('addError', self, exc_info)])
235
def test_startTestRun(self):
236
# Calling `startTestRun` on a `MultiTestResult` forwards to all its
238
self.multiResult.startTestRun()
239
self.assertResultLogsEqual([('startTestRun')])
241
def test_stopTestRun(self):
242
# Calling `stopTestRun` on a `MultiTestResult` forwards to all its
244
self.multiResult.stopTestRun()
245
self.assertResultLogsEqual([('stopTestRun')])
248
class TestTextTestResult(TestWithFakeExceptions):
249
"""Tests for `TextTestResult`."""
252
super(TestTextTestResult, self).setUp()
253
self.result = TextTestResult(StringIO())
255
def make_erroring_test(self):
256
class Test(TestCase):
261
def make_failing_test(self):
262
class Test(TestCase):
265
return Test("failed")
268
class Test(TestCase):
274
return self.result.stream.getvalue()
276
def test__init_sets_stream(self):
277
result = TextTestResult("fp")
278
self.assertEqual("fp", result.stream)
280
def reset_output(self):
281
self.result.stream.reset()
282
self.result.stream.truncate()
284
def test_startTestRun(self):
285
self.result.startTestRun()
286
self.assertEqual("Tests running...\n", self.getvalue())
288
def test_stopTestRun_count_many(self):
289
test = self.make_test()
290
self.result.startTestRun()
291
self.result.startTest(test)
292
self.result.stopTest(test)
293
self.result.startTest(test)
294
self.result.stopTest(test)
295
self.result.stream.reset()
296
self.result.stream.truncate()
297
self.result.stopTestRun()
298
self.assertThat(self.getvalue(),
299
DocTestMatches("Ran 2 tests in ...s\n...", doctest.ELLIPSIS))
301
def test_stopTestRun_count_single(self):
302
test = self.make_test()
303
self.result.startTestRun()
304
self.result.startTest(test)
305
self.result.stopTest(test)
307
self.result.stopTestRun()
308
self.assertThat(self.getvalue(),
309
DocTestMatches("Ran 1 test in ...s\n\nOK\n", doctest.ELLIPSIS))
311
def test_stopTestRun_count_zero(self):
312
self.result.startTestRun()
314
self.result.stopTestRun()
315
self.assertThat(self.getvalue(),
316
DocTestMatches("Ran 0 tests in ...s\n\nOK\n", doctest.ELLIPSIS))
318
def test_stopTestRun_current_time(self):
319
test = self.make_test()
320
now = datetime.datetime.now()
321
self.result.time(now)
322
self.result.startTestRun()
323
self.result.startTest(test)
324
now = now + datetime.timedelta(0, 0, 0, 1)
325
self.result.time(now)
326
self.result.stopTest(test)
328
self.result.stopTestRun()
329
self.assertThat(self.getvalue(),
330
DocTestMatches("... in 0.001s\n...", doctest.ELLIPSIS))
332
def test_stopTestRun_successful(self):
333
self.result.startTestRun()
334
self.result.stopTestRun()
335
self.assertThat(self.getvalue(),
336
DocTestMatches("...\n\nOK\n", doctest.ELLIPSIS))
338
def test_stopTestRun_not_successful_failure(self):
339
test = self.make_failing_test()
340
self.result.startTestRun()
341
test.run(self.result)
342
self.result.stopTestRun()
343
self.assertThat(self.getvalue(),
344
DocTestMatches("...\n\nFAILED (failures=1)\n", doctest.ELLIPSIS))
346
def test_stopTestRun_not_successful_error(self):
347
test = self.make_erroring_test()
348
self.result.startTestRun()
349
test.run(self.result)
350
self.result.stopTestRun()
351
self.assertThat(self.getvalue(),
352
DocTestMatches("...\n\nFAILED (failures=1)\n", doctest.ELLIPSIS))
354
def test_stopTestRun_shows_details(self):
355
self.result.startTestRun()
356
self.make_erroring_test().run(self.result)
357
self.make_failing_test().run(self.result)
359
self.result.stopTestRun()
360
self.assertThat(self.getvalue(),
361
DocTestMatches("""...======================================================================
362
ERROR: testtools.tests.test_testresult.Test.error
363
----------------------------------------------------------------------
364
Text attachment: traceback
366
Traceback (most recent call last):
367
File "...testtools/testcase.py", line ..., in run
369
File "...testtools/tests/test_testresult.py", line ..., in error
371
ZeroDivisionError: integer division or modulo by zero
373
======================================================================
374
FAIL: testtools.tests.test_testresult.Test.failed
375
----------------------------------------------------------------------
376
Text attachment: traceback
378
Traceback (most recent call last):
379
File "...testtools/testcase.py", line ..., in run
381
File "...testtools/tests/test_testresult.py", line ..., in failed
385
...""", doctest.ELLIPSIS))
148
388
class TestThreadSafeForwardingResult(TestWithFakeExceptions):
149
389
"""Tests for `MultiTestResult`."""
392
TestWithFakeExceptions.setUp(self)
152
393
self.result_semaphore = threading.Semaphore(1)
153
394
self.target = LoggingResult([])
154
395
self.result1 = ThreadsafeForwardingResult(self.target,
192
440
], self.target._events)
443
class TestExtendedToOriginalResultDecoratorBase(TestCase):
445
def make_26_result(self):
446
self.result = Python26TestResult()
447
self.make_converter()
449
def make_27_result(self):
450
self.result = Python27TestResult()
451
self.make_converter()
453
def make_converter(self):
454
self.converter = ExtendedToOriginalDecorator(self.result)
456
def make_extended_result(self):
457
self.result = ExtendedTestResult()
458
self.make_converter()
460
def check_outcome_details(self, outcome):
461
"""Call an outcome with a details dict to be passed through."""
462
# This dict is /not/ convertible - thats deliberate, as it should
463
# not hit the conversion code path.
464
details = {'foo': 'bar'}
465
getattr(self.converter, outcome)(self, details=details)
466
self.assertEqual([(outcome, self, details)], self.result._events)
468
def get_details_and_string(self):
469
"""Get a details dict and expected string."""
470
text1 = lambda:["1\n2\n"]
471
text2 = lambda:["3\n4\n"]
472
bin1 = lambda:["5\n"]
473
details = {'text 1': Content(ContentType('text', 'plain'), text1),
474
'text 2': Content(ContentType('text', 'strange'), text2),
475
'bin 1': Content(ContentType('application', 'binary'), bin1)}
476
return (details, "Binary content: bin 1\n"
477
"Text attachment: text 1\n------------\n1\n2\n"
478
"------------\nText attachment: text 2\n------------\n"
479
"3\n4\n------------\n")
481
def check_outcome_details_to_exec_info(self, outcome, expected=None):
482
"""Call an outcome with a details dict to be made into exc_info."""
483
# The conversion is a done using RemoteError and the string contents
484
# of the text types in the details dict.
487
details, err_str = self.get_details_and_string()
488
getattr(self.converter, outcome)(self, details=details)
489
err = self.converter._details_to_exc_info(details)
490
self.assertEqual([(expected, self, err)], self.result._events)
492
def check_outcome_details_to_nothing(self, outcome, expected=None):
493
"""Call an outcome with a details dict to be swallowed."""
496
details = {'foo': 'bar'}
497
getattr(self.converter, outcome)(self, details=details)
498
self.assertEqual([(expected, self)], self.result._events)
500
def check_outcome_details_to_string(self, outcome):
501
"""Call an outcome with a details dict to be stringified."""
502
details, err_str = self.get_details_and_string()
503
getattr(self.converter, outcome)(self, details=details)
504
self.assertEqual([(outcome, self, err_str)], self.result._events)
506
def check_outcome_exc_info(self, outcome, expected=None):
507
"""Check that calling a legacy outcome still works."""
508
# calling some outcome with the legacy exc_info style api (no keyword
509
# parameters) gets passed through.
513
getattr(self.converter, outcome)(self, err)
514
self.assertEqual([(expected, self, err)], self.result._events)
516
def check_outcome_exc_info_to_nothing(self, outcome, expected=None):
517
"""Check that calling a legacy outcome on a fallback works."""
518
# calling some outcome with the legacy exc_info style api (no keyword
519
# parameters) gets passed through.
523
getattr(self.converter, outcome)(self, err)
524
self.assertEqual([(expected, self)], self.result._events)
526
def check_outcome_nothing(self, outcome, expected=None):
527
"""Check that calling a legacy outcome still works."""
530
getattr(self.converter, outcome)(self)
531
self.assertEqual([(expected, self)], self.result._events)
533
def check_outcome_string_nothing(self, outcome, expected):
534
"""Check that calling outcome with a string calls expected."""
535
getattr(self.converter, outcome)(self, "foo")
536
self.assertEqual([(expected, self)], self.result._events)
538
def check_outcome_string(self, outcome):
539
"""Check that calling outcome with a string works."""
540
getattr(self.converter, outcome)(self, "foo")
541
self.assertEqual([(outcome, self, "foo")], self.result._events)
544
class TestExtendedToOriginalResultDecorator(
545
TestExtendedToOriginalResultDecoratorBase):
547
def test_progress_py26(self):
548
self.make_26_result()
549
self.converter.progress(1, 2)
551
def test_progress_py27(self):
552
self.make_27_result()
553
self.converter.progress(1, 2)
555
def test_progress_pyextended(self):
556
self.make_extended_result()
557
self.converter.progress(1, 2)
558
self.assertEqual([('progress', 1, 2)], self.result._events)
560
def test_shouldStop(self):
561
self.make_26_result()
562
self.assertEqual(False, self.converter.shouldStop)
563
self.converter.decorated.stop()
564
self.assertEqual(True, self.converter.shouldStop)
566
def test_startTest_py26(self):
567
self.make_26_result()
568
self.converter.startTest(self)
569
self.assertEqual([('startTest', self)], self.result._events)
571
def test_startTest_py27(self):
572
self.make_27_result()
573
self.converter.startTest(self)
574
self.assertEqual([('startTest', self)], self.result._events)
576
def test_startTest_pyextended(self):
577
self.make_extended_result()
578
self.converter.startTest(self)
579
self.assertEqual([('startTest', self)], self.result._events)
581
def test_startTestRun_py26(self):
582
self.make_26_result()
583
self.converter.startTestRun()
584
self.assertEqual([], self.result._events)
586
def test_startTestRun_py27(self):
587
self.make_27_result()
588
self.converter.startTestRun()
589
self.assertEqual([('startTestRun',)], self.result._events)
591
def test_startTestRun_pyextended(self):
592
self.make_extended_result()
593
self.converter.startTestRun()
594
self.assertEqual([('startTestRun',)], self.result._events)
596
def test_stopTest_py26(self):
597
self.make_26_result()
598
self.converter.stopTest(self)
599
self.assertEqual([('stopTest', self)], self.result._events)
601
def test_stopTest_py27(self):
602
self.make_27_result()
603
self.converter.stopTest(self)
604
self.assertEqual([('stopTest', self)], self.result._events)
606
def test_stopTest_pyextended(self):
607
self.make_extended_result()
608
self.converter.stopTest(self)
609
self.assertEqual([('stopTest', self)], self.result._events)
611
def test_stopTestRun_py26(self):
612
self.make_26_result()
613
self.converter.stopTestRun()
614
self.assertEqual([], self.result._events)
616
def test_stopTestRun_py27(self):
617
self.make_27_result()
618
self.converter.stopTestRun()
619
self.assertEqual([('stopTestRun',)], self.result._events)
621
def test_stopTestRun_pyextended(self):
622
self.make_extended_result()
623
self.converter.stopTestRun()
624
self.assertEqual([('stopTestRun',)], self.result._events)
626
def test_tags_py26(self):
627
self.make_26_result()
628
self.converter.tags(1, 2)
630
def test_tags_py27(self):
631
self.make_27_result()
632
self.converter.tags(1, 2)
634
def test_tags_pyextended(self):
635
self.make_extended_result()
636
self.converter.tags(1, 2)
637
self.assertEqual([('tags', 1, 2)], self.result._events)
639
def test_time_py26(self):
640
self.make_26_result()
641
self.converter.time(1)
643
def test_time_py27(self):
644
self.make_27_result()
645
self.converter.time(1)
647
def test_time_pyextended(self):
648
self.make_extended_result()
649
self.converter.time(1)
650
self.assertEqual([('time', 1)], self.result._events)
653
class TestExtendedToOriginalAddError(TestExtendedToOriginalResultDecoratorBase):
657
def test_outcome_Original_py26(self):
658
self.make_26_result()
659
self.check_outcome_exc_info(self.outcome)
661
def test_outcome_Original_py27(self):
662
self.make_27_result()
663
self.check_outcome_exc_info(self.outcome)
665
def test_outcome_Original_pyextended(self):
666
self.make_extended_result()
667
self.check_outcome_exc_info(self.outcome)
669
def test_outcome_Extended_py26(self):
670
self.make_26_result()
671
self.check_outcome_details_to_exec_info(self.outcome)
673
def test_outcome_Extended_py27(self):
674
self.make_27_result()
675
self.check_outcome_details_to_exec_info(self.outcome)
677
def test_outcome_Extended_pyextended(self):
678
self.make_extended_result()
679
self.check_outcome_details(self.outcome)
681
def test_outcome__no_details(self):
682
self.make_extended_result()
683
self.assertRaises(ValueError,
684
getattr(self.converter, self.outcome), self)
687
class TestExtendedToOriginalAddFailure(
688
TestExtendedToOriginalAddError):
690
outcome = 'addFailure'
693
class TestExtendedToOriginalAddExpectedFailure(
694
TestExtendedToOriginalAddError):
696
outcome = 'addExpectedFailure'
698
def test_outcome_Original_py26(self):
699
self.make_26_result()
700
self.check_outcome_exc_info_to_nothing(self.outcome, 'addSuccess')
702
def test_outcome_Extended_py26(self):
703
self.make_26_result()
704
self.check_outcome_details_to_nothing(self.outcome, 'addSuccess')
708
class TestExtendedToOriginalAddSkip(
709
TestExtendedToOriginalResultDecoratorBase):
713
def test_outcome_Original_py26(self):
714
self.make_26_result()
715
self.check_outcome_string_nothing(self.outcome, 'addSuccess')
717
def test_outcome_Original_py27(self):
718
self.make_27_result()
719
self.check_outcome_string(self.outcome)
721
def test_outcome_Original_pyextended(self):
722
self.make_extended_result()
723
self.check_outcome_string(self.outcome)
725
def test_outcome_Extended_py26(self):
726
self.make_26_result()
727
self.check_outcome_string_nothing(self.outcome, 'addSuccess')
729
def test_outcome_Extended_py27(self):
730
self.make_27_result()
731
self.check_outcome_details_to_string(self.outcome)
733
def test_outcome_Extended_pyextended(self):
734
self.make_extended_result()
735
self.check_outcome_details(self.outcome)
737
def test_outcome__no_details(self):
738
self.make_extended_result()
739
self.assertRaises(ValueError,
740
getattr(self.converter, self.outcome), self)
743
class TestExtendedToOriginalAddSuccess(
744
TestExtendedToOriginalResultDecoratorBase):
746
outcome = 'addSuccess'
747
expected = 'addSuccess'
749
def test_outcome_Original_py26(self):
750
self.make_26_result()
751
self.check_outcome_nothing(self.outcome, self.expected)
753
def test_outcome_Original_py27(self):
754
self.make_27_result()
755
self.check_outcome_nothing(self.outcome)
757
def test_outcome_Original_pyextended(self):
758
self.make_extended_result()
759
self.check_outcome_nothing(self.outcome)
761
def test_outcome_Extended_py26(self):
762
self.make_26_result()
763
self.check_outcome_details_to_nothing(self.outcome, self.expected)
765
def test_outcome_Extended_py27(self):
766
self.make_27_result()
767
self.check_outcome_details_to_nothing(self.outcome)
769
def test_outcome_Extended_pyextended(self):
770
self.make_extended_result()
771
self.check_outcome_details(self.outcome)
774
class TestExtendedToOriginalAddUnexpectedSuccess(
775
TestExtendedToOriginalAddSuccess):
777
outcome = 'addUnexpectedSuccess'
195
780
def test_suite():
196
781
from unittest import TestLoader
197
782
return TestLoader().loadTestsFromName(__name__)