~ubuntu-branches/ubuntu/trusty/percona-xtradb-cluster-5.5/trusty-proposed

« back to all changes in this revision

Viewing changes to python-for-subunit2junitxml/testtools/tests/test_testtools.py

  • Committer: Package Import Robot
  • Author(s): Rafael David Tinoco
  • Date: 2016-07-16 20:24:11 UTC
  • mfrom: (5.1.1 trusty-security)
  • Revision ID: package-import@ubuntu.com-20160716202411-wqt0uhix3mzbyhr6
Tags: 5.5.37-25.10+dfsg-0ubuntu0.14.04.2
d/p/fix_tc_log_initlization_on_ppc64.patch: Fix log-tc-size for bigger
page sizes to fix crash on ppc64el (LP: #1570678)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2008-2010 testtools developers. See LICENSE for details.
 
2
 
 
3
"""Tests for extensions to the base test library."""
 
4
 
 
5
from pprint import pformat
 
6
import os
 
7
import sys
 
8
import tempfile
 
9
import unittest
 
10
 
 
11
from testtools import (
 
12
    ErrorHolder,
 
13
    MultipleExceptions,
 
14
    PlaceHolder,
 
15
    TestCase,
 
16
    clone_test_with_new_id,
 
17
    content,
 
18
    skip,
 
19
    skipIf,
 
20
    skipUnless,
 
21
    testcase,
 
22
    )
 
23
from testtools.matchers import (
 
24
    Equals,
 
25
    MatchesException,
 
26
    Raises,
 
27
    )
 
28
from testtools.tests.helpers import (
 
29
    an_exc_info,
 
30
    LoggingResult,
 
31
    Python26TestResult,
 
32
    Python27TestResult,
 
33
    ExtendedTestResult,
 
34
    )
 
35
try:
 
36
    exec('from __future__ import with_statement')
 
37
except SyntaxError:
 
38
    pass
 
39
else:
 
40
    from test_with_with import *
 
41
 
 
42
 
 
43
class TestPlaceHolder(TestCase):
 
44
 
 
45
    def makePlaceHolder(self, test_id="foo", short_description=None):
 
46
        return PlaceHolder(test_id, short_description)
 
47
 
 
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())
 
52
 
 
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())
 
57
 
 
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())
 
63
 
 
64
    def test_repr_just_id(self):
 
65
        # repr(placeholder) shows you how the object was constructed.
 
66
        test = PlaceHolder("test id")
 
67
        self.assertEqual(
 
68
            "<testtools.testcase.PlaceHolder(%s)>" % repr(test.id()),
 
69
            repr(test))
 
70
 
 
71
    def test_repr_with_description(self):
 
72
        # repr(placeholder) shows you how the object was constructed.
 
73
        test = PlaceHolder("test id", "description")
 
74
        self.assertEqual(
 
75
            "<testtools.testcase.PlaceHolder(%r, %r)>" % (
 
76
                test.id(), test.shortDescription()),
 
77
            repr(test))
 
78
 
 
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())
 
83
 
 
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))
 
88
 
 
89
    def test_runs_as_success(self):
 
90
        # When run, a PlaceHolder test records a success.
 
91
        test = self.makePlaceHolder()
 
92
        log = []
 
93
        test.run(LoggingResult(log))
 
94
        self.assertEqual(
 
95
            [('startTest', test), ('addSuccess', test), ('stopTest', test)],
 
96
            log)
 
97
 
 
98
    def test_call_is_run(self):
 
99
        # A PlaceHolder can be called, in which case it behaves like run.
 
100
        test = self.makePlaceHolder()
 
101
        run_log = []
 
102
        test.run(LoggingResult(run_log))
 
103
        call_log = []
 
104
        test(LoggingResult(call_log))
 
105
        self.assertEqual(run_log, call_log)
 
106
 
 
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()
 
111
 
 
112
    def test_debug(self):
 
113
        # A PlaceHolder can be debugged.
 
114
        self.makePlaceHolder().debug()
 
115
 
 
116
 
 
117
class TestErrorHolder(TestCase):
 
118
 
 
119
    def makeException(self):
 
120
        try:
 
121
            raise RuntimeError("danger danger")
 
122
        except:
 
123
            return sys.exc_info()
 
124
 
 
125
    def makePlaceHolder(self, test_id="foo", error=None,
 
126
                        short_description=None):
 
127
        if error is None:
 
