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.
