840
849
self.assertContainsRe(output,
841
850
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
843
def test_uses_time_from_testtools(self):
844
"""Test case timings in verbose results should use testtools times"""
846
class TimeAddedVerboseTestResult(tests.VerboseTestResult):
847
def startTest(self, test):
848
self.time(datetime.datetime.utcfromtimestamp(1.145))
849
super(TimeAddedVerboseTestResult, self).startTest(test)
850
def addSuccess(self, test):
851
self.time(datetime.datetime.utcfromtimestamp(51.147))
852
super(TimeAddedVerboseTestResult, self).addSuccess(test)
853
def report_tests_starting(self): pass
855
self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
856
self.assertEndsWith(sio.getvalue(), "OK 50002ms\n")
858
852
def test_known_failure(self):
859
853
"""A KnownFailure being raised should trigger several result actions."""
860
854
class InstrumentedTestResult(tests.ExtendedTestResult):
1713
1690
self.assertEqual('original', obj.test_attr)
1716
class _MissingFeature(tests.Feature):
1719
missing_feature = _MissingFeature()
1722
def _get_test(name):
1723
"""Get an instance of a specific example test.
1725
We protect this in a function so that they don't auto-run in the test
1729
class ExampleTests(tests.TestCase):
1731
def test_fail(self):
1732
mutter('this was a failing test')
1733
self.fail('this test will fail')
1735
def test_error(self):
1736
mutter('this test errored')
1737
raise RuntimeError('gotcha')
1739
def test_missing_feature(self):
1740
mutter('missing the feature')
1741
self.requireFeature(missing_feature)
1743
def test_skip(self):
1744
mutter('this test will be skipped')
1745
raise tests.TestSkipped('reason')
1747
def test_success(self):
1748
mutter('this test succeeds')
1750
def test_xfail(self):
1751
mutter('test with expected failure')
1752
self.knownFailure('this_fails')
1754
def test_unexpected_success(self):
1755
mutter('test with unexpected success')
1756
self.expectFailure('should_fail', lambda: None)
1758
return ExampleTests(name)
1761
class TestTestCaseLogDetails(tests.TestCase):
1763
def _run_test(self, test_name):
1764
test = _get_test(test_name)
1765
result = testtools.TestResult()
1769
def test_fail_has_log(self):
1770
result = self._run_test('test_fail')
1771
self.assertEqual(1, len(result.failures))
1772
result_content = result.failures[0][1]
1773
self.assertContainsRe(result_content, 'Text attachment: log')
1774
self.assertContainsRe(result_content, 'this was a failing test')
1776
def test_error_has_log(self):
1777
result = self._run_test('test_error')
1778
self.assertEqual(1, len(result.errors))
1779
result_content = result.errors[0][1]
1780
self.assertContainsRe(result_content, 'Text attachment: log')
1781
self.assertContainsRe(result_content, 'this test errored')
1783
def test_skip_has_no_log(self):
1784
result = self._run_test('test_skip')
1785
self.assertEqual(['reason'], result.skip_reasons.keys())
1786
skips = result.skip_reasons['reason']
1787
self.assertEqual(1, len(skips))
1789
self.assertFalse('log' in test.getDetails())
1791
def test_missing_feature_has_no_log(self):
1792
# testtools doesn't know about addNotSupported, so it just gets
1793
# considered as a skip
1794
result = self._run_test('test_missing_feature')
1795
self.assertEqual([missing_feature], result.skip_reasons.keys())
1796
skips = result.skip_reasons[missing_feature]
1797
self.assertEqual(1, len(skips))
1799
self.assertFalse('log' in test.getDetails())
1801
def test_xfail_has_no_log(self):
1802
result = self._run_test('test_xfail')
1803
self.assertEqual(1, len(result.expectedFailures))
1804
result_content = result.expectedFailures[0][1]
1805
self.assertNotContainsRe(result_content, 'Text attachment: log')
1806
self.assertNotContainsRe(result_content, 'test with expected failure')
1808
def test_unexpected_success_has_log(self):
1809
result = self._run_test('test_unexpected_success')
1810
self.assertEqual(1, len(result.unexpectedSuccesses))
1811
# Inconsistency, unexpectedSuccesses is a list of tests,
1812
# expectedFailures is a list of reasons?
1813
test = result.unexpectedSuccesses[0]
1814
details = test.getDetails()
1815
self.assertTrue('log' in details)
1818
1693
class TestTestCloning(tests.TestCase):
1819
1694
"""Tests that test cloning of TestCases (as used by multiply_tests)."""
2165
2040
load_list='missing file name', list_only=True)
2168
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2170
_test_needs_features = [features.subunit]
2172
def run_subunit_stream(self, test_name):
2173
from subunit import ProtocolTestCase
2175
return TestUtil.TestSuite([_get_test(test_name)])
2176
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2177
test_suite_factory=factory)
2178
test = ProtocolTestCase(stream)
2179
result = testtools.TestResult()
2181
content = stream.getvalue()
2182
return content, result
2184
def test_fail_has_log(self):
2185
content, result = self.run_subunit_stream('test_fail')
2186
self.assertEqual(1, len(result.failures))
2187
self.assertContainsRe(content, '(?m)^log$')
2188
self.assertContainsRe(content, 'this test will fail')
2190
def test_error_has_log(self):
2191
content, result = self.run_subunit_stream('test_error')
2192
self.assertContainsRe(content, '(?m)^log$')
2193
self.assertContainsRe(content, 'this test errored')
2195
def test_skip_has_no_log(self):
2196
content, result = self.run_subunit_stream('test_skip')
2197
self.assertNotContainsRe(content, '(?m)^log$')
2198
self.assertNotContainsRe(content, 'this test will be skipped')
2199
self.assertEqual(['reason'], result.skip_reasons.keys())
2200
skips = result.skip_reasons['reason']
2201
self.assertEqual(1, len(skips))
2203
# RemotedTestCase doesn't preserve the "details"
2204
## self.assertFalse('log' in test.getDetails())
2206
def test_missing_feature_has_no_log(self):
2207
content, result = self.run_subunit_stream('test_missing_feature')
2208
self.assertNotContainsRe(content, '(?m)^log$')
2209
self.assertNotContainsRe(content, 'missing the feature')
2210
self.assertEqual(['_MissingFeature\n'], result.skip_reasons.keys())
2211
skips = result.skip_reasons['_MissingFeature\n']
2212
self.assertEqual(1, len(skips))
2214
# RemotedTestCase doesn't preserve the "details"
2215
## self.assertFalse('log' in test.getDetails())
2217
def test_xfail_has_no_log(self):
2218
content, result = self.run_subunit_stream('test_xfail')
2219
self.assertNotContainsRe(content, '(?m)^log$')
2220
self.assertNotContainsRe(content, 'test with expected failure')
2221
self.assertEqual(1, len(result.expectedFailures))
2222
result_content = result.expectedFailures[0][1]
2223
self.assertNotContainsRe(result_content, 'Text attachment: log')
2224
self.assertNotContainsRe(result_content, 'test with expected failure')
2226
def test_unexpected_success_has_log(self):
2227
content, result = self.run_subunit_stream('test_unexpected_success')
2228
self.assertContainsRe(content, '(?m)^log$')
2229
self.assertContainsRe(content, 'test with unexpected success')
2230
self.expectFailure('subunit treats "unexpectedSuccess"'
2231
' as a plain success',
2232
self.assertEqual, 1, len(result.unexpectedSuccesses))
2233
self.assertEqual(1, len(result.unexpectedSuccesses))
2234
test = result.unexpectedSuccesses[0]
2235
# RemotedTestCase doesn't preserve the "details"
2236
## self.assertTrue('log' in test.getDetails())
2238
def test_success_has_no_log(self):
2239
content, result = self.run_subunit_stream('test_success')
2240
self.assertEqual(1, result.testsRun)
2241
self.assertNotContainsRe(content, '(?m)^log$')
2242
self.assertNotContainsRe(content, 'this test succeeds')
2245
2043
class TestRunBzr(tests.TestCase):
3323
3122
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3326
class TestPostMortemDebugging(tests.TestCase):
3327
"""Check post mortem debugging works when tests fail or error"""
3329
class TracebackRecordingResult(tests.ExtendedTestResult):
3331
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3332
self.postcode = None
3333
def _post_mortem(self, tb=None):
3334
"""Record the code object at the end of the current traceback"""
3335
tb = tb or sys.exc_info()[2]
3338
while next is not None:
3341
self.postcode = tb.tb_frame.f_code
3342
def report_error(self, test, err):
3344
def report_failure(self, test, err):
3347
def test_location_unittest_error(self):
3348
"""Needs right post mortem traceback with erroring unittest case"""
3349
class Test(unittest.TestCase):
3352
result = self.TracebackRecordingResult()
3354
self.assertEqual(result.postcode, Test.runTest.func_code)
3356
def test_location_unittest_failure(self):
3357
"""Needs right post mortem traceback with failing unittest case"""
3358
class Test(unittest.TestCase):
3360
raise self.failureException
3361
result = self.TracebackRecordingResult()
3363
self.assertEqual(result.postcode, Test.runTest.func_code)
3365
def test_location_bt_error(self):
3366
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3367
class Test(tests.TestCase):
3368
def test_error(self):
3370
result = self.TracebackRecordingResult()
3371
Test("test_error").run(result)
3372
self.assertEqual(result.postcode, Test.test_error.func_code)
3374
def test_location_bt_failure(self):
3375
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3376
class Test(tests.TestCase):
3377
def test_failure(self):
3378
raise self.failureException
3379
result = self.TracebackRecordingResult()
3380
Test("test_failure").run(result)
3381
self.assertEqual(result.postcode, Test.test_failure.func_code)
3383
def test_env_var_triggers_post_mortem(self):
3384
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3386
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3387
post_mortem_calls = []
3388
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3389
self.overrideEnv('BZR_TEST_PDB', None)
3390
result._post_mortem(1)
3391
self.overrideEnv('BZR_TEST_PDB', 'on')
3392
result._post_mortem(2)
3393
self.assertEqual([2], post_mortem_calls)
3396
3125
class TestRunSuite(tests.TestCase):
3398
3127
def test_runner_class(self):
3409
3138
self.verbosity)
3410
3139
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3411
3140
self.assertLength(1, calls)
3414
class TestEnvironHandling(tests.TestCase):
3416
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3417
self.failIf('MYVAR' in os.environ)
3418
self.overrideEnv('MYVAR', '42')
3419
# We use an embedded test to make sure we fix the _captureVar bug
3420
class Test(tests.TestCase):
3422
# The first call save the 42 value
3423
self.overrideEnv('MYVAR', None)
3424
self.assertEquals(None, os.environ.get('MYVAR'))
3425
# Make sure we can call it twice
3426
self.overrideEnv('MYVAR', None)
3427
self.assertEquals(None, os.environ.get('MYVAR'))
3429
result = tests.TextTestResult(output, 0, 1)
3430
Test('test_me').run(result)
3431
if not result.wasStrictlySuccessful():
3432
self.fail(output.getvalue())
3433
# We get our value back
3434
self.assertEquals('42', os.environ.get('MYVAR'))
3437
class TestIsolatedEnv(tests.TestCase):
3438
"""Test isolating tests from os.environ.
3440
Since we use tests that are already isolated from os.environ a bit of care
3441
should be taken when designing the tests to avoid bootstrap side-effects.
3442
The tests start an already clean os.environ which allow doing valid
3443
assertions about which variables are present or not and design tests around
3447
class ScratchMonkey(tests.TestCase):
3452
def test_basics(self):
3453
# Make sure we know the definition of BZR_HOME: not part of os.environ
3454
# for tests.TestCase.
3455
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3456
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3457
# Being part of isolated_environ, BZR_HOME should not appear here
3458
self.assertFalse('BZR_HOME' in os.environ)
3459
# Make sure we know the definition of LINES: part of os.environ for
3461
self.assertTrue('LINES' in tests.isolated_environ)
3462
self.assertEquals('25', tests.isolated_environ['LINES'])
3463
self.assertEquals('25', os.environ['LINES'])
3465
def test_injecting_unknown_variable(self):
3466
# BZR_HOME is known to be absent from os.environ
3467
test = self.ScratchMonkey('test_me')
3468
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3469
self.assertEquals('foo', os.environ['BZR_HOME'])
3470
tests.restore_os_environ(test)
3471
self.assertFalse('BZR_HOME' in os.environ)
3473
def test_injecting_known_variable(self):
3474
test = self.ScratchMonkey('test_me')
3475
# LINES is known to be present in os.environ
3476
tests.override_os_environ(test, {'LINES': '42'})
3477
self.assertEquals('42', os.environ['LINES'])
3478
tests.restore_os_environ(test)
3479
self.assertEquals('25', os.environ['LINES'])
3481
def test_deleting_variable(self):
3482
test = self.ScratchMonkey('test_me')
3483
# LINES is known to be present in os.environ
3484
tests.override_os_environ(test, {'LINES': None})
3485
self.assertTrue('LINES' not in os.environ)
3486
tests.restore_os_environ(test)
3487
self.assertEquals('25', os.environ['LINES'])
3490
class TestDocTestSuiteIsolation(tests.TestCase):
3491
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3493
Since tests.TestCase alreay provides an isolation from os.environ, we use
3494
the clean environment as a base for testing. To precisely capture the
3495
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3498
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3499
not `os.environ` so each test overrides it to suit its needs.
3503
def get_doctest_suite_for_string(self, klass, string):
3504
class Finder(doctest.DocTestFinder):
3506
def find(*args, **kwargs):
3507
test = doctest.DocTestParser().get_doctest(
3508
string, {}, 'foo', 'foo.py', 0)
3511
suite = klass(test_finder=Finder())
3514
def run_doctest_suite_for_string(self, klass, string):
3515
suite = self.get_doctest_suite_for_string(klass, string)
3517
result = tests.TextTestResult(output, 0, 1)
3519
return result, output
3521
def assertDocTestStringSucceds(self, klass, string):
3522
result, output = self.run_doctest_suite_for_string(klass, string)
3523
if not result.wasStrictlySuccessful():
3524
self.fail(output.getvalue())
3526
def assertDocTestStringFails(self, klass, string):
3527
result, output = self.run_doctest_suite_for_string(klass, string)
3528
if result.wasStrictlySuccessful():
3529
self.fail(output.getvalue())
3531
def test_injected_variable(self):
3532
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3535
>>> os.environ['LINES']
3538
# doctest.DocTestSuite fails as it sees '25'
3539
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3540
# tests.DocTestSuite sees '42'
3541
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3543
def test_deleted_variable(self):
3544
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3547
>>> os.environ.get('LINES')
3549
# doctest.DocTestSuite fails as it sees '25'
3550
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3551
# tests.DocTestSuite sees None
3552
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)