128
            error = self.makeException()
 
129
        return ErrorHolder(test_id, error, short_description)
 
130
 
 
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())
 
135
 
 
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())
 
140
 
 
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())
 
146
 
 
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)
 
151
        self.assertEqual(
 
152
            "<testtools.testcase.ErrorHolder(%r, %r)>" % (test.id(), error),
 
153
            repr(test))
 
154
 
 
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")
 
159
        self.assertEqual(
 
160
            "<testtools.testcase.ErrorHolder(%r, %r, %r)>" % (
 
161
                test.id(), error, test.shortDescription()),
 
162
            repr(test))
 
163
 
 
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())
 
168
 
 
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))
 
173
 
 
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)
 
178
        log = []
 
179
        test.run(LoggingResult(log))
 
180
        self.assertEqual(
 
181
            [('startTest', test),
 
182
             ('addError', test, error),
 
183
             ('stopTest', test)], log)
 
184
 
 
185
    def test_call_is_run(self):
 
186
        # A PlaceHolder can be called, in which case it behaves like run.
 
187
        test = self.makePlaceHolder()
 
188
        run_log = []
 
189
        test.run(LoggingResult(run_log))
 
190
        call_log = []
 
191
        test(LoggingResult(call_log))
 
192
        self.assertEqual(run_log, call_log)
 
193
 
 
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()
 
198
 
 
199
    def test_debug(self):
 
200
        # A PlaceHolder can be debugged.
 
201
        self.makePlaceHolder().debug()
 
202
 
 
203
 
 
204
class TestEquality(TestCase):
 
205
    """Test ``TestCase``'s equality implementation."""
 
206
 
 
207
    def test_identicalIsEqual(self):
 
208
        # TestCase's are equal if they are identical.
 
209
        self.assertEqual(self, self)
 
210
 
 
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'))
 
215
 
 
216
 
 
217
class TestAssertions(TestCase):
 
218
    """Test assertions in TestCase."""
 
219
 
 
220
    def raiseError(self, exceptionFactory, *args, **kwargs):
 
221
        raise exceptionFactory(*args, **kwargs)
 
222
 
 
223
    def test_formatTypes_single(self):
 
224
        # Given a single class, _formatTypes returns the name.
 
225
        class Foo(object):
 
226
            pass
 
227
        self.assertEqual('Foo', self._formatTypes(Foo))
 
228
 
 
229
    def test_formatTypes_multiple(self):
 
230
        # Given multiple types, _formatTypes returns the names joined by
 
231
        # commas.
 
232
        class Foo(object):
 
233
            pass
 
234
        class Bar(object):
 
235
            pass
 
236
        self.assertEqual('Foo, Bar', self._formatTypes([Foo, Bar]))
 
237
 
 
238
    def test_assertRaises(self):
 
239
        # assertRaises asserts that a callable raises a particular exception.
 
240
        self.assertRaises(RuntimeError, self.raiseError, RuntimeError)
 
241
 
 
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.
 
245
        ret = ('orange', 42)
 
246
        try:
 
247
            self.assertRaises(RuntimeError, lambda: ret)
 
248
        except self.failureException:
 
249
            # We expected assertRaises to raise this exception.
 
250
            e = sys.exc_info()[1]
 
251
            self.assertEqual(
 
252
                '%s not raised, %r returned instead.'
 
253
                % (self._formatTypes(RuntimeError), ret), str(e))
 
254
        else:
 
255
            self.fail('Expected assertRaises to fail, but it did not.')
 
256
 
 
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)))
 
262
 
 
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.
 
266
 
 
267
        # This contraption stores the raised exception, so we can compare it
 
268
        # to the return value of assertRaises.
 
269
        raisedExceptions = []
 
270
        def raiseError():
 
271
            try:
 
272
                raise RuntimeError('Deliberate error')
 
273
            except RuntimeError:
 
274
                raisedExceptions.append(sys.exc_info()[1])
 
275
                raise
 
276
 
 
277
        exception = self.assertRaises(RuntimeError, raiseError)
 
278
        self.assertEqual(1, len(raisedExceptions))
 
279
        self.assertTrue(
 
280
            exception is raisedExceptions[0],
 
281
            "%r is not %r" % (exception, raisedExceptions[0]))
 
282
 
 
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)
 
287
        self.assertRaises(
 
288
            expectedExceptions, self.raiseError, expectedExceptions[0])
 
