Nir Soffer has uploaded a new change for review.

Change subject: tests: Add assertNotRaises assertion
......................................................................

tests: Add assertNotRaises assertion

We like to separate test errors from test failures. If I'm trying to
setup a test, and the setup code raised, this is failure of the test
code, not the code under test. If an assetion failed, this is a failure
of the code under test.

There are other cases, where error raised in the test should be
considered a test failure. For example, if I'm testing code writing a
file, and the test is verifying the code by parsing the file, we can
have many possible errors that mean test failure - missing file, some
parsing error, and sometimes just any error while trying to parse the
file. In this case, we may get a test error instead of a failure, and
waste time suspecting error free test code.

This patch add a new assertNotRaises assertion, that ensure that we get
a test failure in such cases.

This assertion can be used inline:

    self.assertNotRaises(Error, func, "foo")

Or as a context manager:

    with self.assertNotRaises(Error):
        that_func('foo')
        other_func('bar')

The test will fail Error or subclass of Error is raised, but will pass
if it raises unrelated error.

Change-Id: I33c96ca855753a75ffe2f82bdecab2e1612da08a
Signed-off-by: Nir Soffer <nsof...@redhat.com>
---
M tests/Makefile.am
M tests/testrunner.py
A tests/testrunnerTests.py
3 files changed, 81 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/77/28177/1

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 037db35..30953a8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -69,6 +69,7 @@
        sslTests.py \
        storageMailboxTests.py \
        tcTests.py \
+       testrunnerTests.py \
        toolTests.py \
        transportWrapperTests.py \
        utilsTests.py \
diff --git a/tests/testrunner.py b/tests/testrunner.py
index ac0f90f..81a97d8 100644
--- a/tests/testrunner.py
+++ b/tests/testrunner.py
@@ -181,6 +181,15 @@
         with context:
             callableObj(*args, **kwargs)
 
+    def assertNotRaises(self, excClass, callableObj=None, *args, **kwargs):
+        # This is required when exception raised during the call should be
+        # considered as a test failure.
+        context = not_raises(excClass, self)
+        if callableObj is None:
+            return context
+        with context:
+            callableObj(*args, **kwargs)
+
     # FIXME: This is a forward port of the assertIn from python
     #        2.7, remove when no loger supporting earlier versions
     def assertIn(self, member, container, msg=None):
@@ -320,6 +329,16 @@
         return True
 
 
+@contextmanager
+def not_raises(unexpected, test_case):
+    try:
+        yield
+    except unexpected as e:
+        raise test_case.failureException("Excption raised: %s" % e)
+    except:
+        pass
+
+
 # FIXME: This is a forward port of the assertIn from python
 #        2.7, remove when no loger supporting earlier versions
 def safe_repr(obj, short=False):
diff --git a/tests/testrunnerTests.py b/tests/testrunnerTests.py
new file mode 100644
index 0000000..afb3a5e
--- /dev/null
+++ b/tests/testrunnerTests.py
@@ -0,0 +1,61 @@
+#
+# Copyright 2014 Red Hat, Inc.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+from testrunner import VdsmTestCase
+
+
+class Error(Exception):
+    pass
+
+
+class SubError(Error):
+    pass
+
+
+class OtherError(Exception):
+    pass
+
+
+class TestRunnerTests(VdsmTestCase):
+
+    def test_context_failure(self):
+        with self.assertRaises(self.failureException):
+            with self.assertNotRaises(Error):
+                raise Error("generated error")
+
+    def test_context_pass(self):
+        with self.assertNotRaises(Error):
+            raise OtherError("generated error")
+
+    def test_inline_failure(self):
+        def func():
+            raise Error("generated error")
+        with self.assertRaises(self.failureException):
+            self.assertNotRaises(Error, func)
+
+    def test_inline_pass(self):
+        def func():
+            raise OtherError("generated error")
+        self.assertNotRaises(Error, func)
+
+    def test_subclass(self):
+        with self.assertRaises(self.failureException):
+            with self.assertNotRaises(Error):
+                raise SubError("generated error")


-- 
To view, visit http://gerrit.ovirt.org/28177
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I33c96ca855753a75ffe2f82bdecab2e1612da08a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsof...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to