[TIP] RFC: Post-assertRaises assertions WAS: ANN: unittest2 0.4.0 Release

Olemis Lang olemis at gmail.com
Fri Apr 9 06:10:30 PDT 2010


On Thu, Apr 8, 2010 at 5:42 PM, Michael Foord <michael at voidspace.org.uk> wrote:
> Hello all,
>

:o)

> I'm pleased to announce the release of version 0.4.0 of unittest2.
>
[...]
>
> For full details of all the new features, see my blog entry:
>
> * http://www.voidspace.org.uk/python/weblog/arch_d7_2010_04_03.shtml#e1171
>

I wanted to know if you have considered support for writing assertions
targeting the exception object been raised . In my experience that is
very helpful when testing some kind of systems. For instance, in Trac
XmlRpcPlugin (<=0.1.6, current trunk ;o) you can find many tests
(actually all TCs checking for error conditions ;o) like this

{{{
#!python

class RpcXmlTestCase(unittest.TestCase):
    # Further code omitted ;o)
    def test_wrong_argspec(self):
        try:
            self.admin.system.listMethods("hello")
            self.fail("Oops. Wrong argspec accepted???")
        except xmlrpclib.Fault, e:
            self.assertEquals(2, e.faultCode)
            self.assertTrue("listMethods() takes exactly 2 arguments" \
                                    in e.faultString)

}}}

The fact is that the exception object is needed to ensure proper error
codes are returned by the RPC subsystem (and the current protocol
handler under test, plugin is starting to adopt a pluggable
architecture to support multiple RPC protocols ;o). Such assertions on
exc objs will be used quite quite quite often. Nonetheless this
specific style has some drawbacks e.g. assertion for failures are not
explicit, other error conditions are reported as errors rather than
failures, and ...

Therefore, we're recently considering [1]_ (not committed yet ;o) to
adopt this style

{{{
#!python

class TracRpcTestCase(unittest.TestCase):
        # Further code omitted ;o)
        def assertRaises(self, excClass, callableObj, *args, **kwargs):
            """Enhanced assertions to detect exceptions."""
            try:
                callableObj(*args, **kwargs)
            except excClass, e:
                return e
            except self.failureException :
                raise
            except Exception, e :
                if hasattr(excClass, '__name__'): excName = excClass.__name__
                else: excName = str(excClass)

                if hasattr(e, '__name__'): excMsg = e.__name__
                else: excMsg = str(e)

                raise self.failureException("\n\nExpected %s\n\nGot %s : %s" % (
                                        excName, e.__class__.__name__, excMsg))
            else:
                if hasattr(excClass,'__name__'): excName = excClass.__name__
                else: excName = str(excClass)
                raise self.failureException, "Expected %s\n\nNothing
raised" % excName

class RpcXmlTestCase(TracRpcTestCase):
    # Further code omitted ;o)
    def test_wrong_argspec(self):
        def local_test():
            self.admin.system.listMethods("hello")
            self.fail("Oops. Wrong argspec accepted???")
        e = self.assertRaises(xmlrpclib.Fault, local_test)
        self.assertEquals(1, e.faultCode)
        self.assertTrue("listMethods() takes exactly 2 arguments" \
                                    in e.faultString)

}}}

... using a customized `assertRaises` method that returns the
exception object in order to perform further assertions ;o).

This approach collides with context managers returned by modern
`assertRaises` impl but AFAICS might be extremely useful in situations
like the one I sketched above . Probably would be valuable to consider
support for this in unittest(2) , what d'u think ?

.. [1] TracRpc API v2 patch @ Bb
         (http://bitbucket.org/osimons/trac-rpc-mq/src/tip/t5437/t5437-protocol_api_v2-r7194.diff)

-- 
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:
On adding Hessian (RPC) support for Trac -
http://feedproxy.google.com/~r/simelo-en/~3/Vit6dRudChU/on-adding-hessian-rpc-support-for-trac.html



More information about the testing-in-python mailing list