289
        self.assertRaises(
 
290
            expectedExceptions, self.raiseError, expectedExceptions[1])
 
291
 
 
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)
 
300
        self.assertEqual(
 
301
            '%s not raised, None returned instead.'
 
302
            % self._formatTypes(expectedExceptions), str(failure))
 
303
 
 
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))
 
309
 
 
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())
 
315
 
 
316
    def test_assertIn_failure(self):
 
317
        # assertIn(needle, haystack) fails the test when 'needle' is not in
 
318
        # 'haystack'.
 
319
        self.assertFails('3 not in [0, 1, 2]', self.assertIn, 3, [0, 1, 2])
 
320
        self.assertFails(
 
321
            '%r not in %r' % ('qux', 'foo bar baz'),
 
322
            self.assertIn, 'qux', 'foo bar baz')
 
323
 
 
324
    def test_assertNotIn_success(self):
 
325
        # assertNotIn(needle, haystack) asserts that 'needle' is not in
 
326
        # 'haystack'.
 
327
        self.assertNotIn(3, [0, 1, 2])
 
328
        self.assertNotIn('qux', 'foo bar baz')
 
329
 
 
330
    def test_assertNotIn_failure(self):
 
331
        # assertNotIn(needle, haystack) fails the test when 'needle' is in
 
332
        # 'haystack'.
 
333
        self.assertFails('3 in [1, 2, 3]', self.assertNotIn, 3, [1, 2, 3])
 
334
        self.assertFails(
 
335
            '%r in %r' % ('foo', 'foo bar baz'),
 
336
            self.assertNotIn, 'foo', 'foo bar baz')
 
337
 
 
338
    def test_assertIsInstance(self):
 
339
        # assertIsInstance asserts that an object is an instance of a class.
 
340
 
 
341
        class Foo(object):
 
342
            """Simple class for testing assertIsInstance."""
 
343
 
 
344
        foo = Foo()
 
345
        self.assertIsInstance(foo, Foo)
 
346
 
 
347
    def test_assertIsInstance_multiple_classes(self):
 
348
        # assertIsInstance asserts that an object is an instance of one of a
 
349
        # group of classes.
 
350
 
 
351
        class Foo(object):
 
352
            """Simple class for testing assertIsInstance."""
 
353
 
 
354
        class Bar(object):
 
355
            """Another simple class for testing assertIsInstance."""
 
356
 
 
357
        foo = Foo()
 
358
        self.assertIsInstance(foo, (Foo, Bar))
 
359
        self.assertIsInstance(Bar(), (Foo, Bar))
 
360
 
 
361
    def test_assertIsInstance_failure(self):
 
362
        # assertIsInstance(obj, klass) fails the test when obj is not an
 
363
        # instance of klass.
 
364
 
 
365
        class Foo(object):
 
366
            """Simple class for testing assertIsInstance."""
 
367
 
 
368
        self.assertFails(
 
369
            '42 is not an instance of %s' % self._formatTypes(Foo),
 
370
            self.assertIsInstance, 42, Foo)
 
371
 
 
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.
 
375
 
 
376
        class Foo(object):
 
377
            """Simple class for testing assertIsInstance."""
 
378
 
 
379
        class Bar(object):
 
380
            """Another simple class for testing assertIsInstance."""
 
381
 
 
382
        self.assertFails(
 
383
            '42 is not an instance of %s' % self._formatTypes([Foo, Bar]),
 
384
            self.assertIsInstance, 42, (Foo, Bar))
 
385
 
 
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")
 
389
 
 
390
    def test_assertIs(self):
 
391
        # assertIs asserts that an object is identical to another object.
 
392
        self.assertIs(None, None)
 
393
        some_list = [42]
 
394
        self.assertIs(some_list, some_list)
 
395
        some_object = object()
 
396
        self.assertIs(some_object, some_object)
 
397
 
 
398
    def test_assertIs_fails(self):
 
399
        # assertIs raises assertion errors if one object is not identical to
 
400
        # another.
 
401
        self.assertFails('None is not 42', self.assertIs, None, 42)
 
402
        self.assertFails('[42] is not [42]', self.assertIs, [42], [42])
 
403
 
 
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.
 
407
        self.assertFails(
 
408
            'None is not 42: foo bar', self.assertIs, None, 42, 'foo bar')
 
409
 
 
410
    def test_assertIsNot(self):
 
