unittestreport 数据驱动 (DDT) 的实现源码解析
一、快速使用
在给大家分析源码之前先给大家讲解一下 unittestreport 中的 ddt 如何使用!unittestreport.dataDriver 模块中实现了三个使用方法,支持使用列表(可迭代对象)、JSON 文件、YAML 文件来生成测试用例,这边给大家介绍一下使用方法:
1、模块导入
from unittestreport.dataDriver import ddt, list_data
2、使用案例
from unittestreport import ddt, list_data@ddtclass TestClass(unittest.TestCase): cases = [{'title': '用例1', 'data': '用例参数', 'expected': '预期结果'}, {'title': '用例2', 'data': '用例参数', 'expected': '预期结果'}, {'title': '用例3', 'data': '用例参数', 'expected': '预期结果'}] @list_data(cases) def test_case(self, data): pass
第三步:运行上面用例文件,就会发现执行了三条测试用例
第一步:使用 ddt 装饰测试用例类
第二步:根据使用的数据选择对应的方法进行驱动
二、源码分析
在上面的使用案例中我们使用了一个 ddt 的装饰器去装饰测试用例类,一个 list_data 的装饰器去装饰测试用例方法。
1、ddt
在上面的用例类前面我们用了一个@ddt 这行代码的作用到底是什么呢?
# @ddt这个是装饰器的语法,这行代码的作用等同于 TestClass = ddt(TestClass)
我们来看一下 ddt 里面的源码
def ddt(cls): for name, func in list(cls.__dict__.items()): if hasattr(func, "PARAMS"): for index, case_data in enumerate(getattr(func, "PARAMS")): # 生成用例名称, new_test_name = _create_test_name(index, name) # 生成用例描述 if isinstance(case_data, dict) and case_data.get("title"): test_desc = case_data.get("title") elif isinstance(case_data, dict) and case_data.get("desc"): test_desc = case_data.get("desc") else: test_desc = func.__doc__ func2 = _update_func(new_test_name, case_data, test_desc, func) setattr(cls, new_test_name, func2) else: delattr(cls, name) return cls
从上面的源码我们可以看出来,把测试类当成参数传入 data 之后,在内部做了一系列操作之后将测试类返回了出来。这一系列操作其实就是根据测试用例数据,创建测试用例方法添加到测试类中,代码中重要步骤如下图描述所示。
对于上面遍历,判断方法是否拥有 PARAMS 属性,这个 PARAMA 属性是怎么来的呢?PARAMA 属性是@list_data(cases)的时候添加的,接下来我们来看一下 list_data 的源码
评论:0
点赞:0
阅读: