【接口自动化框架】测试数据部分增加替换变量功能

我们的接口自动化框架的测试数据放到json文件中,

但是有些参数是动态生成的(例如随机字符串);有些参数可以进行再次提取,放在config文件里(例如host,URL,accountid等等);

解决这个问题我想到两个解决方法:

1,在测试case的python文件中生成变量后再赋值给json文件中的变量(缺点:重复代码多)

2,在json文件中直接引用函数 or 变量名称,在case读取json文件时,替换变量(此文重点介绍这种方法

进入正题,第一步:替换变量。

首先介绍一下我的测试数据是放在json文件里的,形式如下;比如像host,uri,account_id 是需要替换的

"test": [
    {
      "tag":"test render string",
      "case": "测试如何替换测试参数",
      "http": {
        "host": "1",
        "uri": "1",
        "method": "POST",
        "headers": {
          "Content-Type": "application/x-www-form-urlencoded"
        },
        "params": {
          "region": "cn",
          "lang": "zh-cn",
          "app_id": "10001",
          "nonce": "${generate_random_digits()}"
        },
        "data": {
          "account_id": "{user.owner.account_id}"
          "mobile":"{user.owner.mobile}"
        }
      },
      "expected": {
        "response": {
            "result_code": "success",
},
        "database": {},
        "kafka": {}
      }}
]
    }

第二步:

我们把例如account_id这种数据放在config文件夹下,可以存放为yaml活着json都可以;只要读取数据出来的形式是字典就行

cache = {
"VARIABLES":{
    "user":{
        "owner":{
            "account_id":"test123",
            "mobile": "13677777777"
    }
    }}

}

至此,需要替换的数据是第一步读取的;要替换的target数据是第二步读取的

第三步:编写render函数进行数据替换,这里替换的是变量

import logging
import re

p = '''{
    "test": [
    {
      "tag":"test render string",
      "case": "测试如何替换测试参数",
      "http": {
        "host": "1",
        "uri": "1",
        "method": "POST",
        "headers": {
          "Content-Type": "application/x-www-form-urlencoded"
        },
        "params": {
          "region": "cn",
          "lang": "zh-cn",
          "app_id": "10001",
          "nonce": "${generate_random_digits()}"
        },
        "data": {
          "account_id": "{user.owner.account_id}"
          "mobile":"{user.owner.mobile}"
        }
      },
      "expected": {
        "response": {
            "result_code": "success",
},
        "database": {},
        "kafka": {}
      }}
]
    }'''

cache = {
"VARIABLES":{
    "user":{
        "owner":{
            "account_id":"1559759948",
            "mobile": "98762424749"
    }
    }}

}

varial_matcher = re.compile(
    r"\{([\w.]+)\}"
    r"|\$\{([\w.]+)\}"  # 匹配$开头并{}包括的变量
)

def render(p, cache):
    # 替换变量
    if isinstance(p, str) and varial_matcher.findall(p):
        variables_list = []
        try:
            for var_tuple in varial_matcher.findall(p):
                variables_list.append(
                    var_tuple[0] or var_tuple[1]
                )
            for items in variables_list:
                items_list = items.split('.')
                target_data = cache.get("VARIABLES")
                for i in items_list:
                    target_data = target_data.get(i, {})
                if target_data != {}:
                    p = p.replace('${', '{').replace("{" + items + "}", str(target_data))
            return p

        except Exception as e:
            logging.error(e)
            logging.error(p)

print(render(p, cache))

第四步:在测试数据的json文件中还有这种

"nonce": "${generate_random_digits(2)}"

引用函数的,需要替换成引用函数后的结果;怎么做呢?和步骤三大同小异

func_matcher = re.compile(
    r"[\$]{1}[\{]{1}"  # 可以匹配${}的函数
    r"([0-9a-zA-Z_.=]+)"  # 匹配函数名称可以包含.
    r"[ ]*"  # 函数方法名称后0或多个空格
    r"\((.*)\)"  # 匹配函数参数
)

def render(p, cache):
# 替换函数
    if isinstance(p, str) and func_matcher.findall(p):
        for fn_tuple in func_matcher.findall(p):
            fun, varials = fn_tuple[0], fn_tuple[1]
            fnc_map = cache.get("FUNCS")
            try:
                fn_raw = "{fun}({varials})".format(fun=fun, varials=varials)
                fn = "{fun}({varials})".format(fun=fun, varials=varials)
                target_data = eval(fn, fnc_map)
                p = p.replace('${', '{').replace("{" + fn_raw + "}", str(target_data))
            except (ModuleNotFoundError, ImportError) as e:
                logging.warning("函数没找到或者导入失败", p, cache)
            except NameError as e:
                logging.warning("err", e)
    return p

print(render(p, cache))

但是在这步前要再自行加一步,就是在cache的数据中,加入我们写好的FUNC参数,以及我们需要替换的函数文件

比如 我的替换函数文件:

#我的func_tools文件
def generate_random_digits(num):
    return str(round(random.uniform(-90, 90), num))

就是在cache的数据中,加入我们写好的FUNC参数

cache["FUNCS"] = load_func_tools("func_tools")
def load_func_tools(module):
    try:
        module_functions = {}
        module = import_module(module)
        if module:
            for name, item in vars(module).items():
                    if isinstance(item, types.FunctionType):
                        module_functions[name] = item
        return module_functions
    except Exception:
        return {}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值