411
        # assertIsNot asserts that an object is not identical to another
 
412
        # object.
 
413
        self.assertIsNot(None, 42)
 
414
        self.assertIsNot([42], [42])
 
415
        self.assertIsNot(object(), object())
 
416
 
 
417
    def test_assertIsNot_fails(self):
 
418
        # assertIsNot raises assertion errors if one object is identical to
 
419
        # another.
 
420
        self.assertFails('None is None', self.assertIsNot, None, None)
 
421
        some_list = [42]
 
422
        self.assertFails(
 
423
            '[42] is [42]', self.assertIsNot, some_list, some_list)
 
424
 
 
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.
 
428
        self.assertFails(
 
429
            'None is None: foo bar', self.assertIsNot, None, None, "foo bar")
 
430
 
 
431
    def test_assertThat_matches_clean(self):
 
432
        class Matcher(object):
 
433
            def match(self, foo):
 
434
                return None
 
435
        self.assertThat("foo", Matcher())
 
436
 
 
437
    def test_assertThat_mismatch_raises_description(self):
 
438
        calls = []
 
439
        class Mismatch(object):
 
440
            def __init__(self, thing):
 
441
                self.thing = thing
 
442
            def describe(self):
 
443
                calls.append(('describe_diff', self.thing))
 
444
                return "object is not a thing"
 
445
            def get_details(self):
 
446
                return {}
 
447
        class Matcher(object):
 
448
            def match(self, thing):
 
449
                calls.append(('match', thing))
 
450
                return Mismatch(thing)
 
451
            def __str__(self):
 
452
                calls.append(('__str__',))
 
453
                return "a description"
 
454
        class Test(TestCase):
 
455
            def test(self):
 
456
                self.assertThat("foo", Matcher())
 
457
        result = Test("test").run()
 
458
        self.assertEqual([
 
459
            ('match', "foo"),
 
460
            ('describe_diff', "foo"),
 
461
            ('__str__',),
 
462
            ], calls)
 
463
        self.assertFalse(result.wasSuccessful())
 
464
 
 
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(
 
473
            [message,
 
474
             'not equal:',
 
475
             'a = %s' % pformat(a),
 
476
             'b = %s' % pformat(b),
 
477
             ''])
 
478
        expected_error = '\n'.join([
 
479
            'Match failed. Matchee: "%r"' % b,
 
480
            'Matcher: Annotate(%r, Equals(%r))' % (message, a),
 
481
            'Difference: !=:',
 
482
            'reference = %s' % pformat(a),
 
483
            'actual = %s' % pformat(b),
 
484
            ': ' + message,
 
485
            ''
 
486
            ])
 
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)
 
490
 
 
491
    def test_assertEqual_formatting_no_message(self):
 
492
        a = "cat"
 
493
        b = "dog"
 
494
        expected_error = '\n'.join([
 
495
            'Match failed. Matchee: "dog"',
 
496
            'Matcher: Equals(\'cat\')',
 
497
            'Difference: \'cat\' != \'dog\'',
 
498
            ''
 
499
            ])
 
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)
 
503
 
 
504
 
 
505
class TestAddCleanup(TestCase):
 
506
    """Tests for TestCase.addCleanup."""
 
507
 
 
508
    class LoggingTest(TestCase):
 
509
        """A test that logs calls to setUp, runTest and tearDown."""
 
510
 
 
511
        def setUp(self):
 
512
            TestCase.setUp(self)
 
513
            self._calls = ['setUp']
 
514
 
 
515
        def brokenSetUp(self):
 
516
            # A tearDown that deliberately fails.
 
517
            self._calls = ['brokenSetUp']
 
518
            raise RuntimeError('Deliberate Failure')
 
519
 
 
520
        def runTest(self):
 
521
            self._calls.append('runTest')
 
522
 
 
523
        def brokenTest(self):
 
524
            raise RuntimeError('Deliberate broken test')
 
525
 
 
526
        def tearDown(self):
 
527
            self._calls.append('tearDown')
 
528
            TestCase.tearDown(self)
 
529
 
 
530
    def setUp(self):
 
531
        TestCase.setUp(self)
 
532
        self._result_calls = []
 
533
        self.test = TestAddCleanup.LoggingTest('runTest')
 
534
        self.logging_result = LoggingResult(self._result_calls)
 
535
 
 
536
    def assertErrorLogEqual(self, messages):
 
