用例步骤的数据驱动

小白  初识博客园~~

记录下自动化测试一些值得注意的点

-----------------------------------------------------------

数据驱动:

脚本与数据分离的模式增强了对代码的复用,初学者都是沉迷使用python框架中自带的装饰器@ddt.data 、@pytest.mark.parametrize

最近看了些相关资料,除了用例数据的数据驱动,还有用例步骤的数据驱动、配置的数据驱动

我想说的是后者,实话拿着github代码的思路,自己封装了一遍

以下是原始代码

   @pytest.mark.parametrize("name", file['data'], ids=['用例1', '用例2', '用例3'])
    @assert_logger
    def test_tagsave(self, name):
# 环境清理
# 步骤1: 调用接口获取标签列表
self.vip.taglist(pagesize=10, pageindex=1, querytype=1, tagname=f"{name}") # 步骤2: 调用rjsonpath提取tagid
tagidsdata
= self.vip.rjsonpath(f"$.data[?(@.name == '{name}')]") if tagidsdata is not False:
        # 步骤3:调用接口删除已存在的tagid
            self.vip.tagdelete(tagid=tagidsdata[0]['id'])
        
# 步骤4:调用新增标签接口测试
r = self.vip.tagsave(name=f"{name}", type=1, ruletext=None)
# 步骤5: 断言新增标签
assert r.success is True

# 步骤6:调用列表接口、删除接口清理环境
r = self.vip.taglist(pageindex=1, pagesize=10, querytype=1, tagname=f"{name}") tagid = self.vip.rjsonpath(f"$.data[?(@.name == '{name}')]")[0]['id'] r = self.vip.tagdelete(tagid=tagid)

 

从上面的代码看来,一条新增标签接口的测试用例由不同的接口依次调用进行测试,正是我们测试人口中经常提起的业务测试。

    @pytest.mark.parametrize("name", file['data'], ids=[1, 2, 3])
    @assert_logger
    def test_tagsave_steps(self, name):
        self.vip.params = {"name": name}
        self.vip.steps_run(self.file['steps'])

从上可见,一行代码就能把业务封装,我i们只需要着手写去对应的 file就可以了

而file得形式不拘泥于excel、json、yaml,甚至是py文件(我个人比较喜欢yaml形式,深受httprunner工具得毒害~,听说它又改为py文件了,确实yaml很难找到格式错误之处)

看着这份yaml文件,明白了原来关键字驱动也就是这么回事~,操作与业务分离,操作生成代码,高级一点的数据驱动

以下file文件,yaml 和 steps_run方法

data: ["测试", "高级测试", "测试开发"]

steps:
- {method: vip.taglist, pagesize: 10, pageindex: 1, querytype: 1, tagname: '${name}'}
- {path: "$.data[?(@.name == ${name})]", extract: tagid, conditions: "['id']"}
- {method: vip.tagdelete, tagid: "${tagid}"}
- {method: vip.taglist, pagesize: 10, pageindex: 1, querytype: 1, assertext: result1}
- {method: vip.tagsave ,name: "${name}", type: 1, ruletext: None}
- {assertion: ["res['msg']", eq, 'ok']}
- {method: vip.taglist, pagesize: 10, pageindex: 1, querytype: 1, tagname: '${name}'}
- {path: "$.data[?(@.name == ${name})]", extract: tagid, conditions: "['id']"}
- {method: vip.tagdelete, tagid: "${tagid}"}
- {method: vip.taglist, pagesize: 10, pageindex: 1, querytype: 1, assertext: result2}
- {assertion: [result1, eq, result2]}

 

class KDT:
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(KDT, "_instance"):
            KDT._instance = object.__new__(cls)
        return KDT._instance

    def start(self, objec, params: dict, data: dict, steps):
        for step in steps:
            raw = yaml.dump(step)
            templatel = Template(raw)
            print(params.update(data))
            step = yaml.safe_load(templatel.safe_substitute(dict(params, **data)))
            for oprerate in [i if isinstance(step, dict) else Exception(f"请检查参数替换{step}") for i in step.keys()]:
                if oprerate in self.__dir__():
                    getattr(self, oprerate)(objec, data, step)

    def method(self, objec, data, step):
        method = step['method'].split('.')[-1]
        if "$" in str(step):
            raise Exception(f"请检查参数替换{step}")
        res: ResultBase = getattr(objec, method)(**step)
        data['res'] = res.res
        if step.get("assertext", False):
            data[step['assertext']] = res.res

    def extract(self, objec, data, step):
        step_value = getattr(objec, "rjsonpath")(**step)
        if isinstance(step_value, list):
            step_value = step_value[0]
        if step.get("conditions", False):
            if isinstance(step_value, str):
                step_value = json.loads(step_value)
            if step_value is not False:
                step_value = eval("step_value" + str(step['conditions']))
            else:
                print(f"提取参数失败,参数如下:{step}")
            data[step['extract']] = step_value

    def assertion(self, objec, data, step):
        assertion = step['assertion']
        if isinstance(assertion, str):
            assert eval(assertion)
        if assertion[1] == 'eq':
            if data.get(repr(assertion[0])) is not None:
                assert data[repr(assertion[0])] == data[repr(assertion[2])]
            elif 'res' in str(assertion):
                res = data.get('res')
                # assert eval(assertion[0]) == assertion[2]
                pass

 

posted @ 2021-01-14 14:09  半城风雨  阅读(258)  评论(0)    收藏  举报