bb0aba6496172b1605cbcfa119817c802955e3bb
[metze/samba/wip.git] / lib / testtools / testtools / tests / test_testcase.py
1 # Copyright (c) 2008-2011 testtools developers. See LICENSE for details.
2
3 """Tests for extensions to the base test library."""
4
5 from doctest import ELLIPSIS
6 from pprint import pformat
7 import sys
8 import unittest
9
10 from testtools import (
11     ErrorHolder,
12     MultipleExceptions,
13     PlaceHolder,
14     TestCase,
15     clone_test_with_new_id,
16     content,
17     skip,
18     skipIf,
19     skipUnless,
20     testcase,
21     )
22 from testtools.compat import (
23     _b,
24     _u,
25     )
26 from testtools.matchers import (
27     Annotate,
28     DocTestMatches,
29     Equals,
30     MatchesException,
31     Raises,
32     )
33 from testtools.testresult.doubles import (
34     Python26TestResult,
35     Python27TestResult,
36     ExtendedTestResult,
37     )
38 from testtools.testresult.real import TestResult
39 from testtools.tests.helpers import (
40     an_exc_info,
41     FullStackRunTest,
42     LoggingResult,
43     )
44 try:
45     exec('from __future__ import with_statement')
46 except SyntaxError:
47     pass
48 else:
49     from testtools.tests.test_with_with import *
50
51
52 class TestPlaceHolder(TestCase):
53
54     run_test_with = FullStackRunTest
55
56     def makePlaceHolder(self, test_id="foo", short_description=None):
57         return PlaceHolder(test_id, short_description)
58
59     def test_id_comes_from_constructor(self):
60         # The id() of a PlaceHolder is whatever you pass into the constructor.
61         test = PlaceHolder("test id")
62         self.assertEqual("test id", test.id())
63
64     def test_shortDescription_is_id(self):
65         # The shortDescription() of a PlaceHolder is the id, by default.
66         test = PlaceHolder("test id")
67         self.assertEqual(test.id(), test.shortDescription())
68
69     def test_shortDescription_specified(self):
70         # If a shortDescription is provided to the constructor, then
71         # shortDescription() returns that instead.
72         test = PlaceHolder("test id", "description")
73         self.assertEqual("description", test.shortDescription())
74
75     def test_repr_just_id(self):
76         # repr(placeholder) shows you how the object was constructed.
77         test = PlaceHolder("test id")
78         self.assertEqual(
79             "<testtools.testcase.PlaceHolder(%s)>" % repr(test.id()),
80             repr(test))
81
82     def test_repr_with_description(self):
83         # repr(placeholder) shows you how the object was constructed.
84         test = PlaceHolder("test id", "description")
85         self.assertEqual(
86             "<testtools.testcase.PlaceHolder(%r, %r)>" % (
87                 test.id(), test.shortDescription()),
88             repr(test))
89
90     def test_counts_as_one_test(self):
91         # A placeholder test counts as one test.
92         test = self.makePlaceHolder()
93         self.assertEqual(1, test.countTestCases())
94
95     def test_str_is_id(self):
96         # str(placeholder) is always the id(). We are not barbarians.
97         test = self.makePlaceHolder()
98         self.assertEqual(test.id(), str(test))
99
100     def test_runs_as_success(self):
101         # When run, a PlaceHolder test records a success.
102         test = self.makePlaceHolder()
103         log = []
104         test.run(LoggingResult(log))
105         self.assertEqual(
106             [('startTest', test), ('addSuccess', test), ('stopTest', test)],
107             log)
108
109     def test_call_is_run(self):
110         # A PlaceHolder can be called, in which case it behaves like run.
111         test = self.makePlaceHolder()
112         run_log = []
113         test.run(LoggingResult(run_log))
114         call_log = []
115         test(LoggingResult(call_log))
116         self.assertEqual(run_log, call_log)
117
118     def test_runs_without_result(self):
119         # A PlaceHolder can be run without a result, in which case there's no
120         # way to actually get at the result.
121         self.makePlaceHolder().run()
122
123     def test_debug(self):
124         # A PlaceHolder can be debugged.
125         self.makePlaceHolder().debug()
126
127
128 class TestErrorHolder(TestCase):
129
130     run_test_with = FullStackRunTest
131
132     def makeException(self):
133         try:
134             raise RuntimeError("danger danger")
135         except:
136             return sys.exc_info()
137
138     def makePlaceHolder(self, test_id="foo", error=None,
139                         short_description=None):
140         if error is None:
141             error = self.makeException()
142         return ErrorHolder(test_id, error, short_description)
143
144     def test_id_comes_from_constructor(self):
145         # The id() of a PlaceHolder is whatever you pass into the constructor.
146         test = ErrorHolder("test id", self.makeException())
147         self.assertEqual("test id", test.id())
148
149     def test_shortDescription_is_id(self):
150         # The shortDescription() of a PlaceHolder is the id, by default.
151         test = ErrorHolder("test id", self.makeException())
152         self.assertEqual(test.id(), test.shortDescription())
153
154     def test_shortDescription_specified(self):
155         # If a shortDescription is provided to the constructor, then
156         # shortDescription() returns that instead.
157         test = ErrorHolder("test id", self.makeException(), "description")
158         self.assertEqual("description", test.shortDescription())
159
160     def test_repr_just_id(self):
161         # repr(placeholder) shows you how the object was constructed.
162         error = self.makeException()
163         test = ErrorHolder("test id", error)
164         self.assertEqual(
165             "<testtools.testcase.ErrorHolder(%r, %r)>" % (test.id(), error),
166             repr(test))
167
168     def test_repr_with_description(self):
169         # repr(placeholder) shows you how the object was constructed.
170         error = self.makeException()
171         test = ErrorHolder("test id", error, "description")
172         self.assertEqual(
173             "<testtools.testcase.ErrorHolder(%r, %r, %r)>" % (
174                 test.id(), error, test.shortDescription()),
175             repr(test))
176
177     def test_counts_as_one_test(self):
178         # A placeholder test counts as one test.
179         test = self.makePlaceHolder()
180         self.assertEqual(1, test.countTestCases())
181
182     def test_str_is_id(self):
183         # str(placeholder) is always the id(). We are not barbarians.
184         test = self.makePlaceHolder()
185         self.assertEqual(test.id(), str(test))
186
187     def test_runs_as_error(self):
188         # When run, a PlaceHolder test records a success.
189         error = self.makeException()
190         test = self.makePlaceHolder(error=error)
191         log = []
192         test.run(LoggingResult(log))
193         self.assertEqual(
194             [('startTest', test),
195              ('addError', test, error),
196              ('stopTest', test)], log)
197
198     def test_call_is_run(self):
199         # A PlaceHolder can be called, in which case it behaves like run.
200         test = self.makePlaceHolder()
201         run_log = []
202         test.run(LoggingResult(run_log))
203         call_log = []
204         test(LoggingResult(call_log))
205         self.assertEqual(run_log, call_log)
206
207     def test_runs_without_result(self):
208         # A PlaceHolder can be run without a result, in which case there's no
209         # way to actually get at the result.
210         self.makePlaceHolder().run()
211
212     def test_debug(self):
213         # A PlaceHolder can be debugged.
214         self.makePlaceHolder().debug()
215
216
217 class TestEquality(TestCase):
218     """Test ``TestCase``'s equality implementation."""
219
220     run_test_with = FullStackRunTest
221
222     def test_identicalIsEqual(self):
223         # TestCase's are equal if they are identical.
224         self.assertEqual(self, self)
225
226     def test_nonIdenticalInUnequal(self):
227         # TestCase's are not equal if they are not identical.
228         self.assertNotEqual(TestCase(methodName='run'),
229             TestCase(methodName='skip'))
230
231
232 class TestAssertions(TestCase):
233     """Test assertions in TestCase."""
234
235     run_test_with = FullStackRunTest
236
237     def raiseError(self, exceptionFactory, *args, **kwargs):
238         raise exceptionFactory(*args, **kwargs)
239
240     def test_formatTypes_single(self):
241         # Given a single class, _formatTypes returns the name.
242         class Foo(object):
243             pass
244         self.assertEqual('Foo', self._formatTypes(Foo))
245
246     def test_formatTypes_multiple(self):
247         # Given multiple types, _formatTypes returns the names joined by
248         # commas.
249         class Foo(object):
250             pass
251         class Bar(object):
252             pass
253         self.assertEqual('Foo, Bar', self._formatTypes([Foo, Bar]))
254
255     def test_assertRaises(self):
256         # assertRaises asserts that a callable raises a particular exception.
257         self.assertRaises(RuntimeError, self.raiseError, RuntimeError)
258
259     def test_assertRaises_fails_when_no_error_raised(self):
260         # assertRaises raises self.failureException when it's passed a
261         # callable that raises no error.
262         ret = ('orange', 42)
263         self.assertFails("<function <lambda> at ...> returned ('orange', 42)",
264             self.assertRaises, RuntimeError, lambda: ret)
265
266     def test_assertRaises_fails_when_different_error_raised(self):
267         # assertRaises re-raises an exception that it didn't expect.
268         self.assertThat(lambda: self.assertRaises(RuntimeError,
269             self.raiseError, ZeroDivisionError),
270             Raises(MatchesException(ZeroDivisionError)))
271
272     def test_assertRaises_returns_the_raised_exception(self):
273         # assertRaises returns the exception object that was raised. This is
274         # useful for testing that exceptions have the right message.
275
276         # This contraption stores the raised exception, so we can compare it
277         # to the return value of assertRaises.
278         raisedExceptions = []
279         def raiseError():
280             try:
281                 raise RuntimeError('Deliberate error')
282             except RuntimeError:
283                 raisedExceptions.append(sys.exc_info()[1])
284                 raise
285
286         exception = self.assertRaises(RuntimeError, raiseError)
287         self.assertEqual(1, len(raisedExceptions))
288         self.assertTrue(
289             exception is raisedExceptions[0],
290             "%r is not %r" % (exception, raisedExceptions[0]))
291
292     def test_assertRaises_with_multiple_exceptions(self):
293         # assertRaises((ExceptionOne, ExceptionTwo), function) asserts that
294         # function raises one of ExceptionTwo or ExceptionOne.
295         expectedExceptions = (RuntimeError, ZeroDivisionError)
296         self.assertRaises(
297             expectedExceptions, self.raiseError, expectedExceptions[0])
298         self.assertRaises(
299             expectedExceptions, self.raiseError, expectedExceptions[1])
300
301     def test_assertRaises_with_multiple_exceptions_failure_mode(self):
302         # If assertRaises is called expecting one of a group of exceptions and
303         # a callable that doesn't raise an exception, then fail with an
304         # appropriate error message.
305         expectedExceptions = (RuntimeError, ZeroDivisionError)
306         failure = self.assertRaises(
307             self.failureException,
308             self.assertRaises, expectedExceptions, lambda: None)
309         self.assertFails('<function <lambda> at ...> returned None',
310             self.assertRaises, expectedExceptions, lambda: None)
311
312     def assertFails(self, message, function, *args, **kwargs):
313         """Assert that function raises a failure with the given message."""
314         failure = self.assertRaises(
315             self.failureException, function, *args, **kwargs)
316         self.assertThat(failure, DocTestMatches(message, ELLIPSIS))
317
318     def test_assertIn_success(self):
319         # assertIn(needle, haystack) asserts that 'needle' is in 'haystack'.
320         self.assertIn(3, range(10))
321         self.assertIn('foo', 'foo bar baz')
322         self.assertIn('foo', 'foo bar baz'.split())
323
324     def test_assertIn_failure(self):
325         # assertIn(needle, haystack) fails the test when 'needle' is not in
326         # 'haystack'.
327         self.assertFails('3 not in [0, 1, 2]', self.assertIn, 3, [0, 1, 2])
328         self.assertFails(
329             '%r not in %r' % ('qux', 'foo bar baz'),
330             self.assertIn, 'qux', 'foo bar baz')
331
332     def test_assertNotIn_success(self):
333         # assertNotIn(needle, haystack) asserts that 'needle' is not in
334         # 'haystack'.
335         self.assertNotIn(3, [0, 1, 2])
336         self.assertNotIn('qux', 'foo bar baz')
337
338     def test_assertNotIn_failure(self):
339         # assertNotIn(needle, haystack) fails the test when 'needle' is in
340         # 'haystack'.
341         self.assertFails('[1, 2, 3] matches Contains(3)', self.assertNotIn,
342             3, [1, 2, 3])
343         self.assertFails(
344             "'foo bar baz' matches Contains('foo')",
345             self.assertNotIn, 'foo', 'foo bar baz')
346
347     def test_assertIsInstance(self):
348         # assertIsInstance asserts that an object is an instance of a class.
349
350         class Foo(object):
351             """Simple class for testing assertIsInstance."""
352
353         foo = Foo()
354         self.assertIsInstance(foo, Foo)
355
356     def test_assertIsInstance_multiple_classes(self):
357         # assertIsInstance asserts that an object is an instance of one of a
358         # group of classes.
359
360         class Foo(object):
361             """Simple class for testing assertIsInstance."""
362
363         class Bar(object):
364             """Another simple class for testing assertIsInstance."""
365
366         foo = Foo()
367         self.assertIsInstance(foo, (Foo, Bar))
368         self.assertIsInstance(Bar(), (Foo, Bar))
369
370     def test_assertIsInstance_failure(self):
371         # assertIsInstance(obj, klass) fails the test when obj is not an
372         # instance of klass.
373
374         class Foo(object):
375             """Simple class for testing assertIsInstance."""
376
377         self.assertFails(
378             "'42' is not an instance of %s" % self._formatTypes(Foo),
379             self.assertIsInstance, 42, Foo)
380
381     def test_assertIsInstance_failure_multiple_classes(self):
382         # assertIsInstance(obj, (klass1, klass2)) fails the test when obj is
383         # not an instance of klass1 or klass2.
384
385         class Foo(object):
386             """Simple class for testing assertIsInstance."""
387
388         class Bar(object):
389             """Another simple class for testing assertIsInstance."""
390
391         self.assertFails(
392             "'42' is not an instance of any of (%s)" % self._formatTypes([Foo, Bar]),
393             self.assertIsInstance, 42, (Foo, Bar))
394
395     def test_assertIsInstance_overridden_message(self):
396         # assertIsInstance(obj, klass, msg) permits a custom message.
397         self.assertFails("'42' is not an instance of str: foo",
398             self.assertIsInstance, 42, str, "foo")
399
400     def test_assertIs(self):
401         # assertIs asserts that an object is identical to another object.
402         self.assertIs(None, None)
403         some_list = [42]
404         self.assertIs(some_list, some_list)
405         some_object = object()
406         self.assertIs(some_object, some_object)
407
408     def test_assertIs_fails(self):
409         # assertIs raises assertion errors if one object is not identical to
410         # another.
411         self.assertFails('None is not 42', self.assertIs, None, 42)
412         self.assertFails('[42] is not [42]', self.assertIs, [42], [42])
413
414     def test_assertIs_fails_with_message(self):
415         # assertIs raises assertion errors if one object is not identical to
416         # another, and includes a user-supplied message, if it's provided.
417         self.assertFails(
418             'None is not 42: foo bar', self.assertIs, None, 42, 'foo bar')
419
420     def test_assertIsNot(self):
421         # assertIsNot asserts that an object is not identical to another
422         # object.
423         self.assertIsNot(None, 42)
424         self.assertIsNot([42], [42])
425         self.assertIsNot(object(), object())
426
427     def test_assertIsNot_fails(self):
428         # assertIsNot raises assertion errors if one object is identical to
429         # another.
430         self.assertFails('None matches Is(None)', self.assertIsNot, None, None)
431         some_list = [42]
432         self.assertFails(
433             '[42] matches Is([42])', self.assertIsNot, some_list, some_list)
434
435     def test_assertIsNot_fails_with_message(self):
436         # assertIsNot raises assertion errors if one object is identical to
437         # another, and includes a user-supplied message if it's provided.
438         self.assertFails(
439             'None matches Is(None): foo bar', self.assertIsNot, None, None,
440             "foo bar")
441
442     def test_assertThat_matches_clean(self):
443         class Matcher(object):
444             def match(self, foo):
445                 return None
446         self.assertThat("foo", Matcher())
447
448     def test_assertThat_mismatch_raises_description(self):
449         calls = []
450         class Mismatch(object):
451             def __init__(self, thing):
452                 self.thing = thing
453             def describe(self):
454                 calls.append(('describe_diff', self.thing))
455                 return "object is not a thing"
456             def get_details(self):
457                 return {}
458         class Matcher(object):
459             def match(self, thing):
460                 calls.append(('match', thing))
461                 return Mismatch(thing)
462             def __str__(self):
463                 calls.append(('__str__',))
464                 return "a description"
465         class Test(TestCase):
466             def test(self):
467                 self.assertThat("foo", Matcher())
468         result = Test("test").run()
469         self.assertEqual([
470             ('match', "foo"),
471             ('describe_diff', "foo"),
472             ], calls)
473         self.assertFalse(result.wasSuccessful())
474
475     def test_assertThat_output(self):
476         matchee = 'foo'
477         matcher = Equals('bar')
478         expected = matcher.match(matchee).describe()
479         self.assertFails(expected, self.assertThat, matchee, matcher)
480
481     def test_assertThat_message_is_annotated(self):
482         matchee = 'foo'
483         matcher = Equals('bar')
484         expected = Annotate('woo', matcher).match(matchee).describe()
485         self.assertFails(expected, self.assertThat, matchee, matcher, 'woo')
486
487     def test_assertThat_verbose_output(self):
488         matchee = 'foo'
489         matcher = Equals('bar')
490         expected = (
491             'Match failed. Matchee: %r\n'
492             'Matcher: %s\n'
493             'Difference: %s\n' % (
494                 matchee,
495                 matcher,
496                 matcher.match(matchee).describe(),
497                 ))
498         self.assertFails(
499             expected, self.assertThat, matchee, matcher, verbose=True)
500
501     def get_error_string(self, e):
502         """Get the string showing how 'e' would be formatted in test output.
503
504         This is a little bit hacky, since it's designed to give consistent
505         output regardless of Python version.
506
507         In testtools, TestResult._exc_info_to_unicode is the point of dispatch
508         between various different implementations of methods that format
509         exceptions, so that's what we have to call. However, that method cares
510         about stack traces and formats the exception class. We don't care
511         about either of these, so we take its output and parse it a little.
512         """
513         error = TestResult()._exc_info_to_unicode((e.__class__, e, None), self)
514         # We aren't at all interested in the traceback.
515         if error.startswith('Traceback (most recent call last):\n'):
516             lines = error.splitlines(True)[1:]
517             for i, line in enumerate(lines):
518                 if not line.startswith(' '):
519                     break
520             error = ''.join(lines[i:])
521         # We aren't interested in how the exception type is formatted.
522         exc_class, error = error.split(': ', 1)
523         return error
524
525     def test_assertThat_verbose_unicode(self):
526         # When assertThat is given matchees or matchers that contain non-ASCII
527         # unicode strings, we can still provide a meaningful error.
528         matchee = _u('\xa7')
529         matcher = Equals(_u('a'))
530         expected = (
531             'Match failed. Matchee: %s\n'
532             'Matcher: %s\n'
533             'Difference: %s\n\n' % (
534                 repr(matchee).replace("\\xa7", matchee),
535                 matcher,
536                 matcher.match(matchee).describe(),
537                 ))
538         e = self.assertRaises(
539             self.failureException, self.assertThat, matchee, matcher,
540             verbose=True)
541         self.assertEqual(expected, self.get_error_string(e))
542
543     def test_assertEqual_nice_formatting(self):
544         message = "These things ought not be equal."
545         a = ['apple', 'banana', 'cherry']
546         b = {'Thatcher': 'One who mends roofs of straw',
547              'Major': 'A military officer, ranked below colonel',
548              'Blair': 'To shout loudly',
549              'Brown': 'The colour of healthy human faeces'}
550         expected_error = '\n'.join([
551             '!=:',
552             'reference = %s' % pformat(a),
553             'actual    = %s' % pformat(b),
554             ': ' + message,
555             ])
556         self.assertFails(expected_error, self.assertEqual, a, b, message)
557         self.assertFails(expected_error, self.assertEquals, a, b, message)
558         self.assertFails(expected_error, self.failUnlessEqual, a, b, message)
559
560     def test_assertEqual_formatting_no_message(self):
561         a = "cat"
562         b = "dog"
563         expected_error = "'cat' != 'dog'"
564         self.assertFails(expected_error, self.assertEqual, a, b)
565         self.assertFails(expected_error, self.assertEquals, a, b)
566         self.assertFails(expected_error, self.failUnlessEqual, a, b)
567
568     def test_assertEqual_non_ascii_str_with_newlines(self):
569         message = _u("Be careful mixing unicode and bytes")
570         a = "a\n\xa7\n"
571         b = "Just a longish string so the more verbose output form is used."
572         expected_error = '\n'.join([
573             '!=:',
574             "reference = '''\\",
575             'a',
576             repr('\xa7')[1:-1],
577             "'''",
578             'actual    = %r' % (b,),
579             ': ' + message,
580             ])
581         self.assertFails(expected_error, self.assertEqual, a, b, message)
582
583     def test_assertIsNone(self):
584         self.assertIsNone(None)
585
586         expected_error = 'None is not 0'
587         self.assertFails(expected_error, self.assertIsNone, 0)
588
589     def test_assertIsNotNone(self):
590         self.assertIsNotNone(0)
591         self.assertIsNotNone("0")
592
593         expected_error = 'None matches Is(None)'
594         self.assertFails(expected_error, self.assertIsNotNone, None)
595
596
597 class TestAddCleanup(TestCase):
598     """Tests for TestCase.addCleanup."""
599
600     run_test_with = FullStackRunTest
601
602     class LoggingTest(TestCase):
603         """A test that logs calls to setUp, runTest and tearDown."""
604
605         def setUp(self):
606             TestCase.setUp(self)
607             self._calls = ['setUp']
608
609         def brokenSetUp(self):
610             # A tearDown that deliberately fails.
611             self._calls = ['brokenSetUp']
612             raise RuntimeError('Deliberate Failure')
613
614         def runTest(self):
615             self._calls.append('runTest')
616
617         def brokenTest(self):
618             raise RuntimeError('Deliberate broken test')
619
620         def tearDown(self):
621             self._calls.append('tearDown')
622             TestCase.tearDown(self)
623
624     def setUp(self):
625         TestCase.setUp(self)
626         self._result_calls = []
627         self.test = TestAddCleanup.LoggingTest('runTest')
628         self.logging_result = LoggingResult(self._result_calls)
629
630     def assertErrorLogEqual(self, messages):
631         self.assertEqual(messages, [call[0] for call in self._result_calls])
632
633     def assertTestLogEqual(self, messages):
634         """Assert that the call log equals 'messages'."""
635         case = self._result_calls[0][1]
636         self.assertEqual(messages, case._calls)
637
638     def logAppender(self, message):
639         """A cleanup that appends 'message' to the tests log.
640
641         Cleanups are callables that are added to a test by addCleanup. To
642         verify that our cleanups run in the right order, we add strings to a
643         list that acts as a log. This method returns a cleanup that will add
644         the given message to that log when run.
645         """
646         self.test._calls.append(message)
647
648     def test_fixture(self):
649         # A normal run of self.test logs 'setUp', 'runTest' and 'tearDown'.
650         # This test doesn't test addCleanup itself, it just sanity checks the
651         # fixture.
652         self.test.run(self.logging_result)
653         self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
654
655     def test_cleanup_run_before_tearDown(self):
656         # Cleanup functions added with 'addCleanup' are called before tearDown
657         # runs.
658         self.test.addCleanup(self.logAppender, 'cleanup')
659         self.test.run(self.logging_result)
660         self.assertTestLogEqual(['setUp', 'runTest', 'tearDown', 'cleanup'])
661
662     def test_add_cleanup_called_if_setUp_fails(self):
663         # Cleanup functions added with 'addCleanup' are called even if setUp
664         # fails. Note that tearDown has a different behavior: it is only
665         # called when setUp succeeds.
666         self.test.setUp = self.test.brokenSetUp
667         self.test.addCleanup(self.logAppender, 'cleanup')
668         self.test.run(self.logging_result)
669         self.assertTestLogEqual(['brokenSetUp', 'cleanup'])
670
671     def test_addCleanup_called_in_reverse_order(self):
672         # Cleanup functions added with 'addCleanup' are called in reverse
673         # order.
674         #
675         # One of the main uses of addCleanup is to dynamically create
676         # resources that need some sort of explicit tearDown. Often one
677         # resource will be created in terms of another, e.g.,
678         #     self.first = self.makeFirst()
679         #     self.second = self.makeSecond(self.first)
680         #
681         # When this happens, we generally want to clean up the second resource
682         # before the first one, since the second depends on the first.
683         self.test.addCleanup(self.logAppender, 'first')
684         self.test.addCleanup(self.logAppender, 'second')
685         self.test.run(self.logging_result)
686         self.assertTestLogEqual(
687             ['setUp', 'runTest', 'tearDown', 'second', 'first'])
688
689     def test_tearDown_runs_after_cleanup_failure(self):
690         # tearDown runs even if a cleanup function fails.
691         self.test.addCleanup(lambda: 1/0)
692         self.test.run(self.logging_result)
693         self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
694
695     def test_cleanups_continue_running_after_error(self):
696         # All cleanups are always run, even if one or two of them fail.
697         self.test.addCleanup(self.logAppender, 'first')
698         self.test.addCleanup(lambda: 1/0)
699         self.test.addCleanup(self.logAppender, 'second')
700         self.test.run(self.logging_result)
701         self.assertTestLogEqual(
702             ['setUp', 'runTest', 'tearDown', 'second', 'first'])
703
704     def test_error_in_cleanups_are_captured(self):
705         # If a cleanup raises an error, we want to record it and fail the the
706         # test, even though we go on to run other cleanups.
707         self.test.addCleanup(lambda: 1/0)
708         self.test.run(self.logging_result)
709         self.assertErrorLogEqual(['startTest', 'addError', 'stopTest'])
710
711     def test_keyboard_interrupt_not_caught(self):
712         # If a cleanup raises KeyboardInterrupt, it gets reraised.
713         def raiseKeyboardInterrupt():
714             raise KeyboardInterrupt()
715         self.test.addCleanup(raiseKeyboardInterrupt)
716         self.assertThat(lambda:self.test.run(self.logging_result),
717             Raises(MatchesException(KeyboardInterrupt)))
718
719     def test_all_errors_from_MultipleExceptions_reported(self):
720         # When a MultipleExceptions exception is caught, all the errors are
721         # reported.
722         def raiseMany():
723             try:
724                 1/0
725             except Exception:
726                 exc_info1 = sys.exc_info()
727             try:
728                 1/0
729             except Exception:
730                 exc_info2 = sys.exc_info()
731             raise MultipleExceptions(exc_info1, exc_info2)
732         self.test.addCleanup(raiseMany)
733         self.logging_result = ExtendedTestResult()
734         self.test.run(self.logging_result)
735         self.assertEqual(['startTest', 'addError', 'stopTest'],
736             [event[0] for event in self.logging_result._events])
737         self.assertEqual(set(['traceback', 'traceback-1']),
738             set(self.logging_result._events[1][2].keys()))
739
740     def test_multipleCleanupErrorsReported(self):
741         # Errors from all failing cleanups are reported as separate backtraces.
742         self.test.addCleanup(lambda: 1/0)
743         self.test.addCleanup(lambda: 1/0)
744         self.logging_result = ExtendedTestResult()
745         self.test.run(self.logging_result)
746         self.assertEqual(['startTest', 'addError', 'stopTest'],
747             [event[0] for event in self.logging_result._events])
748         self.assertEqual(set(['traceback', 'traceback-1']),
749             set(self.logging_result._events[1][2].keys()))
750
751     def test_multipleErrorsCoreAndCleanupReported(self):
752         # Errors from all failing cleanups are reported, with stopTest,
753         # startTest inserted.
754         self.test = TestAddCleanup.LoggingTest('brokenTest')
755         self.test.addCleanup(lambda: 1/0)
756         self.test.addCleanup(lambda: 1/0)
757         self.logging_result = ExtendedTestResult()
758         self.test.run(self.logging_result)
759         self.assertEqual(['startTest', 'addError', 'stopTest'],
760             [event[0] for event in self.logging_result._events])
761         self.assertEqual(set(['traceback', 'traceback-1', 'traceback-2']),
762             set(self.logging_result._events[1][2].keys()))
763
764
765 class TestWithDetails(TestCase):
766
767     run_test_with = FullStackRunTest
768
769     def assertDetailsProvided(self, case, expected_outcome, expected_keys):
770         """Assert that when case is run, details are provided to the result.
771
772         :param case: A TestCase to run.
773         :param expected_outcome: The call that should be made.
774         :param expected_keys: The keys to look for.
775         """
776         result = ExtendedTestResult()
777         case.run(result)
778         case = result._events[0][1]
779         expected = [
780             ('startTest', case),
781             (expected_outcome, case),
782             ('stopTest', case),
783             ]
784         self.assertEqual(3, len(result._events))
785         self.assertEqual(expected[0], result._events[0])
786         self.assertEqual(expected[1], result._events[1][0:2])
787         # Checking the TB is right is rather tricky. doctest line matching
788         # would help, but 'meh'.
789         self.assertEqual(sorted(expected_keys),
790             sorted(result._events[1][2].keys()))
791         self.assertEqual(expected[-1], result._events[-1])
792
793     def get_content(self):
794         return content.Content(
795             content.ContentType("text", "foo"), lambda: [_b('foo')])
796
797
798 class TestExpectedFailure(TestWithDetails):
799     """Tests for expected failures and unexpected successess."""
800
801     run_test_with = FullStackRunTest
802
803     def make_unexpected_case(self):
804         class Case(TestCase):
805             def test(self):
806                 raise testcase._UnexpectedSuccess
807         case = Case('test')
808         return case
809
810     def test_raising__UnexpectedSuccess_py27(self):
811         case = self.make_unexpected_case()
812         result = Python27TestResult()
813         case.run(result)
814         case = result._events[0][1]
815         self.assertEqual([
816             ('startTest', case),
817             ('addUnexpectedSuccess', case),
818             ('stopTest', case),
819             ], result._events)
820
821     def test_raising__UnexpectedSuccess_extended(self):
822         case = self.make_unexpected_case()
823         result = ExtendedTestResult()
824         case.run(result)
825         case = result._events[0][1]
826         self.assertEqual([
827             ('startTest', case),
828             ('addUnexpectedSuccess', case, {}),
829             ('stopTest', case),
830             ], result._events)
831
832     def make_xfail_case_xfails(self):
833         content = self.get_content()
834         class Case(TestCase):
835             def test(self):
836                 self.addDetail("foo", content)
837                 self.expectFailure("we are sad", self.assertEqual,
838                     1, 0)
839         case = Case('test')
840         return case
841
842     def make_xfail_case_succeeds(self):
843         content = self.get_content()
844         class Case(TestCase):
845             def test(self):
846                 self.addDetail("foo", content)
847                 self.expectFailure("we are sad", self.assertEqual,
848                     1, 1)
849         case = Case('test')
850         return case
851
852     def test_expectFailure_KnownFailure_extended(self):
853         case = self.make_xfail_case_xfails()
854         self.assertDetailsProvided(case, "addExpectedFailure",
855             ["foo", "traceback", "reason"])
856
857     def test_expectFailure_KnownFailure_unexpected_success(self):
858         case = self.make_xfail_case_succeeds()
859         self.assertDetailsProvided(case, "addUnexpectedSuccess",
860             ["foo", "reason"])
861
862
863 class TestUniqueFactories(TestCase):
864     """Tests for getUniqueString and getUniqueInteger."""
865
866     run_test_with = FullStackRunTest
867
868     def test_getUniqueInteger(self):
869         # getUniqueInteger returns an integer that increments each time you
870         # call it.
871         one = self.getUniqueInteger()
872         self.assertEqual(1, one)
873         two = self.getUniqueInteger()
874         self.assertEqual(2, two)
875
876     def test_getUniqueString(self):
877         # getUniqueString returns the current test id followed by a unique
878         # integer.
879         name_one = self.getUniqueString()
880         self.assertEqual('%s-%d' % (self.id(), 1), name_one)
881         name_two = self.getUniqueString()
882         self.assertEqual('%s-%d' % (self.id(), 2), name_two)
883
884     def test_getUniqueString_prefix(self):
885         # If getUniqueString is given an argument, it uses that argument as
886         # the prefix of the unique string, rather than the test id.
887         name_one = self.getUniqueString('foo')
888         self.assertThat(name_one, Equals('foo-1'))
889         name_two = self.getUniqueString('bar')
890         self.assertThat(name_two, Equals('bar-2'))
891
892
893 class TestCloneTestWithNewId(TestCase):
894     """Tests for clone_test_with_new_id."""
895
896     run_test_with = FullStackRunTest
897
898     def test_clone_test_with_new_id(self):
899         class FooTestCase(TestCase):
900             def test_foo(self):
901                 pass
902         test = FooTestCase('test_foo')
903         oldName = test.id()
904         newName = self.getUniqueString()
905         newTest = clone_test_with_new_id(test, newName)
906         self.assertEqual(newName, newTest.id())
907         self.assertEqual(oldName, test.id(),
908             "the original test instance should be unchanged.")
909
910     def test_cloned_testcase_does_not_share_details(self):
911         """A cloned TestCase does not share the details dict."""
912         class Test(TestCase):
913             def test_foo(self):
914                 self.addDetail(
915                     'foo', content.Content('text/plain', lambda: 'foo'))
916         orig_test = Test('test_foo')
917         cloned_test = clone_test_with_new_id(orig_test, self.getUniqueString())
918         orig_test.run(unittest.TestResult())
919         self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
920         self.assertEqual(None, cloned_test.getDetails().get('foo'))
921
922
923 class TestDetailsProvided(TestWithDetails):
924
925     run_test_with = FullStackRunTest
926
927     def test_addDetail(self):
928         mycontent = self.get_content()
929         self.addDetail("foo", mycontent)
930         details = self.getDetails()
931         self.assertEqual({"foo": mycontent}, details)
932
933     def test_addError(self):
934         class Case(TestCase):
935             def test(this):
936                 this.addDetail("foo", self.get_content())
937                 1/0
938         self.assertDetailsProvided(Case("test"), "addError",
939             ["foo", "traceback"])
940
941     def test_addFailure(self):
942         class Case(TestCase):
943             def test(this):
944                 this.addDetail("foo", self.get_content())
945                 self.fail('yo')
946         self.assertDetailsProvided(Case("test"), "addFailure",
947             ["foo", "traceback"])
948
949     def test_addSkip(self):
950         class Case(TestCase):
951             def test(this):
952                 this.addDetail("foo", self.get_content())
953                 self.skip('yo')
954         self.assertDetailsProvided(Case("test"), "addSkip",
955             ["foo", "reason"])
956
957     def test_addSucccess(self):
958         class Case(TestCase):
959             def test(this):
960                 this.addDetail("foo", self.get_content())
961         self.assertDetailsProvided(Case("test"), "addSuccess",
962             ["foo"])
963
964     def test_addUnexpectedSuccess(self):
965         class Case(TestCase):
966             def test(this):
967                 this.addDetail("foo", self.get_content())
968                 raise testcase._UnexpectedSuccess()
969         self.assertDetailsProvided(Case("test"), "addUnexpectedSuccess",
970             ["foo"])
971
972     def test_addDetails_from_Mismatch(self):
973         content = self.get_content()
974         class Mismatch(object):
975             def describe(self):
976                 return "Mismatch"
977             def get_details(self):
978                 return {"foo": content}
979         class Matcher(object):
980             def match(self, thing):
981                 return Mismatch()
982             def __str__(self):
983                 return "a description"
984         class Case(TestCase):
985             def test(self):
986                 self.assertThat("foo", Matcher())
987         self.assertDetailsProvided(Case("test"), "addFailure",
988             ["foo", "traceback"])
989
990     def test_multiple_addDetails_from_Mismatch(self):
991         content = self.get_content()
992         class Mismatch(object):
993             def describe(self):
994                 return "Mismatch"
995             def get_details(self):
996                 return {"foo": content, "bar": content}
997         class Matcher(object):
998             def match(self, thing):
999                 return Mismatch()
1000             def __str__(self):
1001                 return "a description"
1002         class Case(TestCase):
1003             def test(self):
1004                 self.assertThat("foo", Matcher())
1005         self.assertDetailsProvided(Case("test"), "addFailure",
1006             ["bar", "foo", "traceback"])
1007
1008     def test_addDetails_with_same_name_as_key_from_get_details(self):
1009         content = self.get_content()
1010         class Mismatch(object):
1011             def describe(self):
1012                 return "Mismatch"
1013             def get_details(self):
1014                 return {"foo": content}
1015         class Matcher(object):
1016             def match(self, thing):
1017                 return Mismatch()
1018             def __str__(self):
1019                 return "a description"
1020         class Case(TestCase):
1021             def test(self):
1022                 self.addDetail("foo", content)
1023                 self.assertThat("foo", Matcher())
1024         self.assertDetailsProvided(Case("test"), "addFailure",
1025             ["foo", "foo-1", "traceback"])
1026
1027
1028 class TestSetupTearDown(TestCase):
1029
1030     run_test_with = FullStackRunTest
1031
1032     def test_setUpNotCalled(self):
1033         class DoesnotcallsetUp(TestCase):
1034             def setUp(self):
1035                 pass
1036             def test_method(self):
1037                 pass
1038         result = unittest.TestResult()
1039         DoesnotcallsetUp('test_method').run(result)
1040         self.assertEqual(1, len(result.errors))
1041
1042     def test_tearDownNotCalled(self):
1043         class DoesnotcalltearDown(TestCase):
1044             def test_method(self):
1045                 pass
1046             def tearDown(self):
1047                 pass
1048         result = unittest.TestResult()
1049         DoesnotcalltearDown('test_method').run(result)
1050         self.assertEqual(1, len(result.errors))
1051
1052
1053 class TestSkipping(TestCase):
1054     """Tests for skipping of tests functionality."""
1055
1056     run_test_with = FullStackRunTest
1057
1058     def test_skip_causes_skipException(self):
1059         self.assertThat(lambda:self.skip("Skip this test"),
1060             Raises(MatchesException(self.skipException)))
1061
1062     def test_can_use_skipTest(self):
1063         self.assertThat(lambda:self.skipTest("Skip this test"),
1064             Raises(MatchesException(self.skipException)))
1065
1066     def test_skip_without_reason_works(self):
1067         class Test(TestCase):
1068             def test(self):
1069                 raise self.skipException()
1070         case = Test("test")
1071         result = ExtendedTestResult()
1072         case.run(result)
1073         self.assertEqual('addSkip', result._events[1][0])
1074         self.assertEqual('no reason given.',
1075             ''.join(result._events[1][2]['reason'].iter_text()))
1076
1077     def test_skipException_in_setup_calls_result_addSkip(self):
1078         class TestThatRaisesInSetUp(TestCase):
1079             def setUp(self):
1080                 TestCase.setUp(self)
1081                 self.skip("skipping this test")
1082             def test_that_passes(self):
1083                 pass
1084         calls = []
1085         result = LoggingResult(calls)
1086         test = TestThatRaisesInSetUp("test_that_passes")
1087         test.run(result)
1088         case = result._events[0][1]
1089         self.assertEqual([('startTest', case),
1090             ('addSkip', case, "skipping this test"), ('stopTest', case)],
1091             calls)
1092
1093     def test_skipException_in_test_method_calls_result_addSkip(self):
1094         class SkippingTest(TestCase):
1095             def test_that_raises_skipException(self):
1096                 self.skip("skipping this test")
1097         result = Python27TestResult()
1098         test = SkippingTest("test_that_raises_skipException")
1099         test.run(result)
1100         case = result._events[0][1]
1101         self.assertEqual([('startTest', case),
1102             ('addSkip', case, "skipping this test"), ('stopTest', case)],
1103             result._events)
1104
1105     def test_skip__in_setup_with_old_result_object_calls_addSuccess(self):
1106         class SkippingTest(TestCase):
1107             def setUp(self):
1108                 TestCase.setUp(self)
1109                 raise self.skipException("skipping this test")
1110             def test_that_raises_skipException(self):
1111                 pass
1112         result = Python26TestResult()
1113         test = SkippingTest("test_that_raises_skipException")
1114         test.run(result)
1115         self.assertEqual('addSuccess', result._events[1][0])
1116
1117     def test_skip_with_old_result_object_calls_addError(self):
1118         class SkippingTest(TestCase):
1119             def test_that_raises_skipException(self):
1120                 raise self.skipException("skipping this test")
1121         result = Python26TestResult()
1122         test = SkippingTest("test_that_raises_skipException")
1123         test.run(result)
1124         self.assertEqual('addSuccess', result._events[1][0])
1125
1126     def test_skip_decorator(self):
1127         class SkippingTest(TestCase):
1128             @skip("skipping this test")
1129             def test_that_is_decorated_with_skip(self):
1130                 self.fail()
1131         result = Python26TestResult()
1132         test = SkippingTest("test_that_is_decorated_with_skip")
1133         test.run(result)
1134         self.assertEqual('addSuccess', result._events[1][0])
1135
1136     def test_skipIf_decorator(self):
1137         class SkippingTest(TestCase):
1138             @skipIf(True, "skipping this test")
1139             def test_that_is_decorated_with_skipIf(self):
1140                 self.fail()
1141         result = Python26TestResult()
1142         test = SkippingTest("test_that_is_decorated_with_skipIf")
1143         test.run(result)
1144         self.assertEqual('addSuccess', result._events[1][0])
1145
1146     def test_skipUnless_decorator(self):
1147         class SkippingTest(TestCase):
1148             @skipUnless(False, "skipping this test")
1149             def test_that_is_decorated_with_skipUnless(self):
1150                 self.fail()
1151         result = Python26TestResult()
1152         test = SkippingTest("test_that_is_decorated_with_skipUnless")
1153         test.run(result)
1154         self.assertEqual('addSuccess', result._events[1][0])
1155
1156
1157 class TestOnException(TestCase):
1158
1159     run_test_with = FullStackRunTest
1160
1161     def test_default_works(self):
1162         events = []
1163         class Case(TestCase):
1164             def method(self):
1165                 self.onException(an_exc_info)
1166                 events.append(True)
1167         case = Case("method")
1168         case.run()
1169         self.assertThat(events, Equals([True]))
1170
1171     def test_added_handler_works(self):
1172         events = []
1173         class Case(TestCase):
1174             def method(self):
1175                 self.addOnException(events.append)
1176                 self.onException(an_exc_info)
1177         case = Case("method")
1178         case.run()
1179         self.assertThat(events, Equals([an_exc_info]))
1180
1181     def test_handler_that_raises_is_not_caught(self):
1182         events = []
1183         class Case(TestCase):
1184             def method(self):
1185                 self.addOnException(events.index)
1186                 self.assertThat(lambda: self.onException(an_exc_info),
1187                     Raises(MatchesException(ValueError)))
1188         case = Case("method")
1189         case.run()
1190         self.assertThat(events, Equals([]))
1191
1192
1193 class TestPatchSupport(TestCase):
1194
1195     run_test_with = FullStackRunTest
1196
1197     class Case(TestCase):
1198         def test(self):
1199             pass
1200
1201     def test_patch(self):
1202         # TestCase.patch masks obj.attribute with the new value.
1203         self.foo = 'original'
1204         test = self.Case('test')
1205         test.patch(self, 'foo', 'patched')
1206         self.assertEqual('patched', self.foo)
1207
1208     def test_patch_restored_after_run(self):
1209         # TestCase.patch masks obj.attribute with the new value, but restores
1210         # the original value after the test is finished.
1211         self.foo = 'original'
1212         test = self.Case('test')
1213         test.patch(self, 'foo', 'patched')
1214         test.run()
1215         self.assertEqual('original', self.foo)
1216
1217     def test_successive_patches_apply(self):
1218         # TestCase.patch can be called multiple times per test. Each time you
1219         # call it, it overrides the original value.
1220         self.foo = 'original'
1221         test = self.Case('test')
1222         test.patch(self, 'foo', 'patched')
1223         test.patch(self, 'foo', 'second')
1224         self.assertEqual('second', self.foo)
1225
1226     def test_successive_patches_restored_after_run(self):
1227         # TestCase.patch restores the original value, no matter how many times
1228         # it was called.
1229         self.foo = 'original'
1230         test = self.Case('test')
1231         test.patch(self, 'foo', 'patched')
1232         test.patch(self, 'foo', 'second')
1233         test.run()
1234         self.assertEqual('original', self.foo)
1235
1236     def test_patch_nonexistent_attribute(self):
1237         # TestCase.patch can be used to patch a non-existent attribute.
1238         test = self.Case('test')
1239         test.patch(self, 'doesntexist', 'patched')
1240         self.assertEqual('patched', self.doesntexist)
1241
1242     def test_restore_nonexistent_attribute(self):
1243         # TestCase.patch can be used to patch a non-existent attribute, after
1244         # the test run, the attribute is then removed from the object.
1245         test = self.Case('test')
1246         test.patch(self, 'doesntexist', 'patched')
1247         test.run()
1248         marker = object()
1249         value = getattr(self, 'doesntexist', marker)
1250         self.assertIs(marker, value)
1251
1252
1253 class TestTestCaseSuper(TestCase):
1254
1255     run_test_with = FullStackRunTest
1256
1257     def test_setup_uses_super(self):
1258         class OtherBaseCase(unittest.TestCase):
1259             setup_called = False
1260             def setUp(self):
1261                 self.setup_called = True
1262                 super(OtherBaseCase, self).setUp()
1263         class OurCase(TestCase, OtherBaseCase):
1264             def runTest(self):
1265                 pass
1266         test = OurCase()
1267         test.setUp()
1268         test.tearDown()
1269         self.assertTrue(test.setup_called)
1270
1271     def test_teardown_uses_super(self):
1272         class OtherBaseCase(unittest.TestCase):
1273             teardown_called = False
1274             def tearDown(self):
1275                 self.teardown_called = True
1276                 super(OtherBaseCase, self).tearDown()
1277         class OurCase(TestCase, OtherBaseCase):
1278             def runTest(self):
1279                 pass
1280         test = OurCase()
1281         test.setUp()
1282         test.tearDown()
1283         self.assertTrue(test.teardown_called)
1284
1285
1286 def test_suite():
1287     from unittest import TestLoader
1288     return TestLoader().loadTestsFromName(__name__)