pytest_api/tools/assert_control.py

199 lines
8.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/3/28 14:18
# @Author : 郭林莉
import jsonpath
from tools.allure_control import SqlSwitch
from tools.log_control import ERROR, WARNING
class Assert:
def __init__(self, assert_data):
self.assert_data = assert_data
@staticmethod
def _check_params(response_data, sql_data):
"""
:param response_data: 响应数据
:param sql_data: 数据库数据
:return:
"""
# 用例如果不执行,接口返回的相应数据和数据库断言都是 False这里则判断跳过断言判断
if response_data is False and sql_data is False:
return False
else:
# 判断断言的数据类型
if isinstance(response_data, dict) and isinstance(sql_data, dict):
pass
elif isinstance(response_data, str):
pass
else:
# pass
raise ValueError("response_data、sql_data、assert_data的数据类型必须要是字典或者str类型")
@staticmethod
def _assert_type(key: any, types: str, value: any):
# 是否相等
if str(types) == "==":
assert key == value
# 判断实际结果小于预期结果
elif str(types) == "lt":
assert key < value
# 判断实际结果小于等于预期结果
elif str(types) == "le":
assert key < value
# 判断实际结果大于预期结果
elif str(types) == "gt":
assert key > value
# 判断实际结果大于等于预期结果
elif str(types) == "ge":
assert key >= value
# 判断实际结果不等于预期结果
elif str(types) == "not_eq":
assert key != value
# 判断字符串是否相等
elif str(types) == "str_eq":
assert key == value
# 判断长度是否相等
elif str(types) == "len_eq":
# assertion isinstance(value, int)
assert len(key) == value
# 判断长度大于
elif str(types) == "len_gt":
assert isinstance(value, int)
assert len(str(key)) > value
# 判断长度大于等于
elif str(types) == 'len_ge':
assert isinstance(value, int)
assert len(key) >= value
elif str(types) == "len_lt":
assert isinstance(value, int)
assert len(key) < value
# 判断长度小于等于
elif str(types) == 'len_le':
assert isinstance(value, int)
assert len(key) <= value
# 判断期望结果内容包含在实际结果中
elif str(types) == "contains":
assert str(value) in str(key)
# 判断实际结果包含在期望结果中
elif str(types) == 'contained_by':
assert str(value) in str(key)
# 检查响应内容的开头是否和预期结果内容的开头相等
elif str(types) == 'startswith':
assert str(value).startswith(str(key))
# 检查响应内容的结尾是否和预期结果内容相等
elif str(types) == 'endswith':
assert str(key).endswith(str(value))
elif str(types) == 'listdata':
assert key
elif str(types) == 'null_list':
assert not key
elif str(types) == 'listdata_len':
# print(len(key))
assert len(key) >= value
elif str(types) == 'status_code':
print("KEY是", key)
print("value", value)
# assert (key['status_code'], 200)
elif str(types) == 'list_in':
# print(len(key))
if key in value:
assert True
else:
assert False
else:
raise ValueError(f"断言失败,目前不支持{types}断言类型,如需新增断言类型,请联系管理员")
def sql_switch_handle(self, sql_data, assert_value, key, values, resp_data) -> None:
"""
:param sql_data: 测试用例中的sql
:param assert_value: 断言内容
:param key:
:param values:
:param resp_data: 预期结果
:return:
"""
# 判断数据库为开关为关闭状态
if SqlSwitch() is False:
WARNING.logger.warning(f"检测到数据库状态为关闭状态,程序已为您跳过此断言,断言值:{values}")
# 数据库开关为开启
if SqlSwitch():
# 判断当用例走的数据数据库断言但是用例中未填写SQL
if sql_data == {'sql': None}:
raise ValueError("请在用例中添加您要查询的SQL语句。")
# 走正常SQL断言逻辑
else:
res_sql_data = jsonpath.jsonpath(sql_data, assert_value)[0]
# 判断mysql查询出来的数据类型如果是bytes类型转换成str类型
if isinstance(res_sql_data, bytes):
res_sql_data = res_sql_data.decode('utf=8')
self._assert_type(types=self.assert_data[key]['type'], key=resp_data[0], value=res_sql_data)
def assert_type_handle(self, assert_type, sql_data, assert_value, key, values, resp_data) -> None:
# 判断断言类型
if assert_type == 'SQL':
self.sql_switch_handle(sql_data, assert_value, key, values, resp_data)
# 判断assertType为空的情况下则走响应断言
elif assert_type == 'str':
print('现在是str类型的断言')
print("预期值",assert_value)
print("实际值", resp_data)
self._assert_type(types=self.assert_data[key]['type'], key=resp_data, value=assert_value)
# elif assert_type == 'noResponse':
# print("预期值", assert_value)
# print("实际值", resp_data[0])
# self._assert_type(types=self.assert_data[key]['type'], key=resp_data, value=assert_value)
elif assert_type is None:
# print("预期值", assert_value)
# print("实际值" ,resp_data[0])
self._assert_type(types=self.assert_data[key]['type'], key=resp_data[0], value=assert_value)
else:
raise ValueError("断言失败,目前只支持数据库断言和响应断言")
def assert_equality(self, response_data, sql_data):
# 判断数据类型
if self._check_params(response_data, sql_data) is not False:
for key, values in self.assert_data.items():
assert_value = self.assert_data[key]['value'] # 获取 yaml 文件中的期望value值
assert_jsonpath = self.assert_data[key]['jsonpath'] # 获取到 yaml断言中的jsonpath的数据
assert_type = self.assert_data[key]['AssertType']
# 从yaml获取jsonpath拿到对象的接口响应数据
if assert_type=='str':
resp_data = response_data
print("resp_dataresp_dataresp_data",resp_data)
else:
resp_data = jsonpath.jsonpath(response_data, assert_jsonpath)
# jsonpath 如果数据获取失败会返回False判断获取成功才会执行如下代码
if resp_data is not False:
# 判断断言类型
# print('断言',assert_type, sql_data, assert_value, key, values, resp_data)
self.assert_type_handle(assert_type, sql_data, assert_value, key, values, resp_data)
else:
ERROR.logger.error("JsonPath值获取失败{}".format(assert_jsonpath))
raise ValueError(f"JsonPath值获取失败{assert_jsonpath}")
else:
raise '断言失败'
pass
#
# if __name__ == '__main__':
# from tools.readfiletools.yaml_data_analysis import CaseData
# from config.setting import ConfigHandler
# #获取用例清洗后的数据
# GetCaseData = CaseData(ConfigHandler.merchant_data_path + r'test_dm\InFo.yaml').case_process()
# #获取用例列表里面第一个用例的 assert
# cc = GetCaseData[0]['assert']
# aa = {'status': 200, 'message': 'ok', 'data': '12312312'}
# bb = {'sql': None}
# Assert(cc).assert_equality(response_data=aa,sql_data=bb)