I'm trying to create a unit test, that checks that every function in mymodule
has its own TestCase
instance.
To reduce boiler-plate code and manual effort I wanted to use introspection/reflection to dynamically add lambda
functions as class methods to the initially empty class Test_TestCases
.
The following code kind of works - it does indeed add lambdas as class methods and unittest.main()
finds and correctly calls them.
import unittest
from unittest import TestCase
import mymodule
class Test_TestCases(TestCase):
"""Class whose test_* methods will be created during runtime."""
pass
################################################################################
if __name__ == "__main__":
for item in dir(mymodule):
attr = getattr(pws, item)
if callable(attr):
testname = "Test_%s" % item
setattr(Test_TestCases, "test_%s_is_tested" % item,
lambda self: self.assertTrue(testname in globals()) and
issubclass(getattr(globals(), testname), TestCase))
unittest.main()
The problem is, that all tests succeed even though I do have untested functions in my unit test module.
After a little trying around I figured out that the variable testname
has the same value every time the lambda
is called.
I could minimize the problem to this piece of code for reproducability:
lambdas = []
for i in range(5):
lambdas.append(lambda: str(i))
print ", ".join(f() for f in lambdas)
I'd expect this output:
0, 1, 2, 3, 4
but instead I get:
4, 4, 4, 4, 4
It seems that the lambdas are initialized lazily.
Could anyone please explain this behaviour or give me a hint on how I would accomplish my goal properly?
Thanks in advance
Shadow testname
with another wrapper function:
def assertion(testname=testname):
def function(self):
return self.assertTrue(testname in globals()) and issubclass(getattr(globals(), testname), TestCase))
return function
setattr(Test_TestCases, "test_%s_is_tested" % item, assertion())