1
# Copyright (c) 2008-2010 testtools developers. See LICENSE for details.
3
"""Tests for extensions to the base test library."""
5
from pprint import pformat
11
from testtools import (
16
clone_test_with_new_id,
23
from testtools.matchers import (
28
from testtools.tests.helpers import (
36
exec('from __future__ import with_statement')
40
from test_with_with import *
43
class TestPlaceHolder(TestCase):
45
def makePlaceHolder(self, test_id="foo", short_description=None):
46
return PlaceHolder(test_id, short_description)
48
def test_id_comes_from_constructor(self):
49
# The id() of a PlaceHolder is whatever you pass into the constructor.
50
test = PlaceHolder("test id")
51
self.assertEqual("test id", test.id())
53
def test_shortDescription_is_id(self):
54
# The shortDescription() of a PlaceHolder is the id, by default.
55
test = PlaceHolder("test id")
56
self.assertEqual(test.id(), test.shortDescription())
58
def test_shortDescription_specified(self):
59
# If a shortDescription is provided to the constructor, then
60
# shortDescription() returns that instead.
61
test = PlaceHolder("test id", "description")
62
self.assertEqual("description", test.shortDescription())
64
def test_repr_just_id(self):
65
# repr(placeholder) shows you how the object was constructed.
66
test = PlaceHolder("test id")
68
"<testtools.testcase.PlaceHolder(%s)>" % repr(test.id()),
71
def test_repr_with_description(self):
72
# repr(placeholder) shows you how the object was constructed.
73
test = PlaceHolder("test id", "description")
75
"<testtools.testcase.PlaceHolder(%r, %r)>" % (
76
test.id(), test.shortDescription()),
79
def test_counts_as_one_test(self):
80
# A placeholder test counts as one test.
81
test = self.makePlaceHolder()
82
self.assertEqual(1, test.countTestCases())
84
def test_str_is_id(self):
85
# str(placeholder) is always the id(). We are not barbarians.
86
test = self.makePlaceHolder()
87
self.assertEqual(test.id(), str(test))
89
def test_runs_as_success(self):
90
# When run, a PlaceHolder test records a success.
91
test = self.makePlaceHolder()
93
test.run(LoggingResult(log))
95
[('startTest', test), ('addSuccess', test), ('stopTest', test)],
98
def test_call_is_run(self):
99
# A PlaceHolder can be called, in which case it behaves like run.
100
test = self.makePlaceHolder()
102
test.run(LoggingResult(run_log))
104
test(LoggingResult(call_log))
105
self.assertEqual(run_log, call_log)
107
def test_runs_without_result(self):
108
# A PlaceHolder can be run without a result, in which case there's no
109
# way to actually get at the result.
110
self.makePlaceHolder().run()
112
def test_debug(self):
113
# A PlaceHolder can be debugged.
114
self.makePlaceHolder().debug()
117
class TestErrorHolder(TestCase):
119
def makeException(self):
121
raise RuntimeError("danger danger")
123
return sys.exc_info()
125
def makePlaceHolder(self, test_id="foo", error=None,
126
short_description=None):
128
error = self.makeException()
129
return ErrorHolder(test_id, error, short_description)
131
def test_id_comes_from_constructor(self):
132
# The id() of a PlaceHolder is whatever you pass into the constructor.
133
test = ErrorHolder("test id", self.makeException())
134
self.assertEqual("test id", test.id())
136
def test_shortDescription_is_id(self):
137
# The shortDescription() of a PlaceHolder is the id, by default.
138
test = ErrorHolder("test id", self.makeException())
139
self.assertEqual(test.id(), test.shortDescription())
141
def test_shortDescription_specified(self):
142
# If a shortDescription is provided to the constructor, then
143
# shortDescription() returns that instead.
144
test = ErrorHolder("test id", self.makeException(), "description")
145
self.assertEqual("description", test.shortDescription())
147
def test_repr_just_id(self):
148
# repr(placeholder) shows you how the object was constructed.
149
error = self.makeException()
150
test = ErrorHolder("test id", error)
152
"<testtools.testcase.ErrorHolder(%r, %r)>" % (test.id(), error),
155
def test_repr_with_description(self):
156
# repr(placeholder) shows you how the object was constructed.
157
error = self.makeException()
158
test = ErrorHolder("test id", error, "description")
160
"<testtools.testcase.ErrorHolder(%r, %r, %r)>" % (
161
test.id(), error, test.shortDescription()),
164
def test_counts_as_one_test(self):
165
# A placeholder test counts as one test.
166
test = self.makePlaceHolder()
167
self.assertEqual(1, test.countTestCases())
169
def test_str_is_id(self):
170
# str(placeholder) is always the id(). We are not barbarians.
171
test = self.makePlaceHolder()
172
self.assertEqual(test.id(), str(test))
174
def test_runs_as_error(self):
175
# When run, a PlaceHolder test records a success.
176
error = self.makeException()
177
test = self.makePlaceHolder(error=error)
179
test.run(LoggingResult(log))
181
[('startTest', test),
182
('addError', test, error),
183
('stopTest', test)], log)
185
def test_call_is_run(self):
186
# A PlaceHolder can be called, in which case it behaves like run.
187
test = self.makePlaceHolder()
189
test.run(LoggingResult(run_log))
191
test(LoggingResult(call_log))
192
self.assertEqual(run_log, call_log)
194
def test_runs_without_result(self):
195
# A PlaceHolder can be run without a result, in which case there's no
196
# way to actually get at the result.
197
self.makePlaceHolder().run()
199
def test_debug(self):
200
# A PlaceHolder can be debugged.
201
self.makePlaceHolder().debug()
204
class TestEquality(TestCase):
205
"""Test ``TestCase``'s equality implementation."""
207
def test_identicalIsEqual(self):
208
# TestCase's are equal if they are identical.
209
self.assertEqual(self, self)
211
def test_nonIdenticalInUnequal(self):
212
# TestCase's are not equal if they are not identical.
213
self.assertNotEqual(TestCase(methodName='run'),
214
TestCase(methodName='skip'))
217
class TestAssertions(TestCase):
218
"""Test assertions in TestCase."""
220
def raiseError(self, exceptionFactory, *args, **kwargs):
221
raise exceptionFactory(*args, **kwargs)
223
def test_formatTypes_single(self):
224
# Given a single class, _formatTypes returns the name.
227
self.assertEqual('Foo', self._formatTypes(Foo))
229
def test_formatTypes_multiple(self):
230
# Given multiple types, _formatTypes returns the names joined by
236
self.assertEqual('Foo, Bar', self._formatTypes([Foo, Bar]))
238
def test_assertRaises(self):
239
# assertRaises asserts that a callable raises a particular exception.
240
self.assertRaises(RuntimeError, self.raiseError, RuntimeError)
242
def test_assertRaises_fails_when_no_error_raised(self):
243
# assertRaises raises self.failureException when it's passed a
244
# callable that raises no error.
247
self.assertRaises(RuntimeError, lambda: ret)
248
except self.failureException:
249
# We expected assertRaises to raise this exception.
250
e = sys.exc_info()[1]
252
'%s not raised, %r returned instead.'
253
% (self._formatTypes(RuntimeError), ret), str(e))
255
self.fail('Expected assertRaises to fail, but it did not.')
257
def test_assertRaises_fails_when_different_error_raised(self):
258
# assertRaises re-raises an exception that it didn't expect.
259
self.assertThat(lambda: self.assertRaises(RuntimeError,
260
self.raiseError, ZeroDivisionError),
261
Raises(MatchesException(ZeroDivisionError)))
263
def test_assertRaises_returns_the_raised_exception(self):
264
# assertRaises returns the exception object that was raised. This is
265
# useful for testing that exceptions have the right message.
267
# This contraption stores the raised exception, so we can compare it
268
# to the return value of assertRaises.
269
raisedExceptions = []
272
raise RuntimeError('Deliberate error')
274
raisedExceptions.append(sys.exc_info()[1])
277
exception = self.assertRaises(RuntimeError, raiseError)
278
self.assertEqual(1, len(raisedExceptions))
280
exception is raisedExceptions[0],
281
"%r is not %r" % (exception, raisedExceptions[0]))
283
def test_assertRaises_with_multiple_exceptions(self):
284
# assertRaises((ExceptionOne, ExceptionTwo), function) asserts that
285
# function raises one of ExceptionTwo or ExceptionOne.
286
expectedExceptions = (RuntimeError, ZeroDivisionError)
288
expectedExceptions, self.raiseError, expectedExceptions[0])
290
expectedExceptions, self.raiseError, expectedExceptions[1])
292
def test_assertRaises_with_multiple_exceptions_failure_mode(self):
293
# If assertRaises is called expecting one of a group of exceptions and
294
# a callable that doesn't raise an exception, then fail with an
295
# appropriate error message.
296
expectedExceptions = (RuntimeError, ZeroDivisionError)
297
failure = self.assertRaises(
298
self.failureException,
299
self.assertRaises, expectedExceptions, lambda: None)
301
'%s not raised, None returned instead.'
302
% self._formatTypes(expectedExceptions), str(failure))
304
def assertFails(self, message, function, *args, **kwargs):
305
"""Assert that function raises a failure with the given message."""
306
failure = self.assertRaises(
307
self.failureException, function, *args, **kwargs)
308
self.assertEqual(message, str(failure))
310
def test_assertIn_success(self):
311
# assertIn(needle, haystack) asserts that 'needle' is in 'haystack'.
312
self.assertIn(3, range(10))
313
self.assertIn('foo', 'foo bar baz')
314
self.assertIn('foo', 'foo bar baz'.split())
316
def test_assertIn_failure(self):
317
# assertIn(needle, haystack) fails the test when 'needle' is not in
319
self.assertFails('3 not in [0, 1, 2]', self.assertIn, 3, [0, 1, 2])
321
'%r not in %r' % ('qux', 'foo bar baz'),
322
self.assertIn, 'qux', 'foo bar baz')
324
def test_assertNotIn_success(self):
325
# assertNotIn(needle, haystack) asserts that 'needle' is not in
327
self.assertNotIn(3, [0, 1, 2])
328
self.assertNotIn('qux', 'foo bar baz')
330
def test_assertNotIn_failure(self):
331
# assertNotIn(needle, haystack) fails the test when 'needle' is in
333
self.assertFails('3 in [1, 2, 3]', self.assertNotIn, 3, [1, 2, 3])
335
'%r in %r' % ('foo', 'foo bar baz'),
336
self.assertNotIn, 'foo', 'foo bar baz')
338
def test_assertIsInstance(self):
339
# assertIsInstance asserts that an object is an instance of a class.
342
"""Simple class for testing assertIsInstance."""
345
self.assertIsInstance(foo, Foo)
347
def test_assertIsInstance_multiple_classes(self):
348
# assertIsInstance asserts that an object is an instance of one of a
352
"""Simple class for testing assertIsInstance."""
355
"""Another simple class for testing assertIsInstance."""
358
self.assertIsInstance(foo, (Foo, Bar))
359
self.assertIsInstance(Bar(), (Foo, Bar))
361
def test_assertIsInstance_failure(self):
362
# assertIsInstance(obj, klass) fails the test when obj is not an
366
"""Simple class for testing assertIsInstance."""
369
'42 is not an instance of %s' % self._formatTypes(Foo),
370
self.assertIsInstance, 42, Foo)
372
def test_assertIsInstance_failure_multiple_classes(self):
373
# assertIsInstance(obj, (klass1, klass2)) fails the test when obj is
374
# not an instance of klass1 or klass2.
377
"""Simple class for testing assertIsInstance."""
380
"""Another simple class for testing assertIsInstance."""
383
'42 is not an instance of %s' % self._formatTypes([Foo, Bar]),
384
self.assertIsInstance, 42, (Foo, Bar))
386
def test_assertIsInstance_overridden_message(self):
387
# assertIsInstance(obj, klass, msg) permits a custom message.
388
self.assertFails("foo", self.assertIsInstance, 42, str, "foo")
390
def test_assertIs(self):
391
# assertIs asserts that an object is identical to another object.
392
self.assertIs(None, None)
394
self.assertIs(some_list, some_list)
395
some_object = object()
396
self.assertIs(some_object, some_object)
398
def test_assertIs_fails(self):
399
# assertIs raises assertion errors if one object is not identical to
401
self.assertFails('None is not 42', self.assertIs, None, 42)
402
self.assertFails('[42] is not [42]', self.assertIs, [42], [42])
404
def test_assertIs_fails_with_message(self):
405
# assertIs raises assertion errors if one object is not identical to
406
# another, and includes a user-supplied message, if it's provided.
408
'None is not 42: foo bar', self.assertIs, None, 42, 'foo bar')
410
def test_assertIsNot(self):
411
# assertIsNot asserts that an object is not identical to another
413
self.assertIsNot(None, 42)
414
self.assertIsNot([42], [42])
415
self.assertIsNot(object(), object())
417
def test_assertIsNot_fails(self):
418
# assertIsNot raises assertion errors if one object is identical to
420
self.assertFails('None is None', self.assertIsNot, None, None)
423
'[42] is [42]', self.assertIsNot, some_list, some_list)
425
def test_assertIsNot_fails_with_message(self):
426
# assertIsNot raises assertion errors if one object is identical to
427
# another, and includes a user-supplied message if it's provided.
429
'None is None: foo bar', self.assertIsNot, None, None, "foo bar")
431
def test_assertThat_matches_clean(self):
432
class Matcher(object):
433
def match(self, foo):
435
self.assertThat("foo", Matcher())
437
def test_assertThat_mismatch_raises_description(self):
439
class Mismatch(object):
440
def __init__(self, thing):
443
calls.append(('describe_diff', self.thing))
444
return "object is not a thing"
445
def get_details(self):
447
class Matcher(object):
448
def match(self, thing):
449
calls.append(('match', thing))
450
return Mismatch(thing)
452
calls.append(('__str__',))
453
return "a description"
454
class Test(TestCase):
456
self.assertThat("foo", Matcher())
457
result = Test("test").run()
460
('describe_diff', "foo"),
463
self.assertFalse(result.wasSuccessful())
465
def test_assertEqual_nice_formatting(self):
466
message = "These things ought not be equal."
467
a = ['apple', 'banana', 'cherry']
468
b = {'Thatcher': 'One who mends roofs of straw',
469
'Major': 'A military officer, ranked below colonel',
470
'Blair': 'To shout loudly',
471
'Brown': 'The colour of healthy human faeces'}
472
expected_error = '\n'.join(
475
'a = %s' % pformat(a),
476
'b = %s' % pformat(b),
478
expected_error = '\n'.join([
479
'Match failed. Matchee: "%r"' % b,
480
'Matcher: Annotate(%r, Equals(%r))' % (message, a),
482
'reference = %s' % pformat(a),
483
'actual = %s' % pformat(b),
487
self.assertFails(expected_error, self.assertEqual, a, b, message)
488
self.assertFails(expected_error, self.assertEquals, a, b, message)
489
self.assertFails(expected_error, self.failUnlessEqual, a, b, message)
491
def test_assertEqual_formatting_no_message(self):
494
expected_error = '\n'.join([
495
'Match failed. Matchee: "dog"',
496
'Matcher: Equals(\'cat\')',
497
'Difference: \'cat\' != \'dog\'',
500
self.assertFails(expected_error, self.assertEqual, a, b)
501
self.assertFails(expected_error, self.assertEquals, a, b)
502
self.assertFails(expected_error, self.failUnlessEqual, a, b)
505
class TestAddCleanup(TestCase):
506
"""Tests for TestCase.addCleanup."""
508
class LoggingTest(TestCase):
509
"""A test that logs calls to setUp, runTest and tearDown."""
513
self._calls = ['setUp']
515
def brokenSetUp(self):
516
# A tearDown that deliberately fails.
517
self._calls = ['brokenSetUp']
518
raise RuntimeError('Deliberate Failure')
521
self._calls.append('runTest')
523
def brokenTest(self):
524
raise RuntimeError('Deliberate broken test')
527
self._calls.append('tearDown')
528
TestCase.tearDown(self)
532
self._result_calls = []
533
self.test = TestAddCleanup.LoggingTest('runTest')
534
self.logging_result = LoggingResult(self._result_calls)
536
def assertErrorLogEqual(self, messages):
537
self.assertEqual(messages, [call[0] for call in self._result_calls])
539
def assertTestLogEqual(self, messages):
540
"""Assert that the call log equals 'messages'."""
541
case = self._result_calls[0][1]
542
self.assertEqual(messages, case._calls)
544
def logAppender(self, message):
545
"""A cleanup that appends 'message' to the tests log.
547
Cleanups are callables that are added to a test by addCleanup. To
548
verify that our cleanups run in the right order, we add strings to a
549
list that acts as a log. This method returns a cleanup that will add
550
the given message to that log when run.
552
self.test._calls.append(message)
554
def test_fixture(self):
555
# A normal run of self.test logs 'setUp', 'runTest' and 'tearDown'.
556
# This test doesn't test addCleanup itself, it just sanity checks the
558
self.test.run(self.logging_result)
559
self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
561
def test_cleanup_run_before_tearDown(self):
562
# Cleanup functions added with 'addCleanup' are called before tearDown
564
self.test.addCleanup(self.logAppender, 'cleanup')
565
self.test.run(self.logging_result)
566
self.assertTestLogEqual(['setUp', 'runTest', 'tearDown', 'cleanup'])
568
def test_add_cleanup_called_if_setUp_fails(self):
569
# Cleanup functions added with 'addCleanup' are called even if setUp
570
# fails. Note that tearDown has a different behavior: it is only
571
# called when setUp succeeds.
572
self.test.setUp = self.test.brokenSetUp
573
self.test.addCleanup(self.logAppender, 'cleanup')
574
self.test.run(self.logging_result)
575
self.assertTestLogEqual(['brokenSetUp', 'cleanup'])
577
def test_addCleanup_called_in_reverse_order(self):
578
# Cleanup functions added with 'addCleanup' are called in reverse
581
# One of the main uses of addCleanup is to dynamically create
582
# resources that need some sort of explicit tearDown. Often one
583
# resource will be created in terms of another, e.g.,
584
# self.first = self.makeFirst()
585
# self.second = self.makeSecond(self.first)
587
# When this happens, we generally want to clean up the second resource
588
# before the first one, since the second depends on the first.
589
self.test.addCleanup(self.logAppender, 'first')
590
self.test.addCleanup(self.logAppender, 'second')
591
self.test.run(self.logging_result)
592
self.assertTestLogEqual(
593
['setUp', 'runTest', 'tearDown', 'second', 'first'])
595
def test_tearDown_runs_after_cleanup_failure(self):
596
# tearDown runs even if a cleanup function fails.
597
self.test.addCleanup(lambda: 1/0)
598
self.test.run(self.logging_result)
599
self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
601
def test_cleanups_continue_running_after_error(self):
602
# All cleanups are always run, even if one or two of them fail.
603
self.test.addCleanup(self.logAppender, 'first')
604
self.test.addCleanup(lambda: 1/0)
605
self.test.addCleanup(self.logAppender, 'second')
606
self.test.run(self.logging_result)
607
self.assertTestLogEqual(
608
['setUp', 'runTest', 'tearDown', 'second', 'first'])
610
def test_error_in_cleanups_are_captured(self):
611
# If a cleanup raises an error, we want to record it and fail the the
612
# test, even though we go on to run other cleanups.
613
self.test.addCleanup(lambda: 1/0)
614
self.test.run(self.logging_result)
615
self.assertErrorLogEqual(['startTest', 'addError', 'stopTest'])
617
def test_keyboard_interrupt_not_caught(self):
618
# If a cleanup raises KeyboardInterrupt, it gets reraised.
619
def raiseKeyboardInterrupt():
620
raise KeyboardInterrupt()
621
self.test.addCleanup(raiseKeyboardInterrupt)
622
self.assertThat(lambda:self.test.run(self.logging_result),
623
Raises(MatchesException(KeyboardInterrupt)))
625
def test_all_errors_from_MultipleExceptions_reported(self):
626
# When a MultipleExceptions exception is caught, all the errors are
632
exc_info1 = sys.exc_info()
636
exc_info2 = sys.exc_info()
637
raise MultipleExceptions(exc_info1, exc_info2)
638
self.test.addCleanup(raiseMany)
639
self.logging_result = ExtendedTestResult()
640
self.test.run(self.logging_result)
641
self.assertEqual(['startTest', 'addError', 'stopTest'],
642
[event[0] for event in self.logging_result._events])
643
self.assertEqual(set(['traceback', 'traceback-1']),
644
set(self.logging_result._events[1][2].keys()))
646
def test_multipleCleanupErrorsReported(self):
647
# Errors from all failing cleanups are reported as separate backtraces.
648
self.test.addCleanup(lambda: 1/0)
649
self.test.addCleanup(lambda: 1/0)
650
self.logging_result = ExtendedTestResult()
651
self.test.run(self.logging_result)
652
self.assertEqual(['startTest', 'addError', 'stopTest'],
653
[event[0] for event in self.logging_result._events])
654
self.assertEqual(set(['traceback', 'traceback-1']),
655
set(self.logging_result._events[1][2].keys()))
657
def test_multipleErrorsCoreAndCleanupReported(self):
658
# Errors from all failing cleanups are reported, with stopTest,
659
# startTest inserted.
660
self.test = TestAddCleanup.LoggingTest('brokenTest')
661
self.test.addCleanup(lambda: 1/0)
662
self.test.addCleanup(lambda: 1/0)
663
self.logging_result = ExtendedTestResult()
664
self.test.run(self.logging_result)
665
self.assertEqual(['startTest', 'addError', 'stopTest'],
666
[event[0] for event in self.logging_result._events])
667
self.assertEqual(set(['traceback', 'traceback-1', 'traceback-2']),
668
set(self.logging_result._events[1][2].keys()))
671
class TestWithDetails(TestCase):
673
def assertDetailsProvided(self, case, expected_outcome, expected_keys):
674
"""Assert that when case is run, details are provided to the result.
676
:param case: A TestCase to run.
677
:param expected_outcome: The call that should be made.
678
:param expected_keys: The keys to look for.
680
result = ExtendedTestResult()
682
case = result._events[0][1]
685
(expected_outcome, case),
688
self.assertEqual(3, len(result._events))
689
self.assertEqual(expected[0], result._events[0])
690
self.assertEqual(expected[1], result._events[1][0:2])
691
# Checking the TB is right is rather tricky. doctest line matching
692
# would help, but 'meh'.
693
self.assertEqual(sorted(expected_keys),
694
sorted(result._events[1][2].keys()))
695
self.assertEqual(expected[-1], result._events[-1])
697
def get_content(self):
698
return content.Content(
699
content.ContentType("text", "foo"), lambda: ['foo'])
702
class TestExpectedFailure(TestWithDetails):
703
"""Tests for expected failures and unexpected successess."""
705
def make_unexpected_case(self):
706
class Case(TestCase):
708
raise testcase._UnexpectedSuccess
712
def test_raising__UnexpectedSuccess_py27(self):
713
case = self.make_unexpected_case()
714
result = Python27TestResult()
716
case = result._events[0][1]
719
('addUnexpectedSuccess', case),
723
def test_raising__UnexpectedSuccess_extended(self):
724
case = self.make_unexpected_case()
725
result = ExtendedTestResult()
727
case = result._events[0][1]
730
('addUnexpectedSuccess', case, {}),
734
def make_xfail_case_xfails(self):
735
content = self.get_content()
736
class Case(TestCase):
738
self.addDetail("foo", content)
739
self.expectFailure("we are sad", self.assertEqual,
744
def make_xfail_case_succeeds(self):
745
content = self.get_content()
746
class Case(TestCase):
748
self.addDetail("foo", content)
749
self.expectFailure("we are sad", self.assertEqual,
754
def test_expectFailure_KnownFailure_extended(self):
755
case = self.make_xfail_case_xfails()
756
self.assertDetailsProvided(case, "addExpectedFailure",
757
["foo", "traceback", "reason"])
759
def test_expectFailure_KnownFailure_unexpected_success(self):
760
case = self.make_xfail_case_succeeds()
761
self.assertDetailsProvided(case, "addUnexpectedSuccess",
765
class TestUniqueFactories(TestCase):
766
"""Tests for getUniqueString and getUniqueInteger."""
768
def test_getUniqueInteger(self):
769
# getUniqueInteger returns an integer that increments each time you
771
one = self.getUniqueInteger()
772
self.assertEqual(1, one)
773
two = self.getUniqueInteger()
774
self.assertEqual(2, two)
776
def test_getUniqueString(self):
777
# getUniqueString returns the current test id followed by a unique
779
name_one = self.getUniqueString()
780
self.assertEqual('%s-%d' % (self.id(), 1), name_one)
781
name_two = self.getUniqueString()
782
self.assertEqual('%s-%d' % (self.id(), 2), name_two)
784
def test_getUniqueString_prefix(self):
785
# If getUniqueString is given an argument, it uses that argument as
786
# the prefix of the unique string, rather than the test id.
787
name_one = self.getUniqueString('foo')
788
self.assertThat(name_one, Equals('foo-1'))
789
name_two = self.getUniqueString('bar')
790
self.assertThat(name_two, Equals('bar-2'))
793
class TestCloneTestWithNewId(TestCase):
794
"""Tests for clone_test_with_new_id."""
796
def test_clone_test_with_new_id(self):
797
class FooTestCase(TestCase):
800
test = FooTestCase('test_foo')
802
newName = self.getUniqueString()
803
newTest = clone_test_with_new_id(test, newName)
804
self.assertEqual(newName, newTest.id())
805
self.assertEqual(oldName, test.id(),
806
"the original test instance should be unchanged.")
808
def test_cloned_testcase_does_not_share_details(self):
809
"""A cloned TestCase does not share the details dict."""
810
class Test(TestCase):
813
'foo', content.Content('text/plain', lambda: 'foo'))
814
orig_test = Test('test_foo')
815
cloned_test = clone_test_with_new_id(orig_test, self.getUniqueString())
816
orig_test.run(unittest.TestResult())
817
self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
818
self.assertEqual(None, cloned_test.getDetails().get('foo'))
821
class TestDetailsProvided(TestWithDetails):
823
def test_addDetail(self):
824
mycontent = self.get_content()
825
self.addDetail("foo", mycontent)
826
details = self.getDetails()
827
self.assertEqual({"foo": mycontent}, details)
829
def test_addError(self):
830
class Case(TestCase):
832
this.addDetail("foo", self.get_content())
834
self.assertDetailsProvided(Case("test"), "addError",
835
["foo", "traceback"])
837
def test_addFailure(self):
838
class Case(TestCase):
840
this.addDetail("foo", self.get_content())
842
self.assertDetailsProvided(Case("test"), "addFailure",
843
["foo", "traceback"])
845
def test_addSkip(self):
846
class Case(TestCase):
848
this.addDetail("foo", self.get_content())
850
self.assertDetailsProvided(Case("test"), "addSkip",
853
def test_addSucccess(self):
854
class Case(TestCase):
856
this.addDetail("foo", self.get_content())
857
self.assertDetailsProvided(Case("test"), "addSuccess",
860
def test_addUnexpectedSuccess(self):
861
class Case(TestCase):
863
this.addDetail("foo", self.get_content())
864
raise testcase._UnexpectedSuccess()
865
self.assertDetailsProvided(Case("test"), "addUnexpectedSuccess",
868
def test_addDetails_from_Mismatch(self):
869
content = self.get_content()
870
class Mismatch(object):
873
def get_details(self):
874
return {"foo": content}
875
class Matcher(object):
876
def match(self, thing):
879
return "a description"
880
class Case(TestCase):
882
self.assertThat("foo", Matcher())
883
self.assertDetailsProvided(Case("test"), "addFailure",
884
["foo", "traceback"])
886
def test_multiple_addDetails_from_Mismatch(self):
887
content = self.get_content()
888
class Mismatch(object):
891
def get_details(self):
892
return {"foo": content, "bar": content}
893
class Matcher(object):
894
def match(self, thing):
897
return "a description"
898
class Case(TestCase):
900
self.assertThat("foo", Matcher())
901
self.assertDetailsProvided(Case("test"), "addFailure",
902
["bar", "foo", "traceback"])
904
def test_addDetails_with_same_name_as_key_from_get_details(self):
905
content = self.get_content()
906
class Mismatch(object):
909
def get_details(self):
910
return {"foo": content}
911
class Matcher(object):
912
def match(self, thing):
915
return "a description"
916
class Case(TestCase):
918
self.addDetail("foo", content)
919
self.assertThat("foo", Matcher())
920
self.assertDetailsProvided(Case("test"), "addFailure",
921
["foo", "foo-1", "traceback"])
924
class TestSetupTearDown(TestCase):
926
def test_setUpNotCalled(self):
927
class DoesnotcallsetUp(TestCase):
930
def test_method(self):
932
result = unittest.TestResult()
933
DoesnotcallsetUp('test_method').run(result)
934
self.assertEqual(1, len(result.errors))
936
def test_tearDownNotCalled(self):
937
class DoesnotcalltearDown(TestCase):
938
def test_method(self):
942
result = unittest.TestResult()
943
DoesnotcalltearDown('test_method').run(result)
944
self.assertEqual(1, len(result.errors))
947
class TestSkipping(TestCase):
948
"""Tests for skipping of tests functionality."""
950
def test_skip_causes_skipException(self):
951
self.assertThat(lambda:self.skip("Skip this test"),
952
Raises(MatchesException(self.skipException)))
954
def test_can_use_skipTest(self):
955
self.assertThat(lambda:self.skipTest("Skip this test"),
956
Raises(MatchesException(self.skipException)))
958
def test_skip_without_reason_works(self):
959
class Test(TestCase):
961
raise self.skipException()
963
result = ExtendedTestResult()
965
self.assertEqual('addSkip', result._events[1][0])
966
self.assertEqual('no reason given.',
967
''.join(result._events[1][2]['reason'].iter_text()))
969
def test_skipException_in_setup_calls_result_addSkip(self):
970
class TestThatRaisesInSetUp(TestCase):
973
self.skip("skipping this test")
974
def test_that_passes(self):
977
result = LoggingResult(calls)
978
test = TestThatRaisesInSetUp("test_that_passes")
980
case = result._events[0][1]
981
self.assertEqual([('startTest', case),
982
('addSkip', case, "skipping this test"), ('stopTest', case)],
985
def test_skipException_in_test_method_calls_result_addSkip(self):
986
class SkippingTest(TestCase):
987
def test_that_raises_skipException(self):
988
self.skip("skipping this test")
989
result = Python27TestResult()
990
test = SkippingTest("test_that_raises_skipException")
992
case = result._events[0][1]
993
self.assertEqual([('startTest', case),
994
('addSkip', case, "skipping this test"), ('stopTest', case)],
997
def test_skip__in_setup_with_old_result_object_calls_addSuccess(self):
998
class SkippingTest(TestCase):
1000
TestCase.setUp(self)
1001
raise self.skipException("skipping this test")
1002
def test_that_raises_skipException(self):
1004
result = Python26TestResult()
1005
test = SkippingTest("test_that_raises_skipException")
1007
self.assertEqual('addSuccess', result._events[1][0])
1009
def test_skip_with_old_result_object_calls_addError(self):
1010
class SkippingTest(TestCase):
1011
def test_that_raises_skipException(self):
1012
raise self.skipException("skipping this test")
1013
result = Python26TestResult()
1014
test = SkippingTest("test_that_raises_skipException")
1016
self.assertEqual('addSuccess', result._events[1][0])
1018
def test_skip_decorator(self):
1019
class SkippingTest(TestCase):
1020
@skip("skipping this test")
1021
def test_that_is_decorated_with_skip(self):
1023
result = Python26TestResult()
1024
test = SkippingTest("test_that_is_decorated_with_skip")
1026
self.assertEqual('addSuccess', result._events[1][0])
1028
def test_skipIf_decorator(self):
1029
class SkippingTest(TestCase):
1030
@skipIf(True, "skipping this test")
1031
def test_that_is_decorated_with_skipIf(self):
1033
result = Python26TestResult()
1034
test = SkippingTest("test_that_is_decorated_with_skipIf")
1036
self.assertEqual('addSuccess', result._events[1][0])
1038
def test_skipUnless_decorator(self):
1039
class SkippingTest(TestCase):
1040
@skipUnless(False, "skipping this test")
1041
def test_that_is_decorated_with_skipUnless(self):
1043
result = Python26TestResult()
1044
test = SkippingTest("test_that_is_decorated_with_skipUnless")
1046
self.assertEqual('addSuccess', result._events[1][0])
1049
class TestOnException(TestCase):
1051
def test_default_works(self):
1053
class Case(TestCase):
1055
self.onException(an_exc_info)
1057
case = Case("method")
1059
self.assertThat(events, Equals([True]))
1061
def test_added_handler_works(self):
1063
class Case(TestCase):
1065
self.addOnException(events.append)
1066
self.onException(an_exc_info)
1067
case = Case("method")
1069
self.assertThat(events, Equals([an_exc_info]))
1071
def test_handler_that_raises_is_not_caught(self):
1073
class Case(TestCase):
1075
self.addOnException(events.index)
1076
self.assertThat(lambda: self.onException(an_exc_info),
1077
Raises(MatchesException(ValueError)))
1078
case = Case("method")
1080
self.assertThat(events, Equals([]))
1083
class TestPatchSupport(TestCase):
1085
class Case(TestCase):
1089
def test_patch(self):
1090
# TestCase.patch masks obj.attribute with the new value.
1091
self.foo = 'original'
1092
test = self.Case('test')
1093
test.patch(self, 'foo', 'patched')
1094
self.assertEqual('patched', self.foo)
1096
def test_patch_restored_after_run(self):
1097
# TestCase.patch masks obj.attribute with the new value, but restores
1098
# the original value after the test is finished.
1099
self.foo = 'original'
1100
test = self.Case('test')
1101
test.patch(self, 'foo', 'patched')
1103
self.assertEqual('original', self.foo)
1105
def test_successive_patches_apply(self):
1106
# TestCase.patch can be called multiple times per test. Each time you
1107
# call it, it overrides the original value.
1108
self.foo = 'original'
1109
test = self.Case('test')
1110
test.patch(self, 'foo', 'patched')
1111
test.patch(self, 'foo', 'second')
1112
self.assertEqual('second', self.foo)
1114
def test_successive_patches_restored_after_run(self):
1115
# TestCase.patch restores the original value, no matter how many times
1117
self.foo = 'original'
1118
test = self.Case('test')
1119
test.patch(self, 'foo', 'patched')
1120
test.patch(self, 'foo', 'second')
1122
self.assertEqual('original', self.foo)
1124
def test_patch_nonexistent_attribute(self):
1125
# TestCase.patch can be used to patch a non-existent attribute.
1126
test = self.Case('test')
1127
test.patch(self, 'doesntexist', 'patched')
1128
self.assertEqual('patched', self.doesntexist)
1130
def test_restore_nonexistent_attribute(self):
1131
# TestCase.patch can be used to patch a non-existent attribute, after
1132
# the test run, the attribute is then removed from the object.
1133
test = self.Case('test')
1134
test.patch(self, 'doesntexist', 'patched')
1137
value = getattr(self, 'doesntexist', marker)
1138
self.assertIs(marker, value)
1142
from unittest import TestLoader
1143
return TestLoader().loadTestsFromName(__name__)