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