537
        self.assertEqual(messages, [call[0] for call in self._result_calls])
 
538
 
 
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)
 
543
 
 
544
    def logAppender(self, message):
 
545
        """A cleanup that appends 'message' to the tests log.
 
546
 
 
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.
 
551
        """
 
552
        self.test._calls.append(message)
 
553
 
 
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
 
557
        # fixture.
 
558
        self.test.run(self.logging_result)
 
559
        self.assertTestLogEqual(['setUp', 'runTest', 'tearDown'])
 
560
 
 
561
    def test_cleanup_run_before_tearDown(self):
 
562
        # Cleanup functions added with 'addCleanup' are called before tearDown
 
563
        # runs.
 
564
        self.test.addCleanup(self.logAppender, 'cleanup')
 
565
        self.test.run(self.logging_result)
 
566
        self.assertTestLogEqual(['setUp', 'runTest', 'tearDown', 'cleanup'])
 
567
 
 
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'])
 
576
 
 
577
    def test_addCleanup_called_in_reverse_order(self):
 
578
        # Cleanup functions added with 'addCleanup' are called in reverse
 
579
        # order.
 
580
        #
 
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)
 
586
        #
 
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'])
 
594
 
 
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'])
 
600
 
 
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'])
 
609
 
 
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'])
 
616
 
 
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)))
 
624
 
 
625
    def test_all_errors_from_MultipleExceptions_reported(self):
 
626
        # When a MultipleExceptions exception is caught, all the errors are
 
627
        # reported.
 
628
        def raiseMany():
 
629
            try:
 
630
                1/0
 
631
            except Exception:
 
632
                exc_info1 = sys.exc_info()
 
633
            try:
 
634
                1/0
 
635
            except Exception:
 
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()))
 
645
 
 
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()))
 
656
 
 
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()))
 
669
 
 
670
 
 
671
class TestWithDetails(TestCase):
 
672
 
 
673
    def assertDetailsProvided(self, case, expected_outcome, expected_keys):
 
674
        """Assert that when case is run, details are provided to the result.
 
675
 
 
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.
 
679
        """
 
680
        result = ExtendedTestResult()
 
681
        case.run(result)
 
682
        case = result._events[0][1]
 
683
        expected = [
 
684
            ('startTest', case),
 
685
            (expected_outcome, case),
 
686
            ('stopTest', case),
 
687
            ]
 
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])
 
696
 
 
697
    def get_content(self):
 
698
        return content.Content(
 
699
            content.ContentType("text", "foo"), lambda: ['foo'])
 
700
 
 
701
 
 
702
class TestExpectedFailure(TestWithDetails):
 
703
    """Tests for expected failures and unexpected successess."""
 
704
 
 
705
    def make_unexpected_case(self):
 
706
        class Case(TestCase):
 
707
            def test(self):
 
708
                raise testcase._UnexpectedSuccess
 
709
        case = Case('test')
 
710
        return case
 
711
 
 
712
    def test_raising__UnexpectedSuccess_py27(self):
 
713
        case = self.make_unexpected_case()
 
714
        result = Python27TestResult()
 
715
        case.run(result)
 
716
        case = result._events[0][1]
 
717
        self.assertEqual([
 
718
            ('startTest', case),
 
719
            ('addUnexpectedSuccess', case),
 
720
            ('stopTest', case),
 
721
            ], result._events)
 
722
 
 
723
    def test_raising__UnexpectedSuccess_extended(self):
 
724
        case = self.make_unexpected_case()
 
725
        result = ExtendedTestResult()
 
726
        case.run(result)
 
727
        case = result._events[0][1]
 
728
        self.assertEqual([
 
729
            ('startTest', case),
 
730
            ('addUnexpectedSuccess', case, {}),
 
731
            ('stopTest', case),
 
732
            ], result._events)
 
733
 
 
734
    def make_xfail_case_xfails(self):
 
735
        content = self.get_content()
 
736
        class Case(TestCase):
 
737
            def test(self):
 
738
                self.addDetail("foo", content)
 
739
                self.expectFailure("we are sad", self.assertEqual,
 
740
                    1, 0)
 
741
        case = Case('test')
 
742
        return case
 
743
 
 
744
    def make_xfail_case_succeeds(self):
 
745
        content = self.get_content()
 
746
        class Case(TestCase):
 
747
            def test(self):
 
748
                self.addDetail("foo", content)
 
