B
Bruce Cropley
Hi all
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
Each of these would call the something function with the
expected parameters. I guess that the new 2.5 partial()
could help with this.
There are two problems:
- Decorators don't seem to be able to add functions to the
class because it is still being defined. I know decorators
aren't really intended for this, but it would be nice to keep
the expansion call near the generic test method source.
- There seems to be a bug with creating functions in a loop,
see below...
Here's my attempt so far:
---------8<-----------
#!/usr/bin/env python
# Generate all combinations of values of args.
def product(*args):
if len(args) == 0:
return [[]]
return [[val] + rest
for val in args[0]
for rest in product(*args[1:])]
class Test:
# Making this a classmethod doesn't seem to have gained me much.
# perhaps it should be just a function, and use func.im_class?
@classmethod
def genTests(cls, func, *args):
""" Generate all test functions of the form:
test_B_Harry_{func.func_name}
test_B_Sally_{func.func_name}
test_S_Harry_{func.func_name}
test_S_Sally_{func.func_name}
... which call self.func with the corresponding parameters.
"""
for param_combo in product(*args):
#print "In loop, generating %s" % param_combo
def testFunc(self):
#print "In test func: %s" % param_combo
func(self, *param_combo)
func_name = "_".join(["test"] + param_combo +
[func.func_name])
setattr(cls, "%s" % func_name, testFunc)
class Derived(Test):
# I want to be able to do:
# @genTests(["B", "S"], ["Harry", "Sally"])
def blah(self, side, name):
print "blah: %s %s" % (side, name)
t = Derived()
# Hack
Derived.genTests(Derived.blah, ["B", "S"], ["Harry", "Sally"])
t.test_S_Sally_blah()
# This is failing (generates test_S_Sally_blah),
# and appears to be a python bug:
t.test_B_Harry_blah()
---------8<----------
Does anyone have any suggestions?
Thanks,
Bruce
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
Each of these would call the something function with the
expected parameters. I guess that the new 2.5 partial()
could help with this.
There are two problems:
- Decorators don't seem to be able to add functions to the
class because it is still being defined. I know decorators
aren't really intended for this, but it would be nice to keep
the expansion call near the generic test method source.
- There seems to be a bug with creating functions in a loop,
see below...
Here's my attempt so far:
---------8<-----------
#!/usr/bin/env python
# Generate all combinations of values of args.
def product(*args):
if len(args) == 0:
return [[]]
return [[val] + rest
for val in args[0]
for rest in product(*args[1:])]
class Test:
# Making this a classmethod doesn't seem to have gained me much.
# perhaps it should be just a function, and use func.im_class?
@classmethod
def genTests(cls, func, *args):
""" Generate all test functions of the form:
test_B_Harry_{func.func_name}
test_B_Sally_{func.func_name}
test_S_Harry_{func.func_name}
test_S_Sally_{func.func_name}
... which call self.func with the corresponding parameters.
"""
for param_combo in product(*args):
#print "In loop, generating %s" % param_combo
def testFunc(self):
#print "In test func: %s" % param_combo
func(self, *param_combo)
func_name = "_".join(["test"] + param_combo +
[func.func_name])
setattr(cls, "%s" % func_name, testFunc)
class Derived(Test):
# I want to be able to do:
# @genTests(["B", "S"], ["Harry", "Sally"])
def blah(self, side, name):
print "blah: %s %s" % (side, name)
t = Derived()
# Hack
Derived.genTests(Derived.blah, ["B", "S"], ["Harry", "Sally"])
t.test_S_Sally_blah()
# This is failing (generates test_S_Sally_blah),
# and appears to be a python bug:
t.test_B_Harry_blah()
---------8<----------
Does anyone have any suggestions?
Thanks,
Bruce