哈喽各位,好久没更新接口自动化脚本内容分享了。本期内容做个收尾。将接口自动化脚本剩余部分--参数必填项、类型、字段长度以及参数生成等函数做个分享。废话不多,昊料开始~
开篇
上期内容介绍了提取字段属性相关函数的代码思路以及源码。接下来就是解析这些字段的属性,并生成所需要的参数值。
必填函数
首先说下必填函数
- 首先定义两个列表。一个列表存储正常的参数。一个用来存储字段的key值。
- 第一个列表主要用来生成常规数据
- 第二个列表为下面必填参数逻辑判断,做一个下标定位的作用
- 再构建一个列表用来容纳必填的参数
- 然后遍历数据源datas。判断当前参数类型,如果字段参数为boolean类型则无需做必填校验,直接跳过。
- 然后判断当前字段是否为必填。满足条件者,则通过存储key值的列表来获取当前字段的下标。
- 最后用一个临时变量和一个临时列表,将生成的必填参数收纳,然后追加到新创建的必填参数列表中。
在这个函数中,我定义了三个列表,两个作为临时处理数据以及协助循环提定位的。最后一个才做必填参数的容器。因为列表是可变参数类型,如果直接在第一个列表中处理数据。会造成数据重复以及不准确的问题。
所以,可以看到,在第二个for中我深拷贝了一下第一个列表。就是用来做数据处理,然后让第一个列表作为基础数据源,始终给我最原始的数据。
源码展示
代码语言:javascript复制# 必填数据构造
def required_datas(datas):
# 构建所有key值列表
par_list = []
key_list = []
for data in datas:
for key, value in data.items():
if ("max" and "min") in value:
par = create_params(par_type=value["type"], par_length=2)
else:
par = create_params(par_type=value["type"], par_length=2)
par_list.append(par)
key_list.append(key)
# 构建新的列表来容纳必填校验的数据
new_data_list = []
for data in datas:
for key, value in data.items():
tmp_par_list = deepcopy(par_list)
if value["type"] == "boolean":
continue
if value["required"].lower() == "true":
# 由于参数列表增加了,所以字段列表也需要增加一个值.两个列表要保持长度统一
# 定位字段下标
key_index = key_list.index(key)
tmp = tmp_par_list
# 满足条件,切换当前字段为空.并将其转换成列表追加到new_list容器中
tmp[key_index] = " "
try:
tmp.insert(0, f"【{key}的必填字段校验】;字段描述:{value['description']}")
except KeyError:
tmp.insert(0, f"【{key}的必填字段校验】;该字段没有描述")
new_data_list.append(tmp)
return new_data_list
长度参数
长度参数逻辑不是很复杂。大致逻辑与必填函数相同,基于此,接收一下当前字段的最大值以及最小值。然后根据最大值,最小值生成不同的参数即可
源码展示
代码语言:javascript复制# 长度参数构造
def length_datas(datas):
# 构造正常参数列表
len_par = []
data_list = []
for data in datas:
data_list = ["常规用例"]
for key, value in data.items():
data_list.append(create_params(value["type"], value["max"]))
len_par.append(data_list)
for data in datas:
con_data = []
key_list = []
# 构建常规参数
for key, value in data.items():
key_list.append(key)
con_data.append(create_params(value["type"], value["max"]))
# 最大值-超出边界值
max_out_of_length_par = []
for key, value in data.items():
for i in range(len(con_data)):
tmp = deepcopy(con_data)
tmp[i] = create_params(par_type=value["type"], par_length=int(value["max"]) 5)
try:
tmp.insert(0, f"【{key_list[i]}的超出边界值】;字段描述:{data[key_list[i]]['description']}")
except KeyError:
tmp.insert(0, f"【{key_list[i]}的超出边界值】;字段描述:为空")
max_out_of_length_par.append(tmp)
len_par.append(tmp)
if len(max_out_of_length_par) == len(con_data):
break
# 最小值
min_length_par = []
for key, value in data.items():
for i in range(len(con_data)):
tmp_ = deepcopy(con_data)
tmp_[i] = create_params(par_type=value["type"], par_length=int(value["min"]))
try:
tmp_.insert(0, f"【{key_list[i]}的最小值】;字段描述:{data[key_list[i]]['description']}")
except KeyError:
tmp_.insert(0, f"【{key_list[i]}的最小值】;字段描述:为空")
min_length_par.append(tmp_)
len_par.append(tmp_)
if len(max_out_of_length_par) == len(con_data):
break
return len_par
类型判断
类型判断函数,整体思路就是在创建参数时,给构造参数的函数传一个错误的类型,再追加到参数列表
源码展示
代码语言:javascript复制`# 类型数据构造
def type_datas(datas):
type_par = []
data_list = []
key_list = []
for data in datas:
for key, value in data.items():
key_list.append(key)
data_list.append(create_params(par_type=value["type"], par_length=value["max"]))
for data in datas:
for key_, value_ in data.items():
for i in range(len(data_list)):
tmp_list = deepcopy(data_list)
if value_["type"] == "string":
tmp_list[i] = create_params(par_type="integer", par_length=value_["max"])
try:
tmp_list.insert(0,
f"【{key_}的类型为:{value_['type']}切换成数字】;字段描述:{data[key_]['description']}")
except KeyError:
tmp_list.insert(0,
f"【{key_}的类型为:{value_['type']}切换成数字】;该字段没有描述")
type_par.append(tmp_list)
break
elif value_["type"] in ["number", "integer"]:
tmp_list[i] = create_params(par_type="string", par_length=value_["max"])
try:
tmp_list.insert(0,
f"【{key_}的类型为:{value_['type']}切换成字符串】;字段描述:{data[key_]['description']}")
except KeyError:
tmp_list.insert(0,
f"【{key_}的类型为:{value_['type']}切换成字符串】;该字段没有描述")
type_par.append(tmp_list)
break
elif value_["type"] == "boolean":
tmp_list[i] = create_params(par_type="string", par_length=value_["max"])
try:
tmp_list.insert(0,
f"【{key_}的类型为:{value_['type']}切换成字符串】;字段描述:{data[key_]['description']}")
except KeyError:
tmp_list.insert(0,
f"【{key_}的类型为:{value_['type']}切换成字符串】;该字段没有描述")
type_par.append(tmp_list)
break
if len(type_par) == len(data_list):
break
return type_par
参数生成
最后最主要的参数生成函数。根据上面函数的使用情况,调用该函数。生成相应参数后,将参数返回。代码量最少,但是是举足轻重的一个成员。
代码语言:javascript复制# 生成参数
def create_params(par_type, par_length=None):
if par_type.lower() == "string":
str_par = ""
for i in range(int(par_length)):
str_par = string.ascii_letters[random.randint(0, 51)]
return str_par
elif par_type.lower() in ["number", "integer"]:
nums = ""
for i in range(int(par_length)):
nums = str(random.randint(0, 9))
return int(nums)
elif par_type.lower() == "boolean":
boo = ['true', 'false']
return boo[random.randint(0, 1)]
结尾
本期内容就到这里了。上述几个函数,整体思路上本质都是差不多的。围绕着一个字段,一条用例的原则。展开细化处理即可。
基于此。本系列所有内容就到此结束了。后面还会更新一些渗透测试的学习、以及对这个脚本的代码优化等分享。拜拜~