749
                self.expectFailure("we are sad", self.assertEqual,
 
750
                    1, 1)
 
751
        case = Case('test')
 
752
        return case
 
753
 
 
754
    def test_expectFailure_KnownFailure_extended(self):
 
755
        case = self.make_xfail_case_xfails()
 
756
        self.assertDetailsProvided(case, "addExpectedFailure",
 
757
            ["foo", "traceback", "reason"])
 
758
 
 
759
    def test_expectFailure_KnownFailure_unexpected_success(self):
 
760
        case = self.make_xfail_case_succeeds()
 
761
        self.assertDetailsProvided(case, "addUnexpectedSuccess",
 
762
            ["foo", "reason"])
 
763
 
 
764
 
 
765
class TestUniqueFactories(TestCase):
 
766
    """Tests for getUniqueString and getUniqueInteger."""
 
767
 
 
768
    def test_getUniqueInteger(self):
 
769
        # getUniqueInteger returns an integer that increments each time you
 
770
        # call it.
 
771
        one = self.getUniqueInteger()
 
772
        self.assertEqual(1, one)
 
773
        two = self.getUniqueInteger()
 
774
        self.assertEqual(2, two)
 
775
 
 
776
    def test_getUniqueString(self):
 
777
        # getUniqueString returns the current test id followed by a unique
 
778
        # integer.
 
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)
 
783
 
 
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'))
 
791
 
 
792
 
 
793
class TestCloneTestWithNewId(TestCase):
 
794
    """Tests for clone_test_with_new_id."""
 
795
 
 
796
    def test_clone_test_with_new_id(self):
 
797
        class FooTestCase(TestCase):
 
798
            def test_foo(self):
 
799
                pass
 
800
        test = FooTestCase('test_foo')
 
801
        oldName = test.id()
 
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.")
 
807
 
 
808
    def test_cloned_testcase_does_not_share_details(self):
 
809
        """A cloned TestCase does not share the details dict."""
 
810
        class Test(TestCase):
 
811
            def test_foo(self):
 
812
                self.addDetail(
 
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'))
 
819
 
 
820
 
 
821
class TestDetailsProvided(TestWithDetails):
 
822
 
 
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)
 
828
 
 
829
    def test_addError(self):
 
830
        class Case(TestCase):
 
831
            def test(this):
 
832
                this.addDetail("foo", self.get_content())
 
833
                1/0
 
834
        self.assertDetailsProvided(Case("test"), "addError",
 
835
            ["foo", "traceback"])
 
836
 
 
837
    def test_addFailure(self):
 
838
        class Case(TestCase):
 
839
            def test(this):
 
840
                this.addDetail("foo", self.get_content())
 
841
                self.fail('yo')
 
842
        self.assertDetailsProvided(Case("test"), "addFailure",
 
843
            ["foo", "traceback"])
 
844
 
 
845
    def test_addSkip(self):
 
846
        class Case(TestCase):
 
847
            def test(this):
 
848
                this.addDetail("foo", self.get_content())
 
849
                self.skip('yo')
 
850
        self.assertDetailsProvided(Case("test"), "addSkip",
 
851
            ["foo", "reason"])
 
852
 
 
853
    def test_addSucccess(self):
 
854
        class Case(TestCase):
 
855
            def test(this):
 
856
                this.addDetail("foo", self.get_content())
 
857
        self.assertDetailsProvided(Case("test"), "addSuccess",
 
858
            ["foo"])
 
859
 
 
860
    def test_addUnexpectedSuccess(self):
 
861
        class Case(TestCase):
 
862
            def test(this):
 
863
                this.addDetail("foo", self.get_content())
 
864
                raise testcase._UnexpectedSuccess()
 
865
        self.assertDetailsProvided(Case("test"), "addUnexpectedSuccess",
 
866
            ["foo"])
 
867
 
 
868
    def test_addDetails_from_Mismatch(self):
 
869
        content = self.get_content()
 
870
        class Mismatch(object):
 
871
            def describe(self):
 
872
                return "Mismatch"
 
873
            def get_details(self):
 
874
                return {"foo": content}
 
875
        class Matcher(object):
 
876
            def match(self, thing):
 
877
                return Mismatch()
 
878
            def __str__(self):
 
879
                return "a description"
 
880
        class Case(TestCase):
 
881
            def test(self):
 
882
                self.assertThat("foo", Matcher())
 
