根据装饰器手写ddt实现原理(提升对装饰器理解)

2022-11-23  本文已影响0人  测试探索

一:浅谈ddt

@ddt装饰器装饰类,@data装饰器装饰用例方法并传入测试数据。
@data:做的是第一步,将传入测试数据保存起来
@ddt:第二步,遍历用例数据,给测试类动态添加用例方法


image.png

二、装饰器实现

import pprint
# ==================v2通过装饰器实现,根据数据给类动态添加方法==============
def parameter(cls):
    # 在装饰器内部,给cls类动态添加方法
    # todo:数据不能在装饰器内部写死,需要优化
    # todo:获取类里面原有的方法(不能写死,需要优化)
    # 如何  动态去获取测试方法(在测试类中通过给测试方法加上装饰器对方法做标记)
    # 1、先获取测试类所有的属性和方法,然后遍历,判断是否拥有is_test属性
    attrs = list(cls.__dict__.items())
    print("这里获取的结果:", attrs)
    for name, value in attrs:
        if hasattr(value, "is_test"):
            cases = getattr(value, "params")
            method = value
            print("这里就是需要的结果", name, value, method.__dict__)
            for index, item in enumerate(cases):
                new_name = "{}_{}".format(name, index)

                def create_test_method(method, item):
                    # 定义一个函数作为测试方法
                    def test_method(self):
                        # 调用原来的方法并传入
                        method(self, item)

                    return test_method

                # 给类动态添加方法
                setattr(cls, new_name, create_test_method(method, item))
            else:
                delattr(cls, name)

    return cls

def data(datas):
    def mark(func):
        # 给被装饰的函数添加is_test属性
        func.is_test = True
        # 将数据datas保存为方法的属性
        func.params = datas
        return func
    return mark


@parameter #TestDemo = parameter(TestDemo)
class TestDemo:
    cases1 = [
        {"title": "用例1", "data": 1111},
        {"title": "用例2", "data": 2222},
        {"title": "用例3", "data": 3333},
    ]

    cases2 = [
        {"title": "login2用例1", "data": 1111},
        {"title": "login2用例2", "data": 2222},
        {"title": "login2用例3", "data": 3333},
        {"title": "login2用例4", "data": 4444}
    ]

    @data(cases1)
    def test_login(self,item):
        pass
        print("结果是:",item)

    @data(cases2)
    def test_register(self,item):
        pass

pprint.pprint(TestDemo.__dict__)
image.png
上一篇下一篇

猜你喜欢

热点阅读