Rev 133: (bug #623654) omit repeated time() calls. in http://bazaar.launchpad.net/~jameinel/subunit
John Arbash Meinel
john at arbash-meinel.com
Wed Aug 25 01:17:20 BST 2010
At http://bazaar.launchpad.net/~jameinel/subunit
------------------------------------------------------------
revno: 133
revision-id: john at arbash-meinel.com-20100825001700-jy0r1lbbol5q5ja2
parent: jml at canonical.com-20100805122920-t6z0viif1x08yu0e
fixes bug(s): https://launchpad.net/bugs/623654
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: subunit
timestamp: Tue 2010-08-24 19:17:00 -0500
message:
(bug #623654) omit repeated time() calls.
If we are filtering out a bunch of tests, we should filter out their related time calls.
We emit a time only if it comes before or after something that isn't a time call.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2010-07-02 12:51:46 +0000
+++ b/NEWS 2010-08-25 00:17:00 +0000
@@ -5,6 +5,14 @@
NEXT (In development)
---------------------
+IMPROVEMENTS
+~~~~~~~~~~~~
+
+* 'subunit-filter' now only emits time statements if they come just before or
+ just after another action. That way, went filtering out 1k tests, we don't
+ end up with 2k time statements doing nothing.
+ (John Arbash Meinel, #623654)
+
0.0.6
-----
=== modified file 'python/subunit/test_results.py'
--- a/python/subunit/test_results.py 2010-08-04 17:05:18 +0000
+++ b/python/subunit/test_results.py 2010-08-25 00:17:00 +0000
@@ -87,6 +87,10 @@
def time(self, a_datetime):
return self.decorated.time(a_datetime)
+ def stopTestRun(self):
+ return self.decorated.stopTestRun()
+
+
class HookedTestResultDecorator(TestResultDecorator):
"""A TestResult which calls a hook on every event."""
@@ -236,10 +240,13 @@
self._current_test_filtered = None
# The (new, gone) tags for the current test.
self._current_test_tags = None
+ self._last_was_time = False
+ self._buffered_time = None
def addError(self, test, err=None, details=None):
if (not self._filter_error and
self.filter_predicate(test, 'error', err, details)):
+ self._emitBufferedTime()
self.decorated.startTest(test)
self.decorated.addError(test, err, details=details)
else:
@@ -248,6 +255,7 @@
def addFailure(self, test, err=None, details=None):
if (not self._filter_failure and
self.filter_predicate(test, 'failure', err, details)):
+ self._emitBufferedTime()
self.decorated.startTest(test)
self.decorated.addFailure(test, err, details=details)
else:
@@ -256,6 +264,7 @@
def addSkip(self, test, reason=None, details=None):
if (not self._filter_skip and
self.filter_predicate(test, 'skip', reason, details)):
+ self._emitBufferedTime()
self.decorated.startTest(test)
self.decorated.addSkip(test, reason, details=details)
else:
@@ -264,6 +273,7 @@
def addSuccess(self, test, details=None):
if (not self._filter_success and
self.filter_predicate(test, 'success', None, details)):
+ self._emitBufferedTime()
self.decorated.startTest(test)
self.decorated.addSuccess(test, details=details)
else:
@@ -271,6 +281,7 @@
def addExpectedFailure(self, test, err=None, details=None):
if self.filter_predicate(test, 'expectedfailure', err, details):
+ self._emitBufferedTime()
self.decorated.startTest(test)
return self.decorated.addExpectedFailure(test, err,
details=details)
@@ -278,6 +289,7 @@
self._filtered()
def addUnexpectedSuccess(self, test, details=None):
+ self._emitBufferedTime()
self.decorated.startTest(test)
return self.decorated.addUnexpectedSuccess(test, details=details)
@@ -330,6 +342,28 @@
if id.startswith("subunit.RemotedTestCase."):
return id[len("subunit.RemotedTestCase."):]
return id
+
+ def time(self, a_datetime):
+ if self._last_was_time:
+ self._buffered_time = a_datetime
+ return
+ self._last_was_time = True
+ super(TestResultFilter, self).time(a_datetime)
+
+ def _emitBufferedTime(self):
+ """Called before an action call.
+
+ If we have a time call that was buffered, waiting for output, we go
+ ahead and emit it now, and clear the buffers.
+ """
+ self._last_was_time = False
+ if self._buffered_time is not None:
+ super(TestResultFilter, self).time(self._buffered_time)
+ self._buffered_time = None
+
+ def stopTestRun(self):
+ self._emitBufferedTime()
+ super(TestResultFilter, self).stopTestRun()
class TestIdPrintingResult(testtools.TestResult):
=== modified file 'python/subunit/tests/test_test_results.py'
--- a/python/subunit/tests/test_test_results.py 2009-12-13 01:59:07 +0000
+++ b/python/subunit/tests/test_test_results.py 2010-08-25 00:17:00 +0000
@@ -193,6 +193,88 @@
self.assertNotEqual(None, self.decorated._calls[2])
+class TestTestResultFilter(unittest.TestCase):
+
+ def make_result(self, filter_success=True, filter_failure=False,
+ filter_error=False, filter_skip=False):
+
+ terminal = TimeCapturingResult()
+ # The result object under test.
+ self.result = subunit.test_results.TestResultFilter(terminal,
+ filter_skip=filter_skip, filter_error=filter_error,
+ filter_failure=filter_failure, filter_success=filter_success)
+ self.decorated = terminal
+ self.cur_time = 0
+
+ def addTime(self):
+ dt = datetime.datetime(2009,10,11,12,13,14,self.cur_time,
+ iso8601.Utc())
+ self.result.time(dt)
+ self.cur_time += 1
+
+ def make_simple_timing(self, center_call, *args, **kwargs):
+ self.result.startTestRun()
+ self.addTime()
+ self.addTime()
+ center_call(*args, **kwargs)
+ self.addTime()
+ self.addTime()
+ self.result.stopTestRun()
+
+ def test_timing_filtered(self):
+ self.make_result()
+ self.result.startTestRun()
+ for i in xrange(4):
+ self.addTime()
+ self.result.stopTestRun()
+ self.assertEqual(2, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_success_filtered(self):
+ self.make_result()
+ self.make_simple_timing(self.result.addSuccess, self)
+ # addSuccess defaults to being filtered, so we hide the extra time
+ # calls
+ self.assertEqual(2, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_success_not_filtered(self):
+ self.make_result(filter_success=False)
+ self.make_simple_timing(self.result.addSuccess, self)
+ # When not filtered, we include the start time, the time before and
+ # after the run, and the stop time.
+ self.assertEqual(4, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_failure(self):
+ self.make_result()
+ self.make_simple_timing(self.result.addFailure, self, details={})
+ self.assertEqual(4, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_error(self):
+ self.make_result()
+ self.make_simple_timing(self.result.addError, self, details={})
+ self.assertEqual(4, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_skip(self):
+ self.make_result(filter_skip=False)
+ self.make_simple_timing(self.result.addSkip, self, 'foo')
+ self.assertEqual(4, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_expected_failure(self):
+ self.make_result()
+ self.make_simple_timing(self.result.addExpectedFailure, self, 'xfail')
+ self.assertEqual(4, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_unexpected_success(self):
+ self.make_result()
+ self.make_simple_timing(self.result.addUnexpectedSuccess, self)
+ self.assertEqual(4, len(self.decorated._calls))
+
+ def test_timing_filtered_w_add_unexpected_success(self):
+ self.make_result()
+ self.make_simple_timing(self.result.addUnexpectedSuccess, self)
+ self.assertEqual(4, len(self.decorated._calls))
+
+
+
def test_suite():
loader = subunit.tests.TestUtil.TestLoader()
result = loader.loadTestsFromName(__name__)
More information about the bazaar-commits
mailing list