请求入参data参数化替换,数据库前置处理:setup_sql

import re
import time
import uuid
import ast
from api.conf.setting import user_info
from api.tools.handle_attribute import HandleAttr
from api.tools.handle_phone import HandlePhone
from api.conf.setting import get_mobile_code_sql
from api.tools.handle_faker import HandleFake
from api.tools.handle_db import mysql
"""
核心功能:
# 相当于jmeter中从文件读取数据,放到请求中进行参数化
# 相当于jmeter中正则表达式替换#号中的变量#(\w.+?) 参数化
   \w小写的字母和数字 +?贪婪模式 ()分组匹配
   (.*?)万能匹配
# 读取数据库参数化,jmeter读取数据库
# 相当于jmeter中的函数表达式str(uuid.uuid4()))生成变量
# extract_data响应结果提取token,相当于jmeter设置全局变量,jsonpath进行参数化
# excel中的setup_sql相当于jmeter中的前置处理器
# excel中的assert_db相当于jmeter中的后置处理器
"""
class HandleReplace:
    def __init__(self):
        # 实例化faker类,生成不重复的电话号码,用于注册
        self.handle_phone = HandlePhone()
        # 随机生成手机号
        # self.handle_phone = HandleFake()

    # 删除换行符和空格 data:str给变量data制定数据格式,好处,可以使用制定格式的方法
    def __delete_space_wraps(self, data: str):
        """
        :param data:excel中获取的请求参数
        :return: 去掉空格和换行符的请求参数
        """
        for str_data in [" ", "\n"]:
            data = data.replace(str_data, "")
        return data
    # 获取需要替换的参数名称
    def __get_replace_key(self, data):
        """
        :param data: #中需要替换的变量
        :return: ['user_name', 'passwd', 'sessionUUID']
        """
        # 正则表达式替换#号中的变量 \w小写的字母和数字 +?贪婪模式 ()分组匹配
        # (.*?)万能匹配
        key_list = re.findall("#(\w.+?)#", data)
        # key_list_2 = re.findall("#(.*?)#", data)
        # print(key_list)
        return key_list

    # 根据数据的来源,获取数据,设置为类属性,往这里添加属性名称和值,传进来的key是属性名称,传入的user_info是配置文件中的字典类型
    # data参数化处理替换,数据源(配置文件user_info读取,函数生成)
    def __get_data_and_set_attribute(self, key: str, user_info: dict):
        # 相当于jmeter中从文件读取数据,放到请求中进行参数化
        # 获取需要替换的参数,来源不相同的数据,统一设置为类属性
        # user_info来源配置文件:user_info["username"]["password"]
        # 取值变量,通过脚本生成:'sessionUUID'
        # 参数化取值来源:响应结果提取token
        # 参数化取值来源数据库:mysql查询语句
        # key取数来源:通过正则获取的key_list循环获取属性['user_name', 'passwd', 'session_uuid']
        if key in user_info:  # 如果key属性在配置文件user_info字典中['user_name', 'passwd']
            # 取出来设置为类属性,给HandleAttr类添加属性
            # key['user_name', 'passwd', 'session_uuid'],通过key设置为属性,拿也通过key拿
            setattr(HandleAttr, key, str(user_info[key]))
        # key为脚本生成['session_uuid']
        # 相当于jmeter中的函数表达式
        elif key == "session_uuid":
            # 特殊处理,通过脚本生成:session_uuid
            setattr(HandleAttr, key, str(uuid.uuid4()))
        # 添加产品的唯一字段partCode,单独处理  或者支付回调bizPayNo
        elif key == "partyCode" or key == "partyCode":  # 后续接口无需传入partyCode
            # 如果partyCode属性存在类属性中
            if hasattr(HandleAttr, key):
                pass
            else:  # 不在内属性中
                setattr(HandleAttr, key, int(time.time() * 1000))
        elif key == "mobile":  # 判断入参是否为电话号码
            if hasattr(HandleAttr, key):
                pass
            else:  # 不在内属性中  mobile : 15217890987
                # setattr(HandleAttr, key, self.handle_phone.get_phone())
                setattr(HandleAttr, key, self.handle_phone.get_phone())
        # 支付回调的唯一字段bizPayNo,单独处理
        elif key == "bizPayNo":  # 后续接口无需传入partyCode
            # 如果partyCode属性存在类属性中
            if hasattr(HandleAttr, key):
                pass
            else:  # 不在内属性中
                setattr(HandleAttr, key, int(time.time() * 1000))
        # elif key == "valid_code":  # 将短信验证码设置为内属性
        #     if hasattr(HandleAttr, key):
        #         pass
        #     else:  # 不在内属性中  mobile : 15217890987
        #         # 获取短信验证码,设置为内属性
        #         valid_code = self.__get_valid_code()
        #         setattr(HandleAttr, key, valid_code)
    # 通过查询数据库获取数据,然后设置为内属性,相当于jmeter后置处理,处理excel中的assert_db
    def __execute_sql_and_setattr(self, sql):  # key:mobile_code
        # # 获取mobile获取注册手机号
        # self.mobile = str(getattr(HandleAttr, "mobile"))
        # # 通过配置文件读取需要替换的sql
        # sql = get_mobile_code_sql["sql"].format(self.mobile)
        # # 调用handle_db中的get_data查询数据,返回列表value值
        # 调用sql执行方法,获取到数据result以列表嵌套字典形式显示
        result = mysql.get_data_dict(sql=sql)
        # 三元运算将字符串转换为dict格式
        # 循环列表得到字典dict_data
        for dict_data in result:
            # dict.items()以列表返回可遍历的(键, 值)
            for key, value in dict_data.items():
                # 拿到数据并设置为属性
                setattr(HandleAttr, key, str(value))
    # 调用数据来源执行sql,设置属性方法,设置类属性(类似于jmeter中的前置处理器),处理excel中的setup_sql,处理data参数化,设置为类属性
    def __set_attribute(self, key_list, setup_sql):
        """
        :param key_list: ["user_name","session_id"]
        :param setup_sql: 接口执行前,需要通过sql查询来获取替换数据,可以兼容多条
        :return:
        """
        # 如果excel中setup_sql字段存在
        if setup_sql:
            # 将读取出来的字符串,转换为列表,然后遍历列表,循环读取数据,列表兼容多条sql语句,用","隔开即可
            for sql in ast.literal_eval(setup_sql):
                # 通过replace_sql方法将#mobile#进行替换
                new_sql = self.replace_sql(sql=sql)
                # 执行sql语句,并设置为属性
                self.__execute_sql_and_setattr(sql=new_sql)
        else:
            print(setup_sql)
        for key in key_list:  # key属性名称,只对excel请求参数进行属性设置,相当于jmeter后置处理
            # key_list列表中的key属性名称设置为类属性
            # 通过脚本生成的数据
            # 响应数据
            # 数据库
            self.__get_data_and_set_attribute(key=key, user_info=user_info)
    def replace_data(self, data, setup_sql):  # 替换请求参数:data,前置处理:setup_sql参数化替换,读取sql数据生成类属性
        """
        思路:
        1、传入请求参数
        2、删除请求参数中的换行符和空格
        3、获取需要替换的参数名称:通过正则表达式返回list[]
        4、每一个方法实现某一个功能
        5、通过参数名称获取参数的值:统一设置为类属性
        6、将参数的值替换掉参数名称和#号
        :param data :str类型,excel中读取到的请求参数data
        :return:
        """
        if data:
            # 将data中的数据去除空格和换行,返回类型str
            new_data = self.__delete_space_wraps(data=data)
            # print(new_data)
            # 正则获取需要替换的参数名称,返回类型list ["mobile","mobile_code"}]
            key_list = self.__get_replace_key(data=new_data)
            # print(key_list)
            # 如果key_list列表为非空,需要做参数替换
            if len(key_list) > 0:
                # 调用set_attribute方法将key_list,setup_sql设置为类属性
                self.__set_attribute(key_list=key_list, setup_sql=setup_sql)
                for key in key_list:
                    new_data = new_data.replace(f"#{key}#", str(getattr(HandleAttr, key)))
              # 将new_data字符串转化为dict类型,可以使用ast.literal_eval()进行安全地转换。
                new_data = ast.literal_eval(new_data)
                # 将new_data中的t添加value值时间戳
                if "t" in new_data:
                    new_data["t"] = int(time.time() * 1000)
                else:
                    pass
                return new_data
            else:
                print("无需替换数据")
             # 将new_data字符串转化为dict类型,可以使用ast.literal_eval()进行安全地转换。
                new_data = ast.literal_eval(new_data)
                # 将new_data中的t添加value值时间戳
                new_data["t"] = int(time.time() * 1000)
                return new_data
        else:
            print("没有data传参,无需替换参数,请求为get")
            return {}
    # 替换查询mysql语句中的参数,替换assert_db请求参数,从类中读取属性key数据value值,替换##中的数据
    def replace_sql(self, sql: str):  # sql:通过excel中的assert_db读取  assert_db_info:通过setting配置文件读取
        # 获取需要替换的参数名称,返回类型list
        key_list = self.__get_replace_key(data=sql)  # key_list等于["file_path"]
        if len(key_list):  # 如果key_list需要替换的数据不为空
            # 获取key的值,将其设置为类属性(作用是什么?)
            # for key in key_list:
            #     self.__get_data_and_set_attribute(key=key, user_info=assert_db_info)
            for key in key_list:
                # 数据来源excel读取,从类中读取属性key数据value值,替换##中的数据
                sql = sql.replace(f"#{key}#", str(getattr(HandleAttr, key)))
            return sql
        else:
            print("查询mysql语句中的参数为空,无需进行替换")
            return sql
if __name__ == '__main__':
    data = '{\n "t": "",\n "principal": "#user_name#",\n "credentials": "#password#",\n "sessionUUID":"#session_uuid#",\n "imageCode": "lemon"\n}'
    cl = HandleReplace()
    data = cl.replace_data('{\n "t": "",\n "principal": "#user_name#",\n "credentials": "#password#",\n "sessionUUID":"#session_uuid#",\n "imageCode": "lemon"\n}')
    print(data)

 

posted on 2020-03-21 11:17  诚实的表达自己  阅读(284)  评论(0编辑  收藏  举报