前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于python的Json容错数据自动化输出

基于python的Json容错数据自动化输出

作者头像
用户5521279
发布2020-05-24 10:52:18
1.5K0
发布2020-05-24 10:52:18
举报
文章被收录于专栏:搜狗测试搜狗测试

前言

测试工作中往往需要对服务端所返回的Json数据做容错,即需要确保原数据中各项值被替换成异常数据类型时,相关数据传输与处理系统不会发生报错、崩溃等问题。

若手动编写容错数据,小编认为有以下两点弊端:

1. 繁琐操作带来的人力、时间成本消耗;

2. 可能因数据繁多而导致疏漏;

因此希望实现能够根据待测试Json数据,一键输出全部相关容错数据文件的脚本。

概述

开始代码实现之前希望能够明确思路,小编经过思考,确立脚本实现环节如下:

1. 获取key

获取Json中所有需做数据替换处理的元素标识(如Json对象中的各个key);

2. 定位value

根据获取到的标识,定位到需修改的值(如key对应的value);

3. 替换与输出

将每个值进行数据替换并输出为各式容错数据文件。

实现方案

1. 获取key

以这样一份基本包含各式数据的Json为例

{
  "testDict":{
  "testDict_1_string":"1_value",
  "testDict_2_int":1,
  "testDict_3_bollen":false,
  "testDict_4_list":["4_value",1],
  "testDict_5_null":null,
  "testDict_6_dict":{"6_key":{"6_key_1":"6_value_1"}, "6_list":["test_list"]},
  "testDict_7_complex":[
    {
      "id":"10000",
      "testA":{"A":"A_value"},
      "testB":["B1","B2"]
      },
      {
        "id":"10001",
      "testC":{"C":"C_value"},
      "testRepeat":"R_value"
      },
      ["testX", "testY", {"testRepeat":"testRepeat"}],
      ["test_list_2"],
      "7_value"
    ],
  "testRepeat":"R_value"
  },
  "testRepeat":"R_value",
  "test_extra":["test_extra_value"]
}

小编尝试通过对其进行递归处理进行key的获取,并辅以这样几点思考:

1. 针对数据中字典形式的json对象、列表形式的json数组,需不同的处理方法;

2. 为避免重复key混淆,需使用数据链路结构进行区分,如“父级key—子级key—子级key”;

3. 为避免链路结构同key产生混淆,需使用特殊符号进行层级链接。

4. 为避免多重数组导致数据链路结构重复,需额外添加”inlist”标识。

代码如下:

def getKeyFromJsonFile(dic_json, keylist, keyParent=None, isChild=False, listInlist=False):
  # 如果获取到的数据类型为dict,则遍历字典的key来获取value数据类型
  if isinstance(dic_json, dict):
    for key in dic_json:
      # 根据value数据类型做不同处理并递归
      if isinstance(dic_json[key], dict):
        # 拼接节点路径并插入列表
        if isChild:
          key = keyParent + '-*-' + key
        keylist.append(key)
        getKeyFromJsonFile(dic_json[key.split('-*-')[-1]], keylist, keyParent=key, isChild=True, listInlist=False)
      elif isinstance(dic_json[key], list):
        if isChild:
          key = keyParent + '-*-' + key
        keylist.append(key)
        for i in dic_json[key.split('-*-')[-1]]:
          getKeyFromJsonFile(i, keylist, keyParent=key, isChild=True, listInlist=False)
      else:
        # 列表内的key可能和列表内列表的key结构重复
        # 仅处理一层,再深层缺乏实际意义
        if listInlist:
          key = key + '_*inlist'
        if isChild:
          key = keyParent + '-*-' + key
        keylist.append(key)
  # 针对[...]中包含[...]需再次递归
  if isChild and isinstance(dic_json, list):
    for i in dic_json:
      getKeyFromJsonFile(i, keylist, keyParent=keyParent, isChild=True, listInlist=Tru

2. 定位value

小编尝试将每个key值以链接符号-*-进行分割为列表,并于Json数据中逐级进行找寻、定位,此时对这样两种情况进行了考虑。

若key值对应的value类型并非列表,则位于链路末端的key值对应的value即是需要修改的值:

def getValue(slist, data_next):
  # 遍历分割后的key参数
  for j in range(0 ,len(slist)):
    # 当前key对应的数据类型是list
    if isinstance(data_next[slist[j]], list):
      return
    # 并非列表
    if j == len(slist)-1:
      # 得到需要修改的值
      value = data_next[slist[j]]
      return
    # 每次节点路径的循环中在下一级字典中检索
    data_next = data_next[slist[j]]

而列表内元素无法根据key值定位,直接定位到列表后续进行遍历即可:

def getValueFromList(data_list, key_list):
  # 列表中元素数据类型为字典
  if isinstance(data_list, dict):
    for key in key_list:
      # 在字典中由传入的key进行检索
      if key in data_list.keys() and key == key_list[-1]:
        # 得到需要修改的值
        value = data_list[key]
        # 如果dict内部仍有list
        if isinstance(data_list[key], list):
          # 得到需要遍历其内元素进行修改的目标列表
          value = data_list[key]
        return
      # 有子节点则继续递归
      elif key in data_list.keys():
        getValueFromList(data_list[key], key_list)

二者结合,则getValue方法内列表相关逻辑应是:

if isinstance(data_next[slist[j]], list):
  # 当前key无子节点
  if j == len(slist)-1:
    # 得到需要遍历其内元素进行修改的目标列表
    value = data_next[slist[j]]
  # 截取后续子节点在列表中进行递归
  else:
    for datas in data_next[slist[j]]:
      tlist = slist[j+1:]
      getValueFromList(datas, tlist)
  return

1. 针对列表中包含列表,需添加判断isinstance(data_list, list)继续递归处理;

2. 针对添加了inlist的列表标识,需进行字符串分割后再去遍历取值。

3. 替换与输出

通过遍历预设的测试数据列表即可对需要修改的值进行替换,列表示例如下:

# Json容错常用数据类型
null = None
false = False
type_list = ["testString", 1, false, null, ["test_list"], {"test_dict":"test_dict_v

修改后的数据指向的仍是原待测试Json数据(需要在每次修改、输出文件后进行数据还原),直接将其写入文件即可——将以容错类型命名的每组数据存入以数据链路key值命名创建的文件夹内(避免输出相同结构的重复数据):

# path为预设好的文件夹路径+文件名称
with open(path, "w") as f:
  json.dump(data, f, sort_keys=True, indent=4, ensure_ascii=False)

此外,缺省(如Json数据中不存在这一key)同样是一种常规的数据容错方式,可使用pop()方法操作字典、列表对相应值进行删除予以实现。

运行结果

综上,运行脚本可得容错文件如图——针对需要替换的值,每组容错数据包含int、string、bool等数据类型及数据缺省:

打开任一文件,如图中...-testA-*-A_int.json,可见原数据中相应值已被替换成了预设值:

// Json中相应位置
"testDict_7_complex": [
            {
                "id": "10000",
                "testA": {
                    "A": 1
                },

至此,一键自动化输出Json容错数据文件的目的便达成了。感谢阅读,欢迎交流。

python测试应用系列其他文章:

基于python的测试报告自动化生成

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档