🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快
本期内容就json格式的数据解析,来进行阐述。在MeterSphere中,有两种方式可以进行json格式的数据维护。一种是使用他们自带的JsonSchema来填写key-value表单。另一种就是手写json。
手写json在日常工作中效率较低,原因有二,一是手写太麻烦,占据大量个工作时间,影响效率。二是对正确性以及层级结构无法保证准确性。两者相比较,故选择JsonSchema的方式来维护json格式的数据。
json格式数据模型如下
"jsonSchema": {
"properties": {
"字段1": {
"mock": {
"mock": ""
},
"type": "string",
"description": "字段描述。。。"
},
"字段2": {
"type": "number",
"mock": {
"mock": ""
},
"minLength":50,
"maxLength":100
},
"字段3": {
"type": "integer",
"mock": {
"mock": ""
},
"description": "字段描述"
}
},
"type": "object",
"mock": {
"mock": ""
},
"required": [
"字段1",
"字段2",
]
}
使用JsonSchema作为最外层节点,第二层节点包含了类型、字段属性、必填字段列表等参数信息。第三层节点就是字段的一些属性,包含了字段长度、字段名称、字段类型、字段描述等
特别需要说明的是,MeterSphere的字段类型有很多,其中包含了object以及array这两种类型的数据
- object:如果字段类型是object,那么该字段节点下会嵌套另外一些字段,这些字段也是json格式的
- array:同理,如果字段类型是array,那么该字段下面会嵌套一个列表,列表中的每一个元素,都是json格式,不可以手动设置key,是从0递增自动命名。
这两种类型是可以无限重复套娃下去。只要你需要。
所以在解析这类数据时,我们就需要先解决这种层层嵌套的问题。
思路梳理
- 首先判断一下数据类型是否为上述这种套娃格式
- 判断字段类型是object还是array
- 利用python的递归,调用自身。并将字段属性作为参数传给这个函数
- 然后提取字段中的最大值,最小值,以及参数名称、类型
- 判断当前字段是否在必填列表中,如果在,则将这个字段设置为必填
如上是大概的解题思路,抛开拆解套娃,代码相对简单。如下是源码展示
# 解析json请求的参数
def post_arguments(data, required_list=None):
field = {}
if not isinstance(data, dict):
raise TypeError("'data' is not dict")
for key, value in data.items():
if value["type"] == "object" and "properties" in value:
# 递归调用,实现多层嵌套解析
if "required" in value:
recursion_par = post_arguments(value["properties"], value["required"])
par = {
key:
{"type": value["type"],
"description": value["description"] if "description" in value else "",
**recursion_par
}
}
field.update(par)
else:
recursion_par = post_arguments(value["properties"])
par = {
key: {"type": value["type"],
"description": value["description"] if "description" in value else "",
**recursion_par
}
}
field.update(par)
elif value["type"] == "array" and "items" in value:
for l, i in enumerate(value["items"]):
for arr_key, arr_value in i.items():
if arr_value == "object" and "properties" in arr_value:
# 递归调用,实现多层嵌套解析
if "required" in arr_value:
recursion_par = post_arguments(arr_value["properties"], value["required"])
par = {
l: {"type": value["type"],
"description": value["description"] if "description" in value else "",
**recursion_par
}
}
field.update(par)
else:
recursion_par = post_arguments(arr_value["properties"])
par = {
l: {"type": value["type"],
"description": value["description"] if "description" in value else "",
**recursion_par
}
}
field.update(par)
elif arr_value == "array" and "items" in arr_value:
if "required" in arr_value:
recursion_par = post_arguments(arr_value["properties"], arr_value["required"])
par = {
l: {"type": value["type"],
"description": value["description"] if "description" in value else "",
**recursion_par
}
}
field.update(par)
else:
recursion_par = post_arguments(arr_value["properties"])
par = {
l: {"type": value["type"],
"description": value["description"] if "description" in value else "",
**recursion_par
}
}
field.update(par)
else:
maxLength = MAX_LENGTH
minLength = MIN_LENGTH
required = "false"
if "maxLength" in arr_key:
maxLength = i["maxLength"]
elif "maxLength" in arr_key:
minLength = i["minLength"]
if required_list:
if l in required_list:
required = "true"
items_par = {
key:
{
"type": value["type"],
"description": value["description"] if "description" in value else "",
l: {
"type": i["type"],
"required": required,
"max": maxLength,
"min": minLength
}
}
}
field.update(items_par)
else:
maxLength = MAX_LENGTH
minLength = MIN_LENGTH
required = "false"
if "maxLength" in value:
maxLength = value["maxLength"]
elif "minLength" in value:
minLength = value["minLength"]
if required_list:
if key in required_list:
required = "true"
else:
required = "false"
par = {
key: {
"type": value["type"],
"description": value["description"] if "description" in value else "",
"required": required,
"max": maxLength,
"min": minLength,
}
}
field.update(par)
return field
可以看到,思路不是很难,但是代码还是比较臃肿的,其中有很多的代码是冗余的,在后期优化中,将考虑这块重构一下。大家在写的时候将思路缕清,别写出我这么烂的代码。。。。引以为戒~
结语
总结一下这个函数
- 首先在写的时候,多重嵌套是个难题,可以通过递归的方式解决
- 另外一定在思路缕清的前提下,再开始写代码,我就是在边写边思考,一个for循环一个for循环的嵌套。导致代码极其臃肿。执行效率有一定程度的降低,且代码可读性不好
- 公共代码提取:像一些数据结构模板,这些都可以提取成一个公共变量,然后调用即可。在函数中反复写着相类似的模板,是一种很愚蠢的行为。。。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底