I want to load the function into the unit test dynamically, passing code as str
and use exec()
to run them in test.
My current code look like this:
import unittest
class ParametrizedTestCase(unittest.TestCase):
def __init__(self, methodName='runTest', param=None):
super(ParametrizedTestCase, self).__init__(methodName)
exec (param)
self.param = param
@staticmethod
def parametrize(testcase_klass, param=None):
testloader = unittest.TestLoader()
testname = testloader.getTestCaseNames(testcase_klass)
suite = unittest.TestSuite()
for name in testname:
suite.addTest(testcase_klass(name, param=param))
return suite
class TestZero(ParametrizedTestCase):
def test_add(self):
print('param:', self.param)
self.assertEqual(add(1,1), 2)
if __name__ == '__main__':
code = "def add(a, b): return a b"
suite = ParametrizedTestCase.parametrize(TestZero, param=code)
unittest.TextTestRunner(verbosity=2).run(suite)
and this is current out put:
❯ python test/test0.py
test_add (__main__.TestZero) ... param: def add(a, b): return a b
ERROR
======================================================================
ERROR: test_add (__main__.TestZero)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test/test0.py", line 21, in test_add
self.assertEqual(add(1,1), 2)
NameError: name 'add' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Is it possible to do that and if so, how?
CodePudding user response:
exec
with no additional parameters is defining add
in the local scope of ParameterizedTestCase.__init__
; once that function complete, add
goes out of scope.
One solution is to put add
in the global scope, so that it's accessible.
exec(param, globals())
However, in general you aren't going to know what name (or names) the execution of param
will make available for future tests.