python替换yaml变量的多种方法以及踩坑

方法1:使用template 替换,变量样式符号为"$“或者”${}"
示例:testxxx.yaml 有以下的请求内容

test_chanel_detail:
   "method": "GET"
   "url": "https://xxxx/info/detail"
   "headers": ${header}
   "params": {
      "partner": ${partner},
      "role": ${role}
      }

yaml加载:
需要安装

pip install pyyaml

class ReadFileData():

    def __init__(self):
        self.BASE_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

    def load_yaml(self, yaml_file_name):
        file_path = os.path.join(self.BASE_PATH, "data", yaml_file_name)
        with open(file_path, encoding='utf-8') as f:
            data=f.read()
            # data = yaml.safe_load(f)
        return data
data = ReadFileData()

yaml替换,一般建议使用safe_substitute安全替换,因为如果你替换的字段如果不存在则会跳过。否在会报错

def yaml_test():
    res_data = data.load_yaml("chanle_data.yaml")
    print("res_data", res_data)
    tempplate1 = Template(res_data)
    tempplate1_replace = tempplate1.safe_substitute({"partner": 22, "role": "23", "header": 23})
    tempplate1_json=yaml.safe_load(tempplate1_replace)
    print(tempplate1_json)
if __name__ == "__main__":
    yaml_test()

safe_substitute结果为

{‘test_chanel_detail’: {‘method’: ‘GET’, ‘url’: ‘https://xxxx/info/detail’, ‘headers’: 23, ‘params’: {‘partner’: 22, ‘role’: 23}}}

替换成功

如果替换为:substitute 则会报错

   "params": {
      "partner": ${partner},
      "role": $role
      }
 tempplate1_replace = tempplate1.substitute({"partner": 22, "header": 23})

报错信息如下

   return str(mapping[named])
KeyError: 'role'

注意的是 需要用$role。如果是 ${role},结果依然也会报错
报错信息为:

expected ',' or '}', but got '{'
  in "<unicode string>", line 7, column 16:
          "role": ${role}

方法2:使用pystache 替换,变量样式符号为"{{}}"

test_chanel_detail:
   "method": "GET"
   "url": "https://xxxx/info/detail"
   "headers": {{header}}
   "params": {
      "partner": {{partner}},
      "role": {{role}}
      }

需要安装

pip install pystache

def yaml_test():
    res_data = data.load_yaml("chanle_data.yaml")
    print("res_data", res_data)
    data1=pystache.render(res_data,{"partner": 22,"role":"434", "header": 23})
    c = yaml.safe_load(data1)
    print(c)`

结果为:

{‘test_chanel_detail’: {‘method’: ‘GET’, ‘url’: ‘https://xxxx/info/detail’, ‘headers’: 23, ‘params’: {‘partner’: 22, ‘role’: 434}}}

踩坑1:自动将字符类型的“ 434 ”强转换数字,在java中,这个影响不大,java也会自动转换整数类型,但在python接口中,如果健壮性写的不好,不做强转换,则会报错

踩坑2:如果你需要变量为空字符""或者空对象"None"赋值时则无法替换。**

{“partner”: “22”, “role”:"",“header”: 23}
结果为:
{‘test_chanel_detail’: {‘method’: ‘GET’, ‘url’: ‘https://xxxx/info/detail’, ‘headers’: 23, ‘params’: {‘partner’: 22, ‘role’: None}}}
{“partner”: “22”, “role”:None,“header”: 23}
结果为:
{‘test_chanel_detail’: {‘method’: ‘GET’, ‘url’: ‘https://xxxx/info/detail’, ‘headers’: 23, ‘params’: {‘partner’: 22, ‘role’: ‘None’}}}

传入空字符,则转为了None,传入了None,则转为了‘None’ str,在接口异常测试中,这样的转换是非常奔溃的。由于模板替换是转换为str然后再正则匹配替换关键字,这样的话,空字符是怎么都无法替换到的。

怎么解决???

可以通过特殊标记做一次二次转换
写个函数,将空字符特意转为null_obejct字符。

def object2null(s):
    new=copy.deepcopy(s)
    for k,v in s.items():
        if ""==v:
            new[k]= "null_obejct"
        if v is None:
            new[k] = ""
    return new
def yaml_test():
    res_data = data.load_yaml("chanle_data.yaml")
    print("res_data", res_data)
    tempplate1 = Template(res_data)
    data1=object2null({"partner": 22, "role": "", "header": 23})
    c = tempplate1.safe_substitute(data1)
    cc=yaml.safe_load(c)
    ccc= str(cc)
    print(eval(ccc.replace("null_obejct",""))) #再次转换为字典

最后空字符跟None问题终于解决。

总结:如果用yaml作为变量替换的话,会有很多意想不到的问题,这个就加大了我们脚本编写难度。就像httprunner 3.x ,作者更多的思想就是将自动化编写会回归代码。

当然最后现实怎么用呢,当然直接写代码了,这样简洁了。

    req={
        "method": "GET",
        "url": "https://xxx/detail",
        "headers": header,
        "params": {
            "partner": partner,
             "role": role}
    }
  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值