summaryrefslogtreecommitdiff
path: root/python/subunit
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2009-02-22 17:28:08 +1100
committerRobert Collins <robertc@robertcollins.net>2009-02-22 17:28:08 +1100
commit1fe1cb079b5202ec36985eeb5d2ccb38ca916585 (patch)
tree7030b833635ab1b0b8f1aee2fcbbfd4a3ff8870c /python/subunit
parent0c7bb6072d34094bc07cacd140f7efdd3b0d062d (diff)
downloadsubunit-git-1fe1cb079b5202ec36985eeb5d2ccb38ca916585.tar.gz
Add a TestResultFilter supporting filtering out success/fail/errors.
Diffstat (limited to 'python/subunit')
-rw-r--r--python/subunit/__init__.py49
-rw-r--r--python/subunit/tests/__init__.py2
-rw-r--r--python/subunit/tests/test_subunit_filter.py115
3 files changed, 166 insertions, 0 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py
index f63a3a0..c3d06ff 100644
--- a/python/subunit/__init__.py
+++ b/python/subunit/__init__.py
@@ -681,3 +681,52 @@ class TestResultStats(unittest.TestResult):
def wasSuccessful(self):
"""Tells whether or not this result was a success"""
return self.failed_tests == 0
+
+
+class TestResultFilter(unittest.TestResult):
+ """A pyunit TestResult interface implementation which filters tests.
+
+ Tests that pass the filter are handed on to another TestResult instance
+ for further processing/reporting. To obtain the filtered results,
+ the other instance must be interrogated.
+
+ :ivar result: The result that tests are passed to after filtering.
+ """
+
+ def __init__(self, result, filter_error=False, filter_failure=False,
+ filter_success=True):
+ """Create a FilterResult object filtering to result.
+
+ :param filter_error: Filter out errors.
+ :param filter_failure: Filter out failures.
+ :param filter_success: Filter out successful tests.
+ """
+ unittest.TestResult.__init__(self)
+ self.result = result
+ self._filter_error = filter_error
+ self._filter_failure = filter_failure
+ self._filter_success = filter_success
+
+ def addError(self, test, err):
+ if not self._filter_error:
+ self.result.startTest(test)
+ self.result.addError(test, err)
+ self.result.stopTest(test)
+
+ def addFailure(self, test, err):
+ if not self._filter_failure:
+ self.result.startTest(test)
+ self.result.addFailure(test, err)
+ self.result.stopTest(test)
+
+ def addSuccess(self, test):
+ if not self._filter_success:
+ self.result.startTest(test)
+ self.result.addSuccess(test)
+ self.result.stopTest(test)
+
+ def id_to_orig_id(self, id):
+ if id.startswith("subunit.RemotedTestCase."):
+ return id[len("subunit.RemotedTestCase."):]
+ return id
+
diff --git a/python/subunit/tests/__init__.py b/python/subunit/tests/__init__.py
index a506281..fa41930 100644
--- a/python/subunit/tests/__init__.py
+++ b/python/subunit/tests/__init__.py
@@ -19,6 +19,7 @@
from subunit.tests import (
TestUtil,
+ test_subunit_filter,
test_subunit_stats,
test_subunit_tags,
test_tap2subunit,
@@ -29,6 +30,7 @@ def test_suite():
result = TestUtil.TestSuite()
result.addTest(test_test_protocol.test_suite())
result.addTest(test_tap2subunit.test_suite())
+ result.addTest(test_subunit_filter.test_suite())
result.addTest(test_subunit_tags.test_suite())
result.addTest(test_subunit_stats.test_suite())
return result
diff --git a/python/subunit/tests/test_subunit_filter.py b/python/subunit/tests/test_subunit_filter.py
new file mode 100644
index 0000000..825809c
--- /dev/null
+++ b/python/subunit/tests/test_subunit_filter.py
@@ -0,0 +1,115 @@
+#
+# subunit: extensions to python unittest to get test results from subprocesses.
+# Copyright (C) 2005 Robert Collins <robertc@robertcollins.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Tests for subunit.TestResultFilter."""
+
+import unittest
+from StringIO import StringIO
+
+import subunit
+
+
+class TestTestResultFilter(unittest.TestCase):
+ """Test for TestResultFilter, a TestResult object which filters tests."""
+
+ def _setUp(self):
+ self.output = StringIO()
+
+ def test_default(self):
+ """The default is to exclude success and include everything else."""
+ self.filtered_result = unittest.TestResult()
+ self.filter = subunit.TestResultFilter(self.filtered_result)
+ self.run_tests()
+ self.assertEqual(['subunit.RemotedTestCase.error'],
+ [error[0].id() for error in self.filtered_result.errors])
+ self.assertEqual(['subunit.RemotedTestCase.failed'],
+ [failure[0].id() for failure in
+ self.filtered_result.failures])
+ self.assertEqual(2, self.filtered_result.testsRun)
+
+ def test_exclude_errors(self):
+ self.filtered_result = unittest.TestResult()
+ self.filter = subunit.TestResultFilter(self.filtered_result,
+ filter_error=True)
+ self.run_tests()
+ self.assertEqual([],
+ [error[0].id() for error in self.filtered_result.errors])
+ self.assertEqual(['subunit.RemotedTestCase.failed'],
+ [failure[0].id() for failure in
+ self.filtered_result.failures])
+ self.assertEqual(1, self.filtered_result.testsRun)
+
+ def test_exclude_failure(self):
+ self.filtered_result = unittest.TestResult()
+ self.filter = subunit.TestResultFilter(self.filtered_result,
+ filter_failure=True)
+ self.run_tests()
+ self.assertEqual(['subunit.RemotedTestCase.error'],
+ [error[0].id() for error in self.filtered_result.errors])
+ self.assertEqual([],
+ [failure[0].id() for failure in
+ self.filtered_result.failures])
+ self.assertEqual(1, self.filtered_result.testsRun)
+
+ def test_include_success(self):
+ """Success's can be included if requested."""
+ self.filtered_result = unittest.TestResult()
+ self.filter = subunit.TestResultFilter(self.filtered_result,
+ filter_success=False)
+ self.run_tests()
+ self.assertEqual(['subunit.RemotedTestCase.error'],
+ [error[0].id() for error in self.filtered_result.errors])
+ self.assertEqual(['subunit.RemotedTestCase.failed'],
+ [failure[0].id() for failure in
+ self.filtered_result.failures])
+ self.assertEqual(5, self.filtered_result.testsRun)
+
+
+ def run_tests(self):
+ self.setUpTestStream()
+ self.test = subunit.ProtocolTestCase(self.input_stream)
+ self.test.run(self.filter)
+
+ def setUpTestStream(self):
+ # While TestResultFilter works on python objects, using a subunit
+ # stream is an easy pithy way of getting a series of test objects to
+ # call into the TestResult, and as TestResultFilter is intended for use
+ # with subunit also has the benefit of detecting any interface skew issues.
+ self.input_stream = StringIO()
+ self.input_stream.write("""tags: global
+test passed
+success passed
+test failed
+tags: local
+failure failed
+test error
+error error
+test skipped
+skip skipped
+test todo
+xfail todo
+""")
+ self.input_stream.seek(0)
+
+
+
+def test_suite():
+ loader = subunit.tests.TestUtil.TestLoader()
+ result = loader.loadTestsFromName(__name__)
+ return result