883
        self.assertDetailsProvided(Case("test"), "addFailure",
 
884
            ["foo", "traceback"])
 
885
 
 
886
    def test_multiple_addDetails_from_Mismatch(self):
 
887
        content = self.get_content()
 
888
        class Mismatch(object):
 
889
            def describe(self):
 
890
                return "Mismatch"
 
891
            def get_details(self):
 
892
                return {"foo": content, "bar": content}
 
893
        class Matcher(object):
 
894
            def match(self, thing):
 
895
                return Mismatch()
 
896
            def __str__(self):
 
897
                return "a description"
 
898
        class Case(TestCase):
 
899
            def test(self):
 
900
                self.assertThat("foo", Matcher())
 
901
        self.assertDetailsProvided(Case("test"), "addFailure",
 
902
            ["bar", "foo", "traceback"])
 
903
 
 
904
    def test_addDetails_with_same_name_as_key_from_get_details(self):
 
905
        content = self.get_content()
 
906
        class Mismatch(object):
 
907
            def describe(self):
 
908
                return "Mismatch"
 
909
            def get_details(self):
 
910
                return {"foo": content}
 
911
        class Matcher(object):
 
912
            def match(self, thing):
 
913
                return Mismatch()
 
914
            def __str__(self):
 
915
                return "a description"
 
916
        class Case(TestCase):
 
917
            def test(self):
 
918
                self.addDetail("foo", content)
 
919
                self.assertThat("foo", Matcher())
 
920
        self.assertDetailsProvided(Case("test"), "addFailure",
 
921
            ["foo", "foo-1", "traceback"])
 
922
 
 
923
 
 
924
class TestSetupTearDown(TestCase):
 
925
 
 
926
    def test_setUpNotCalled(self):
 
927
        class DoesnotcallsetUp(TestCase):
 
928
            def setUp(self):
 
929
                pass
 
930
            def test_method(self):
 
931
                pass
 
932
        result = unittest.TestResult()
 
933
        DoesnotcallsetUp('test_method').run(result)
 
934
        self.assertEqual(1, len(result.errors))
 
935
 
 
936
    def test_tearDownNotCalled(self):
 
937
        class DoesnotcalltearDown(TestCase):
 
938
            def test_method(self):
 
939
                pass
 
940
            def tearDown(self):
 
941
                pass
 
942
        result = unittest.TestResult()
 
943
        DoesnotcalltearDown('test_method').run(result)
 
944
        self.assertEqual(1, len(result.errors))
 
945
 
 
946
 
 
947
class TestSkipping(TestCase):
 
948
    """Tests for skipping of tests functionality."""
 
949
 
 
950
    def test_skip_causes_skipException(self):
 
951
        self.assertThat(lambda:self.skip("Skip this test"),
 
952
            Raises(MatchesException(self.skipException)))
 
953
 
 
954
    def test_can_use_skipTest(self):
 
955
        self.assertThat(lambda:self.skipTest("Skip this test"),
 
956
            Raises(MatchesException(self.skipException)))
 
957
 
 
958
    def test_skip_without_reason_works(self):
 
959
        class Test(TestCase):
 
960
            def test(self):
 
961
                raise self.skipException()
 
962
        case = Test("test")
 
963
        result = ExtendedTestResult()
 
964
        case.run(result)
 
965
        self.assertEqual('addSkip', result._events[1][0])
 
966
        self.assertEqual('no reason given.',
 
967
            ''.join(result._events[1][2]['reason'].iter_text()))
 
968
 
 
969
    def test_skipException_in_setup_calls_result_addSkip(self):
 
970
        class TestThatRaisesInSetUp(TestCase):
 
971
            def setUp(self):
 
972
                TestCase.setUp(self)
 
973
                self.skip("skipping this test")
 
974
            def test_that_passes(self):
 
975
                pass
 
976
        calls = []
 
977
        result = LoggingResult(calls)
 
978
        test = TestThatRaisesInSetUp("test_that_passes")
 
979
        test.run(result)
 
980
        case = result._events[0][1]
 
981
        self.assertEqual([('startTest', case),
 
982
            ('addSkip', case, "skipping this test"), ('stopTest', case)],
 
983
            calls)
 
984
 
 
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")
 
991
        test.run(result)
 
992
        case = result._events[0][1]
 
993
        self.assertEqual([('startTest', case),
 
994
            ('addSkip', case, "skipping this test"), ('stopTest', case)],
 
995
            result._events)
 
