如何在结合ddt.idata的unittest中单独运行指定测试方法?
问题描述
使用ddt库的@idata装饰器为unittest测试类的方法提供数据驱动后,无法通过常规方式(命令行指定TestClass.test_xxx或向unittest.main()传参)单独运行某个被装饰的测试方法,执行命令时会抛出AttributeError: type object 'ExampleTest' has no attribute 'test_02'错误。
示例代码:
#!/usr/bin/env python3 import unittest import sys from ddt import idata, ddt test_data_01 = [ ["example1", "example2"], ["example3", "example4"], ] test_data_02 = [ ["other1", "other2"], ] @ddt class ExampleTest(unittest.TestCase): @idata(test_data_01) def test_01(self, params): print(params) @idata(test_data_02) def test_02(self, params): print(params) if __name__ == "__main__": sys.stdout = sys.__stdout__ unittest.main()
命令行执行报错:
bash-3.2$ /usr/bin/python3 ./ddt_problem.py ExampleTest.test_02 Traceback (most recent call last): File "./ddt_problem.py", line 31, in <module> unittest.main() File "/usr/python3.6/lib/python3.6/unittest.py", line 1296, in __init__ self.parseArgs(argv) File "/usr/python3.6/lib/python3.6/unittest.py", line 1349, in parseArgs self.createTests() File "/usr/python3.6/lib/python3.6/unittest.py", line 1353, in createTests self.module) File "/usr/python3.6/lib/python3.6/unittest.py", line 659, in loadTestsFromNames testCase = self.loadTestsFromName(name, module) File "/usr/python3.6/lib/python3.6/unittest.py", line 626, in loadTestsFromName obj = getattr(obj, part) AttributeError: type object 'ExampleTest' has no attribute 'test_02'
解决方法
方法1:直接指定ddt生成的测试方法名
ddt装饰器会将原测试方法拆分为多个独立测试方法,命名规则为原方法名_数据索引(索引从0开始)。比如test_02对应1组数据,生成的方法名为test_02_0,直接在命令行指定这个生成后的方法名即可:
/usr/bin/python3 ./ddt_problem.py ExampleTest.test_02_0
如果不确定生成的方法名,可先完整运行一次测试,控制台输出的测试用例名称就是可直接指定的名称。
方法2:通过unittest.TestLoader筛选测试用例
在脚本中自定义测试套件,筛选出包含目标原方法名的所有测试用例后执行:
if __name__ == "__main__": sys.stdout = sys.__stdout__ loader = unittest.TestLoader() # 加载整个测试类的所有用例 full_suite = loader.loadTestsFromTestCase(ExampleTest) # 筛选出包含'test_02'的测试用例 target_suite = unittest.TestSuite() for test_case in full_suite: if 'test_02' in test_case._testMethodName: target_suite.addTest(test_case) # 运行筛选后的用例 unittest.TextTestRunner(verbosity=2).run(target_suite)
运行脚本时无需额外命令行参数,直接执行即可只运行test_02对应的所有数据驱动用例。
方法3:修改unittest.main的defaultTest参数
直接在unittest.main()中传入defaultTest参数,指定目标测试的标识:
if __name__ == "__main__": sys.stdout = sys.__stdout__ # 指定运行test_02对应的所有生成用例 unittest.main(defaultTest=['ExampleTest.test_02'])
注:部分unittest版本可能需要精确指定生成后的方法名(如ExampleTest.test_02_0),如果前缀匹配无效,可改用方法1或方法2。
内容的提问来源于stack exchange,提问作者LetMeSOThat4U
相关产品推荐
相关产品推荐

