如何动态加载函数以使用 exec() 测试单元?

How to dynamically load a function to test unit with exec()?

我想将函数动态加载到单元测试中,将代码作为 str 传递,并在测试中使用 exec() 到 运行 它们。

我当前的代码如下所示:

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)

这是当前输出:

❯ 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)

是否可以这样做,如果可以,怎么做?

没有附加参数的

execParameterizedTestCase.__init__ 的局部范围内定义 add;一旦该功能完成,add 超出范围。

一个解决方案是将 add 放在全局范围内,以便可以访问。

exec(param, globals())

但是,通常您不会知道 param 的执行将使哪些名称(或多个名称)可用于将来的测试。