测试用例框架优化(二)

不知道大家还记不记得,我们前面跟大家分享了测试用例框架优化(一)内容过程当中,还遗留了第三个问题:

第三个问题:关于字段替换的地方,当我们接口用例很多很多,上千条时候,一个一个的替换,你能确保你每个字段都替换了吗?

而且上百上千个接口一个一个替换也会显得比较麻烦。

现在抽空总结了以下继续分享出来:

我是对   正则表达式提取标识符后替换的过程封装成了一个方法:

我们创建一个替换的py文件:

——解决的问题:在编写测试用例时,用例涉及到的所有mark标识符(#...#)都能够替换成功

 

 

 注意:

我们这里只是简单定义了一个函数,大家也可以定义成类,因为我们现在的功能比较少,如果说
你有更多的用法,像之前我们封装的requests 方法,实际上我们只有def send_requests(self,method,api_url, data,token=None):
是对外用的,但是里面有一些逻辑处理,我们就把它封装成了类,把一些步骤定义成私有方法处理,
所以道理是一样的,如果你未来你的项目替换有很多种情况,你可能需要扩充这里那里,如果你不喜欢
这个函数写的太长,你也可以像requests 封装一样写成一个类,对外的方法只有一个,其他的都是私有方法,你直接
调用就可以,思想是一致的。


import re
from common.my_data import Data
from common.mylogger import logger
from common.handle_phone import get_new_phone

def
replace_case_with_re(case_dict): """ :param case_dict: 从excel当中是读取出来的一行测试数据。为字典形式。 :return: 替换之后的测试数据。类型为字典。 """ # 第一步,把excel当中的一整个测试用例(excel当中的一行)转换成字符串 case_str = str(case_dict) # 第二步,利用正则表达式提取mark标识符 to_be_replaced_marks_list = re.findall("#(\w+)#", case_str) # 第三步:遍历标识符mark,如果标识符是全局变量Data类的属性名,则用属性值替换掉mark if to_be_replaced_marks_list: logger.info("要替换的mark标示符有:{}".format(to_be_replaced_marks_list)) """ 上面的if :if to_be_replaced_marks_list: 只是将Data类里面的标识符替换进来了,我们 之前注册的时候还用到了"#phone#" 需要替换,这个也是我们在发起请求之前需要做处理的, 所以我们应该是需要全部做处理的,不应该漏掉,因为我们Data里面是没有这个属性的,所以替换 不了,那怎么办?所以我们用来替换的数据不一定都是来自响应结果当中提取的,也有可能来自与脚本生成 (比如phone),或者是配置文件,这些不在响应结果里面,但是我们这个框架Data 只是封装了响应结果的数据 而且我们这个框架只有一个phone 是特殊情况需要特殊处理。 ——解决方法: 写一个if 判断,判断是否有phone这个标识符,如果有,调用生成手机号码的脚本,然后替换 如果我们业务流多的情况下,也可以重新定义一个方法来处理 """ # 判断是否有phone这个标识符,如果有,调用生成手机号码的脚本,然后替换 if "#phone#" in to_be_replaced_marks_list: new_phone = get_new_phone() logger.info("有#phone#标识符,需要生成新的手机号码: {}".format(new_phone)) case_str = case_str.replace(f"#phone#", new_phone) # 从Data类当中取值来替换标识符。 for mark in to_be_replaced_marks_list: # 如果全局变量Data类有mark这个属性名 if hasattr(Data, mark): logger.info("将标识符 {} 替换为 {}".format(mark, getattr(Data, mark))) # 使用全局变量Data类的mark属性值,去替换测试用例当中的#mark# case_str = case_str.replace(f"#{mark}#", getattr(Data, mark)) logger.info("替换之后的用例数据为: \n{}".format(case_str)) # 第四步:将完全替换后的一整个测试用例,转换回字典 new_case_dict = eval(case_str) #我们替换后的数据是需要下一步使用的,所以这里要返回 return new_case_dict
上面的if :if to_be_replaced_marks_list: 只是将Data类里面的标识符替换进来了,我们
        之前注册的时候还用到了"#phone#" 需要替换,这个也是我们在发起请求之前需要做处理的,
        所以我们应该是需要全部做处理的,不应该漏掉,因为我们Data里面是没有这个属性的,所以替换
        不了,那怎么办?所以我们用来替换的数据不一定都是来自响应结果当中提取的,也有可能来自与脚本生成
        (比如phone),或者是配置文件,这些不在响应结果里面,但是我们这个框架Data 只是封装了响应结果的数据
        而且我们这个框架只有一个phone 是特殊情况需要特殊处理。
        ——解决方法:
                写一个if 判断,判断是否有phone这个标识符,如果有,调用生成手机号码的脚本,然后替换
                
        如果我们业务流多的情况下,也可以重新定义一个方法来处理

 

 

封装完替换方法之后的测试用例代码示例:

import pytest
import os
import json

from common.myConf import MyConf
from common.my_path import conf_dir
from common.my_requests import MyRequests
from common.my_excel import MyExcel
from common.my_assert import MyAssert
from common.mylogger import logger
from common.my_path import testdata_dir
from common.my_data import Data
from common.my_extract import extract_data_from_response
from common.my_replace import replace_case_with_re

# 第一步:读取注册接口的测试数据 - 是个列表,列表中的每个成员,都是一个接口用例的数据。
excel_path = os.path.join(testdata_dir, "测试用例.xlsx")
print(excel_path)
me = MyExcel(excel_path, "充值接口")
cases = me.read_data()

# 第二步:遍历测试数据,每一组数据,发起一个http的接口
# 实例化请求对象
mq = MyRequests()
massert = MyAssert()


class TestRecharge:

    @pytest.mark.parametrize("case", cases)
    def test_recharge(self, case):
        """
        这里我们把之前的替换方式直接去掉,引用进来我们封装好的替换方法就可以
        :param case:
        :return:
        """
        # 1、第一步:替换,找到需要替换就替换,没有就不需要
        case = replace_case_with_re(case)

        # 2、把替换之后的请求数据(json格式的字符串),转换成一个字典
        req_dict = json.loads(case["req_data"])

        # 3、发起请求,并接收响应结果
        if hasattr(Data, "token"):
            resp = mq.send_requests(case["method"], case["url"], req_dict, token=getattr(Data, "token"))
        else:
            resp = mq.send_requests(case["method"], case["url"], req_dict)
        logger.info(resp.json())

        # 结果空列表
        assert_res = []

        # 5、断言响应结果中的数据
        if case["assert_list"]:
            response_check_res = massert.assert_response_value(case["assert_list"], resp.json())
            assert_res.append(response_check_res)

        if False in assert_res:
            pass
        else:
            # 4、提取响应结果中的数据,并设置为全局变量
            if case["extract"]:
                # 调用提取处理函数
                extract_data_from_response(case["extract"], resp.json())

        # 6、断言数据库 - sql语句、结果与实际、比对的类型
        if case["assert_db"]:
            db_check_res = massert.assert_db(case["assert_db"])
            assert_res.append(db_check_res)

        # 最终的抛AsserttionError
        if False in assert_res:
            raise AssertionError

 

posted @ 2022-01-12 19:11  乘风破浪的小落夜  阅读(141)  评论(0编辑  收藏  举报