如果你看不懂,点击下方不迷路:
前方高能!!正文开始!
在前几章做好的基础上
此章详细讲解数据关联的思路和用法!!
实现接口1的返回值的某一具体参数,在接口2中使用
1、新增文件test_data.txt:
#该文件用来存放 (存放接口1返回的数据):
2、在创建读取文件函数前先到setting.py内新增:
TEST_JSON = os.path.join(PROJECT_ROOT, 'database', 'test_data.txt') #存放接口返回数据
3、创建文件后需要用方法读取、data_driver新增load_data()函数:
使用用setting.TEST_JSON代替读取路径
*函数作用:读取test_data内数据
def load_data() -> dict:
"""
返回test_data内的数据
:return:
"""
#setting.TEST_JSON 为setting.py
with open(setting.TEST_JSON, encoding='utf-8') as file_obj:
for line in file_obj:
token_data = eval(line)
return token_data
4、data_driver新增data_association()函数:
函数作用:用来替换数据,返回替换完成后的数据
def data_association(replace_data, request_data):
"""
判断是否调用上一个接口返回的数据当此次访问的参数,并返回数据
:param replace_data: 上个接口返回的数据
:param request_data: 当前接口的请求测试数据
:return:请求参数 dict格式
"""
# 正则表达式带^特殊符号开头的内容
pattern = re.compile(r"'\^([\s\S]+?)'")
# 拿到匹配的内容 key列表内的值为replace_data的键
keys = re.findall(pattern, str(request_data))
# 如果request_data内没有^,直接返回原数据
if len(keys) <= 0:
return request_data
# 当前匹配出来的内容
present = []
# 拿着这个key 去上个接口里面得到想要的内容
for key in keys:
try:
a = replace_data['{}'.format(key)]
except Exception:
a = request_data
# 每次匹配出来内容都进行遍历装进list中
present.append(a)
# 从index 0开始 根据原值内容 直接进行替换,然后直接返回
for i in range(0, len(present)):
# key[i]是原来的值 present是获取的值 最后将特殊符号处理掉
request_data = str(request_data).replace(keys[i], str(present[i])).replace('^', '')
return request_data
写入如下代码测试结果(不然写一大堆最后执行不了很蛋疼!):
*先在test_data写入内容{‘code’: 0, ‘msg’: ‘ok’, ‘value’: 3}
if __name__ == '__main__':
"""
用test_data数据{'code': 0, 'msg': 'ok', 'value': 3}中的code,value的值分别代替data内的code,value
"""
data = {'a': '^code', 'b': '^value'}
print('test_data内的数据:', load_data()) # test_data内的数据(接口1返回的结果)
print('替换前的参数:', data) # 未替换前的参数
print('替换后的参数:', data_association(load_data(), data)) # 替换完成后的参数(接口2的请求数据)
运行成功打印如下信息:
5、test_case.xlsx内新增数据字段如下:
新增前置条件字段,新增一条case
因为新增字段,需要修改excel_dict函数:
def excel_dict(data):
"""
1.将excel头部替换成英文的
2.处理成json/dict格式
"""
header = {
'用例编号': 'id',
'请求类型': 'get_type',
'测试url': 'url',
'测试接口': 'interface',
'用例标题': 'title',
'测试数据': 'data',
'预期结果': 'expected',
'请求头': 'header',
'响应数据状态/json返回数据的code': 'code',
'状态码': 'status',
'响应状态': 'msg',
'前置条件': 'precondition' #新增对新字段的处理
}
head = []
list_dict_data = []
for d in data[1]:
# 获取到英文的头部内容如果为中文,则替换成英文 进行改成一个k
# 传入两个参数的作用是 查到则返回查到的数据查不到则返回传入的原数据
d = header.get(d, d)
# 将去除的头部英文装进list中
head.append(d)
# 获取到数据进行切片处理,0坐标为标题,1坐标是头部
for b in data[2:]:
# 头部和内容拼接为json串
dict_data = {}
for i in range(len(head)):
# 之所以判断类型,如果不进行判断会出现str的错误,strip去除空格也有转str的用法
if isinstance(b[i], str):
dict_data[head[i]] = b[i].strip()
else:
dict_data[head[i]] = b[i]
# list里面是字典格式
list_dict_data.append(dict_data)
return list_dict_data
6、修改send_request函数前在data_driver内新增data_processing()函数:
用来处理数据的类型
def data_processing(variate):
"""
判断数据类型是否为字典,若不是dict则转换成dict
:param variate: 数据
:return: dict
"""
global false, null, true
false = False
null = None
true = True
if variate == '':
return variate
if isinstance(variate, str):
return eval(variate)
elif isinstance(variate, dict):
return variate
elif variate is None:
return None
创建完成方法后:
- 新增数据关联
- 进入sendrequest.py文件内
def send_requests(apidata):
"""
分析测试用例自带参数、发送请求
:param apidata: 测试用例
:return:
"""
try:
# 从读取的表格中获取响应的参数作为传递
method = apidata["get_type"]
url = apidata["url"]
if apidata["header"] == '':
header = None
else:
header = eval(apidata["header"])
# 判断表内是否有测试数据
if apidata["data"] == "":
body_data = None
else:
#使用data_association函数判断是否需要替换某些数据
body_data = eval(data_association(load_data(), apidata['data'])) #新增数据关联的处理
logging.info('请求参数:{}'.format(body_data)) #新增打印参数log,方便查看
s = requests.session()
re = s.request(method=method, url=get_test_url('loc') + url, headers=header,
json=body_data)
return re
except Exception as error:
logging.error("错误信息", error)
写入如下代码测试结果(不然写一大堆最后执行不了很蛋疼!):
if __name__ == '__main__':
case_dict = {'id': 3.0, 'get_type': 'post', 'interface': '相减接口', 'title': '参数正常-成功', 'header': '',
'precondition': '', 'url': '/less', 'data': "{'a': '^code', 'b':'^value'}",
'expected': "{'code': 1000, 'msg': 'success', 'value': -3}", 'code': 1000.0, 'status': 200.0,
'msg': 'success'}
re = send_requests(case_dict)
print(re.url)
print(re.json())
运行结果如下:
最后在函数TestCase内新增一段代码:
@ddt.ddt
class TestCase(unittest.TestCase):
@ddt.data(*case_data('testcase'))
def test_run_case(self, data):
"""
执行测试脚本
:param data: 参数化后测试用例|dict类型
:return:
"""
self.response = send_requests(data) # 返回response
print('________________________________')
logging.info("页面返回信息:%s" % self.response.json())
self.result = self.response.json()
code = data['code'] # 获取表内code
status = data['status'] # 获取表内状态码
msg = data['msg'] # 获取响应状态
# 判断前置条件是否为1 ---新增
if data['precondition'] == 1:
# 为1:将内容写进test_data文件用来替换下个接口的参数
with codecs.open(setting.TEST_JSON, 'w', encoding='utf-8') as f:
json.dump(self.result, f)
if code == self.result['code'] and status == self.response.status_code \
and msg == self.result['msg']: # 判断返回数据是否和表内数据相同
self.msg_data = "PASS"
else:
self.msg_data = "FAIl"
Excel('w', results_root) \
.write(write_result(value7=str(self.result), value8=self.msg_data))
self.assertEqual(self.result['code'], code)
self.assertEqual(self.response.status_code, status)
self.assertEqual(self.result['msg'], msg)
运行testcase如下:
这样就完成数据关联了! 第三条请求的参数等于第一个返回的数据(可自己进一步修改数据验证)
(数据关联灵感多谢某大佬 - 大佬博客名:寻鱼的猫)
非常感谢您的阅读,第一次写博客文章,写的不好的地方多度包含,欢迎大佬指出代码中的不足,共同提升、共同进步!(要源代码 点赞关注后+VX dengwoi )