[TIP] Nose bug? using inspect.ismethod too aggressive?

Robert Collins robertc at robertcollins.net
Sun Sep 20 21:25:06 PDT 2009


On Sun, 2009-09-20 at 19:46 -0700, Fernando Perez wrote:
> 
> an old solution of mine that went into numpy, one from twisted.trial,
> the one in nose and the one in py.test, and they all left me wanting.
> This one, I'm finally happy with, I hope someone else finds it useful.
>  At the very least, it makes *me* happy :) 

The functionality is nice, and its clearly superior to testscenarios for
the sorts of parameterisation you're doing.

However, the run_parametric function duplicates most of
TestCase.__call__ which -will- lead to skew and bugs. In particular
you're missing all of the 2.7/3.1 changes [some of which [class
skipping] I hope to cleanup 'soon'] but most of which are really good
and useful.

Looking at your implementation, you call setUp()/next()/tearDown(). This
might cause some confusion if users cache attributes :). However,
assuming thats deliberate, what about the below (it needs 2.7/3.1
because of the improved TestSuite). Doing it for older pythons just
needs a slightly larger TestSuite (you have to override a couple more
methods to use self.__iter__).


class IterCallableSuite(TestSuite):
    def __init__(self, iter, adapter):
        self._iter = iter
        self._adapter = adapter
    def __iter__(self):
        for callable in self._iter:
            yield self._adapter(callable)

class ParametricTestCase(unittest.TestCase):
    """Write parametric tests in normal unittest testcase form.

    Limitations: the last iteration misses printing out a newline when
    running in verbose mode.
    """
        
    def run(self, result=None):
        testMethod = getattr(self, self._testMethodName)
        # For normal tests, we just call the base class and return that
        if isgenerator(testMethod):
            return IterSuite(testMethod, lambda next: 
                 unittest.case.FunctionTestCase(next, self.setUp,
                 self.tearDown)).run(result)
        else:
            return super(ParametricTestCase, self).run(result)


def parametric(func):
    """Decorator to make a simple function into a normal test via
unittest."""
    class Tester(ParametricTestCase):
        test = staticmethod(func)

    Tester.__name__ = func.func_name

    return Tester


Cheers,
Rob
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
Url : http://lists.idyll.org/pipermail/testing-in-python/attachments/20090921/8c4530ff/attachment-0001.pgp 


More information about the testing-in-python mailing list