decorators to add test* TestCase methods
Peter Otten
__peter__ at web.de
Fri Jan 27 08:12:38 EST 2006
Bruce Cropley wrote:
> I'm trying to generate test methods in a unittest TestCase
> subclass, using decorators. I'd like to be able to say:
>
> class MyTestCase(unittest.TestCase):
> @genTests(["Buy", "Sell"], [1,2,3], [True, False])
> def something(self, side, price, someFlag):
> # etc...
>
> And have it generate functions called:
> test_Buy_1_True_something
> test_Buy_1_False_something
> through to...
> test_Sell_3_False_something
I think that's a nice idea. Here is a preliminary implementation:
#!/usr/bin/env python
import unittest
def combine(axes):
if axes:
for value in axes[0]:
for rest in combine(axes[1:]):
yield (value,) + rest
else:
yield ()
def make_method(func, name, args):
def method(self):
return func(self, *args)
method.__name__ = name
return method
class TestGrid(object):
def __init__(self, func, axes):
self.func = func
self.axes = axes
def __iter__(self):
axes = self.axes
func = self.func
name_format = "_".join(("test", self.func.__name__) +
("%s",)*len(axes))
for values in combine(axes):
name = name_format % values
yield name, make_method(func, name, values)
class genTests:
def __init__(self, *axes):
self.axes = axes
def __call__(self, func):
return TestGrid(func, self.axes)
class GridTestCase(unittest.TestCase):
class __metaclass__(type):
def __new__(mcl, clsname, bases, dict):
for name, value in dict.items():
if isinstance(value, TestGrid):
for method_name, method in value:
if method_name in dict:
raise Exception("name clash")
dict[method_name] = method
return type.__new__(mcl, clsname, bases, dict)
class MyTestCase(GridTestCase):
@genTests(["Buy", "Sell"], [1,2,3], [True, False])
def something(self, side, price, someFlag):
pass #print "test(side=%r, price=%r, someFlag=%r)" % (side, price,
someFlag)
if __name__ == "__main__":
unittest.main()
More information about the Python-list
mailing list