Rev 4277: Give more output control to ExtendedTestResult (robertc) in http://bazaar.launchpad.net/%7Evila/bzr/integration
Vincent Ladeuil
v.ladeuil+lp at free.fr
Thu Apr 9 07:57:33 BST 2009
At http://bazaar.launchpad.net/%7Evila/bzr/integration
------------------------------------------------------------
revno: 4277 [merge]
revision-id: v.ladeuil+lp at free.fr-20090409065722-4gfl4u30ih8gzgvi
parent: pqm at pqm.ubuntu.com-20090409033000-rh4or6a6adg7k7c9
parent: v.ladeuil+lp at free.fr-20090409064833-z1lihlqdm9fitlq1
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: integration
timestamp: Thu 2009-04-09 08:57:22 +0200
message:
Give more output control to ExtendedTestResult (robertc)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_selftest.py test_selftest.py-20060123024542-01c5f1bbcb596d78
bzrlib/tests/test_selftest.py test_selftest.py-20051202044319-c110a115d8c0456a
------------------------------------------------------------
Use --levels 0 (or -n0) to see merged revisions.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-04-08 20:21:06 +0000
+++ b/NEWS 2009-04-09 06:57:22 +0000
@@ -40,12 +40,12 @@
API Changes
***********
-Testing
-*******
-
Internals
*********
+* ``bzrlib.tests.ExtendedTestResult`` has new methods ``startTests``
+ called before the first test is started, ``done`` called after the last
+ test completes, and a new parameter ``strict``. (Robert Collins)
bzr 1.14rc1
###########
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2009-04-08 18:02:00 +0000
+++ b/bzrlib/builtins.py 2009-04-09 06:57:22 +0000
@@ -3246,14 +3246,6 @@
if cache_dir is not None:
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
- if not list_only:
- print 'testing: %s' % (osutils.realpath(sys.argv[0]),)
- print ' %s (%s python%s)' % (
- bzrlib.__path__[0],
- bzrlib.version_string,
- bzrlib._format_version_tuple(sys.version_info),
- )
- print
if testspecs_list is not None:
pattern = '|'.join(testspecs_list)
else:
@@ -3299,11 +3291,6 @@
finally:
if benchfile is not None:
benchfile.close()
- if not list_only:
- if result:
- note('tests passed')
- else:
- note('tests failed')
return int(not result)
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2009-04-08 12:39:40 +0000
+++ b/bzrlib/tests/__init__.py 2009-04-09 06:48:33 +0000
@@ -133,6 +133,7 @@
def __init__(self, stream, descriptions, verbosity,
bench_history=None,
num_tests=None,
+ strict=False,
):
"""Construct new TestResult.
@@ -165,6 +166,22 @@
self.unsupported = {}
self.count = 0
self._overall_start_time = time.time()
+ self._strict = strict
+
+ def done(self):
+ if self._strict:
+ ok = self.wasStrictlySuccessful()
+ else:
+ ok = self.wasSuccessful()
+ if ok:
+ self.stream.write('tests passed\n')
+ else:
+ self.stream.write('tests failed\n')
+ if TestCase._first_thread_leaker_id:
+ self.stream.write(
+ '%s is leaking threads among %d leaking tests.\n' % (
+ TestCase._first_thread_leaker_id,
+ TestCase._leaking_threads_tests))
def _extractBenchmarkTime(self, testCase):
"""Add a benchmark time for the current test case."""
@@ -196,10 +213,23 @@
def startTest(self, test):
unittest.TestResult.startTest(self, test)
+ if self.count == 0:
+ self.startTests()
self.report_test_start(test)
test.number = self.count
self._recordTestStartTime()
+ def startTests(self):
+ self.stream.write(
+ 'testing: %s\n' % (osutils.realpath(sys.argv[0]),))
+ self.stream.write(
+ ' %s (%s python%s)\n' % (
+ bzrlib.__path__[0],
+ bzrlib.version_string,
+ bzrlib._format_version_tuple(sys.version_info),
+ ))
+ self.stream.write('\n')
+
def _recordTestStartTime(self):
"""Record that a test has started."""
self._start_time = time.time()
@@ -349,9 +379,10 @@
bench_history=None,
num_tests=None,
pb=None,
+ strict=None,
):
ExtendedTestResult.__init__(self, stream, descriptions, verbosity,
- bench_history, num_tests)
+ bench_history, num_tests, strict)
if pb is None:
self.pb = self.ui.nested_progress_bar()
self._supplied_pb = False
@@ -512,13 +543,15 @@
descriptions=0,
verbosity=1,
bench_history=None,
- list_only=False
+ list_only=False,
+ strict=False,
):
self.stream = unittest._WritelnDecorator(stream)
self.descriptions = descriptions
self.verbosity = verbosity
self._bench_history = bench_history
self.list_only = list_only
+ self._strict = strict
def run(self, test):
"Run the given test case or test suite."
@@ -532,6 +565,7 @@
self.verbosity,
bench_history=self._bench_history,
num_tests=test.countTestCases(),
+ strict=self._strict,
)
result.stop_early = self.stop_on_failure
result.report_starting()
@@ -716,12 +750,6 @@
return password
-def _report_leaked_threads():
- bzrlib.trace.warning('%s is leaking threads among %d leaking tests',
- TestCase._first_thread_leaker_id,
- TestCase._leaking_threads_tests)
-
-
class TestCase(unittest.TestCase):
"""Base class for bzr unit tests.
@@ -787,10 +815,6 @@
TestCase._leaking_threads_tests += 1
if TestCase._first_thread_leaker_id is None:
TestCase._first_thread_leaker_id = self.id()
- # we're not specifically told when all tests are finished.
- # This will do. We use a function to avoid keeping a reference
- # to a TestCase object.
- atexit.register(_report_leaked_threads)
def _clear_debug_flags(self):
"""Prevent externally set debug flags affecting tests.
@@ -2617,7 +2641,8 @@
exclude_pattern=None,
strict=False,
runner_class=None,
- suite_decorators=None):
+ suite_decorators=None,
+ stream=None):
"""Run a test suite for bzr selftest.
:param runner_class: The class of runner to use. Must support the
@@ -2632,11 +2657,14 @@
verbosity = 1
if runner_class is None:
runner_class = TextTestRunner
- runner = runner_class(stream=sys.stdout,
+ if stream is None:
+ stream = sys.stdout
+ runner = runner_class(stream=stream,
descriptions=0,
verbosity=verbosity,
bench_history=bench_history,
list_only=list_only,
+ strict=strict,
)
runner.stop_on_failure=stop_on_failure
# built in decorator factories:
@@ -2655,6 +2683,7 @@
result = runner.run(suite)
if list_only:
return True
+ result.done()
if strict:
return result.wasStrictlySuccessful()
else:
@@ -3908,8 +3937,6 @@
from subunit import TestProtocolClient
class SubUnitBzrRunner(TextTestRunner):
def run(self, test):
- # undo out claim for testing which looks like a test start to subunit
- self.stream.write("success: %s\n" % (osutils.realpath(sys.argv[0]),))
result = TestProtocolClient(self.stream)
test.run(result)
return result
=== modified file 'bzrlib/tests/blackbox/test_selftest.py'
--- a/bzrlib/tests/blackbox/test_selftest.py 2009-04-08 07:46:50 +0000
+++ b/bzrlib/tests/blackbox/test_selftest.py 2009-04-08 19:06:40 +0000
@@ -102,9 +102,7 @@
test = ProtocolTestCase(stream)
result = unittest.TestResult()
test.run(result)
- # 1 to deal with the 'test:' noise at the start, and 1 for the one we
- # ran.
- self.assertEqual(2, result.testsRun)
+ self.assertEqual(1, result.testsRun)
class TestRunBzr(ExternalBase):
@@ -198,9 +196,7 @@
finally:
TestCaseWithMemoryTransport.TEST_ROOT = old_root
self.assertContainsRe(out, 'Ran 0 tests.*\n\nOK')
- self.assertEqual(
- 'tests passed\n',
- err)
+ self.assertContainsRe(out, 'tests passed\n')
benchfile = open(".perf_history", "rt")
try:
lines = benchfile.readlines()
=== modified file 'bzrlib/tests/test_selftest.py'
--- a/bzrlib/tests/test_selftest.py 2009-03-24 01:53:42 +0000
+++ b/bzrlib/tests/test_selftest.py 2009-04-09 06:48:33 +0000
@@ -836,7 +836,8 @@
def test_known_failure(self):
"""A KnownFailure being raised should trigger several result actions."""
class InstrumentedTestResult(ExtendedTestResult):
-
+ def done(self): pass
+ def startTests(self): pass
def report_test_start(self, test): pass
def report_known_failure(self, test, err):
self._call = test, err
@@ -884,7 +885,7 @@
# text test output formatting
pb = MockProgress()
result = bzrlib.tests.TextTestResult(
- None,
+ StringIO(),
descriptions=0,
verbosity=1,
pb=pb,
@@ -924,6 +925,8 @@
def test_add_not_supported(self):
"""Test the behaviour of invoking addNotSupported."""
class InstrumentedTestResult(ExtendedTestResult):
+ def done(self): pass
+ def startTests(self): pass
def report_test_start(self, test): pass
def report_unsupported(self, test, feature):
self._call = test, feature
@@ -966,7 +969,7 @@
# text test output formatting
pb = MockProgress()
result = bzrlib.tests.TextTestResult(
- None,
+ StringIO(),
descriptions=0,
verbosity=1,
pb=pb,
@@ -994,7 +997,8 @@
def test_unavailable_exception(self):
"""An UnavailableFeature being raised should invoke addNotSupported."""
class InstrumentedTestResult(ExtendedTestResult):
-
+ def done(self): pass
+ def startTests(self): pass
def report_test_start(self, test): pass
def addNotSupported(self, test, feature):
self._call = test, feature
@@ -1037,6 +1041,19 @@
self.assertTrue(result.wasStrictlySuccessful())
self.assertEqual(None, result._extractBenchmarkTime(test))
+ def test_startTests(self):
+ """Starting the first test should trigger startTests."""
+ class InstrumentedTestResult(ExtendedTestResult):
+ calls = 0
+ def startTests(self): self.calls += 1
+ def report_test_start(self, test): pass
+ result = InstrumentedTestResult(None, None, None, None)
+ def test_function():
+ pass
+ test = unittest.FunctionTestCase(test_function)
+ test.run(result)
+ self.assertEquals(1, result.calls)
+
class TestUnicodeFilenameFeature(TestCase):
@@ -1094,7 +1111,7 @@
'----------------------------------------------------------------------',
'',
'FAILED (failures=1, known_failure_count=1)'],
- lines[0:5] + lines[6:10] + lines[11:])
+ lines[3:8] + lines[9:13] + lines[14:])
def test_known_failure_ok_run(self):
# run a test that generates a known failure which should be printed in the final output.
@@ -2348,5 +2365,21 @@
calls.append(test)
return ExtendedTestResult(self.stream, self.descriptions,
self.verbosity)
- run_suite(suite, runner_class=MyRunner)
+ run_suite(suite, runner_class=MyRunner, stream=StringIO())
self.assertEqual(calls, [suite])
+
+ def test_done(self):
+ """run_suite should call result.done()"""
+ self.calls = 0
+ def one_more_call(): self.calls += 1
+ def test_function():
+ pass
+ test = unittest.FunctionTestCase(test_function)
+ class InstrumentedTestResult(ExtendedTestResult):
+ def done(self): one_more_call()
+ class MyRunner(TextTestRunner):
+ def run(self, test):
+ return InstrumentedTestResult(self.stream, self.descriptions,
+ self.verbosity)
+ run_suite(test, runner_class=MyRunner, stream=StringIO())
+ self.assertEquals(1, self.calls)
More information about the bazaar-commits
mailing list