996
 
 
997
    def test_skip__in_setup_with_old_result_object_calls_addSuccess(self):
 
998
        class SkippingTest(TestCase):
 
999
            def setUp(self):
 
1000
                TestCase.setUp(self)
 
1001
                raise self.skipException("skipping this test")
 
1002
            def test_that_raises_skipException(self):
 
1003
                pass
 
1004
        result = Python26TestResult()
 
1005
        test = SkippingTest("test_that_raises_skipException")
 
1006
        test.run(result)
 
1007
        self.assertEqual('addSuccess', result._events[1][0])
 
1008
 
 
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")
 
1015
        test.run(result)
 
1016
        self.assertEqual('addSuccess', result._events[1][0])
 
1017
 
 
1018
    def test_skip_decorator(self):
 
1019
        class SkippingTest(TestCase):
 
1020
            @skip("skipping this test")
 
1021
            def test_that_is_decorated_with_skip(self):
 
1022
                self.fail()
 
1023
        result = Python26TestResult()
 
1024
        test = SkippingTest("test_that_is_decorated_with_skip")
 
1025
        test.run(result)
 
1026
        self.assertEqual('addSuccess', result._events[1][0])
 
1027
 
 
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):
 
1032
                self.fail()
 
1033
        result = Python26TestResult()
 
1034
        test = SkippingTest("test_that_is_decorated_with_skipIf")
 
1035
        test.run(result)
 
1036
        self.assertEqual('addSuccess', result._events[1][0])
 
1037
 
 
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):
 
1042
                self.fail()
 
1043
        result = Python26TestResult()
 
1044
        test = SkippingTest("test_that_is_decorated_with_skipUnless")
 
1045
        test.run(result)
 
1046
        self.assertEqual('addSuccess', result._events[1][0])
 
1047
 
 
1048
 
 
1049
class TestOnException(TestCase):
 
1050
 
 
1051
    def test_default_works(self):
 
1052
        events = []
 
1053
        class Case(TestCase):
 
1054
            def method(self):
 
1055
                self.onException(an_exc_info)
 
1056
                events.append(True)
 
1057
        case = Case("method")
 
1058
        case.run()
 
1059
        self.assertThat(events, Equals([True]))
 
1060
 
 
1061
    def test_added_handler_works(self):
 
1062
        events = []
 
1063
        class Case(TestCase):
 
1064
            def method(self):
 
1065
                self.addOnException(events.append)
 
1066
                self.onException(an_exc_info)
 
1067
        case = Case("method")
 
1068
        case.run()
 
1069
        self.assertThat(events, Equals([an_exc_info]))
 
1070
 
 
1071
    def test_handler_that_raises_is_not_caught(self):
 
1072
        events = []
 
1073
        class Case(TestCase):
 
1074
            def method(self):
 
1075
                self.addOnException(events.index)
 
1076
                self.assertThat(lambda: self.onException(an_exc_info),
 
1077
                    Raises(MatchesException(ValueError)))
 
1078
        case = Case("method")
 
1079
        case.run()
 
1080
        self.assertThat(events, Equals([]))
 
1081
 
 
1082
 
 
1083
class TestPatchSupport(TestCase):
 
1084
 
 
1085
    class Case(TestCase):
 
1086
        def test(self):
 
1087
            pass
 
1088
 
 
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)
 
1095
 
 
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')
 
1102
        test.run()
 
1103
        self.assertEqual('original', self.foo)
 
1104
 
 
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)
 
1113
 
 
1114
    def test_successive_patches_restored_after_run(self):
 
1115
        # TestCase.patch restores the original value, no matter how many times
 
1116
        # it was called.
 
1117
        self.foo = 'original'
 
1118
        test = self.Case('test')
 
1119
        test.patch(self, 'foo', 'patched')
 
1120
        test.patch(self, 'foo', 'second')
 
1121
        test.run()
 
1122
        self.assertEqual('original', self.foo)
 
1123
 
 
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)
 
1129
 
 
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')
 
1135
        test.run()
 
1136
        marker = object()
 
1137
        value = getattr(self, 'doesntexist', marker)
 
1138
        self.assertIs(marker, value)
 
1139
 
 
1140
 
 
1141
def test_suite():
 
1142
    from unittest import TestLoader
 
1143
    return TestLoader().loadTestsFromName(__name__)