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

原创
2020/05/14 08:00
阅读数 786

前言


测试工作中往往需要对服务端所返回的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=True)


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


针对列表处理方法getValueFromList,小编还进行了以下补充(此处代码不再赘述):

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

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


3. 替换与输出


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

# Json容错常用数据类型null = Nonefalse = Falsetype_list = ["testString", 1, false, null, ["test_list"], {"test_dict":"test_dict_value"}]


修改后的数据指向的仍是原待测试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的测试报告自动化生成









搜狗测试微信号:Qa_xiaoming

搜狗测试QQ粉丝群:459645679


本文分享自微信公众号 - 搜狗测试(SogouQA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部