使用exec()调用Python单元测试出现‘Ran 0 tests’的原因及解决方法
为什么exec()在类方法中执行单元测试时显示“Ran 0 tests”?
问题根源
你遇到的问题核心是命名空间隔离和unittest的测试发现机制导致的:
当你在FitnessFunction方法内部用exec()运行unitTest1.py时,代码里的TestSum测试类会被加载到方法的局部命名空间里,而unittest.main()默认只会在当前模块(也就是Fitness.py的全局命名空间)里查找TestCase子类——它根本看不到局部命名空间里的测试类,所以才会显示“Ran 0 tests”。
而当你把exec()放在main函数里时,测试类是加载到全局命名空间的,unittest.main()能正常扫描到,所以运行正常。
两种可行的解决方案
方案1:手动加载并执行测试用例(推荐)
绕过unittest.main()的自动发现,从exec的命名空间里手动提取测试类,构建测试套件执行,这样不会污染全局命名空间:
修改你的FitnessFunction方法如下:
import sys import unittest sys.path.append('..') class Fitness: def FitnessFunction(self): # 创建独立的命名空间存储exec执行后的内容 exec_namespace = {} # 读取测试文件内容 with open("D:\\docu\\KL\\Data\\unitTest1.py", 'r', encoding='utf-8') as test_file: test_code = test_file.read() # 在自定义命名空间中执行测试代码 exec(test_code, exec_namespace) # 从命名空间中取出测试类 test_class = exec_namespace['TestSum'] # 加载测试用例到套件 test_suite = unittest.TestLoader().loadTestsFromTestCase(test_class) # 执行测试 test_runner = unittest.TextTestRunner() test_result = test_runner.run(test_suite) if __name__ == '__main__': f = Fitness() f.FitnessFunction()
方案2:将exec的命名空间指定为全局
如果一定要用unittest.main(),可以让exec()把测试类加载到全局命名空间,这样unittest.main()就能扫描到:
import sys import unittest sys.path.append('..') class Fitness: def FitnessFunction(self): with open("D:\\docu\\KL\\Data\\unitTest1.py", 'r', encoding='utf-8') as test_file: test_code = test_file.read() # 在全局命名空间执行测试代码,让测试类被全局可见 exec(test_code, globals()) # 指定unittest.main扫描当前模块的全局命名空间 unittest.main(module='__main__', exit=False) if __name__ == '__main__': f = Fitness() f.FitnessFunction()
⚠️ 注意:这种方法会污染当前模块的全局命名空间,可能引发命名冲突,所以仅在特殊场景下使用。
额外提示
你的mid.py和unitTest1.py里的测试用例本身存在一些逻辑错误(比如test_sum_1断言期望是2,但mid(3,2)实际返回1),不过这属于测试用例的逻辑问题,不影响测试的执行流程。
内容的提问来源于stack exchange,提问作者Phạm Ân
相关产品推荐
相关产品推荐

