简述:一般把断言方法集合封装为一个类,独立作为一个模块使用,输入response和期望数据,然后返回断言结果
一、断言返回数据
这里我将不同断言结果的返回数据分别做为一字典类型的实例属性
1、断言通过数据(pass_result)
self.pass_result = {
'code': 0,
'response_code': self.response_data.status_code,
'response_reason': self.response_data.reason,
'response_headers': self.response_data.headers,
'response_body': self.response_data.text,
'message': '测试用例执行通过',
'check_result': True
}
2、断言失败数据(fail_result)
self.fail_result = {
'code': 2,
'response_code': self.response_data.status_code,
'response_reason': self.response_data.reason,
'response_headers': self.response_data.headers,
'response_body': self.response_data.text,
'message': '测试用例断言失败,测试用例执行不通过',
'check_result': False
}
二、私有断言方法
1、跳过断言函数
有些用例不需要进行断言,并且又不想影响结构,就需要用到该函数,该函数固定返回self.pass_result
def __none_check(self):
logger.info("断言类型[none]-->不进行断言操作,本次断言操作通过")
return self.pass_result
2、断言json类型响应数据是否包含期望的键
源码如下
def __key_check(self, check_data):
"""
检查json类型的响应body中是否包含一个或多个key
:param check_data: 检查数据字符串
:return:都包含则返回True; 有一个不包含就返回False
"""
key_list = check_data.split(',')
tmp_result = []
for check_key in key_list:
if check_key in self.response_data.json().keys():
tmp_result.append(True)
else:
tmp_result.append(False)
if False in tmp_result:
error_message = '断言类型[json_key]-->实际结果:%s ;期望结果:%s 不相符,断言失败'%(self.response_data.text, check_data)
logger.error(error_message)
self.fail_result["message"] = error_message
return self.fail_result
else:
pass_message = '断言类型[json_key]-->实际结果:%s ;期望结果:%s 相符,断言通过'%(self.response_data.text, check_data)
logger.info(pass_message)
self.pass_result["message"] = pass_message
return self.pass_result
思路:
(1)本函数是先使用split(‘,’)对检查数据(该数据为str类型)进行分隔,返回期望key列表(key_list)
(2)再使用for循环key_list 使每个key对json类型响应数据进行判断是否存在,存在则在tmp_result列表添加True,反之则添加False
(3)最后判断tmp_result列表是否存在False,存在则return self.fail_result,反之则return self.pass_result
3、断言json类型响应数据是否包含期望的键值对
源码如下
def __key_value_check(self, check_data):
"""
检查json类型的响应body中是否包含一个或多个键值对
:param check_data:检查数据字符串
:return:都包含则返回True; 有一个不包含就返回False
"""
key_value_dict = json.loads(check_data)
tmp_result = []
for key_value in key_value_dict.items():
if key_value in self.response_data.json().items():
tmp_result.append(True)
else:
tmp_result.append(False)
if False in tmp_result:
error_message = '断言类型[json_key_value]-->实际结果:%s ;期望结果:%s 不相符,断言失败' % (self.response_data.text, check_data)
logger.error(error_message)
self.fail_result["message"] = error_message
return self.fail_result
else:
pass_message = '断言类型[json_key_value]-->实际结果:%s ;期望结果:%s 相符,断言通过' % (self.response_data.text, check_data)
logger.info(pass_message)
self.pass_result["message"] = pass_message
return self.pass_result
思路:
(1)本函数是先使用json.loads(也可用eval内置函数)见检查数据(该数据为str类型)进行转换,返回期望数据key_value_dict字典
(2)再使用for循环key_value_dict.items() 使每个键值对对json类型响应数据进行判断是否存在,存在则在tmp_result列表添加True,反之则添加False
(3)最后判断tmp_result列表是否存在False,存在则return self.fail_result,反之则return self.pass_result
4、补充
对键和值的判断还可以用在判断响应头上,实际代码类似就不多赘述
5、使用正则表达式对响应正文进行提取,断言是否有表达式提取到的数据
源码如下
def __body_regexp_check(self, check_data):
if re.findall(check_data, self.response_data.text):
pass_message = '断言类型[body_regexp]-->实际结果:%s ;期望结果:%s 相符,断言通过' % (self.response_data.text, check_data)
logger.info(pass_message)
self.pass_result["message"] = pass_message
return self.pass_result
else:
error_message = '断言类型[body_regexp]-->实际结果:%s ;期望结果:%s 不相符,断言失败' % (self.response_data.text, check_data)
logger.error(error_message)
self.fail_result["message"] = error_message
return self.fail_result
思路:
(1)这个的模块很简单,就是使用re模块的findall方法传入用与检查的正则表达式和str类型的response数据,findall会return列表数据,该列表类型数据每个单元为符合表达式的str类型数据
(2)最后判断列表是否存在数据,存在则return self.pass_result,反之则return self.fail_result
(3)升级思路:这个函数还可以进一步判断,通过正则表达式返回的字符串1是否与期望值一致,
只需对输入的check_data数据统一一个规则,比如“《|》”符号前面的是正则表达式,后面的是期望值,这个符号随你怎么定(当然最好是那种不常出现的字符组合),然后用split分割出来,然后在去判断
6、对响应status_code进行断言
源码如下
def __response_code_check(self, check_data):
if self.response_data.status_code == int(check_data):
pass_message = '断言类型[response_code]-->实际结果:%s ;期望结果:%s 相符,断言通过'
logger.info(pass_message)
self.pass_result["message"] = pass_message
return self.pass_result
else:
error_message = '断言类型[response_code]-->实际结果:%s ;期望结果:%s 不相符,断言失败'
logger.error(error_message)
self.fail_result["message"] = error_message
return self.fail_result
思路:
这个比较简单一看会,不多赘述(至于为啥还写在这里,单纯是因为作者强迫症,就只差这个函数没有写进来)
三、断言方法封装
看前面的第2部分名字“私有断言方法”就明白这些不是开放给外部使用的,所以这里需要一个开放给外部的函数用来使用这些断言方法,这里我分为两个部分
1、实例属性:fuction
源码如下:
self.function = {
'none': self.__none_check,
'json_key': self.__key_check,
'json_key_value': self.__key_value_check,
'body_regexp': self.__body_regexp_check,
'header_key': self.__header_key_check,
'header_key_value': self.__header_key_value_check,
'response_code': self.__response_code_check
}
这个属性是一个字典类型的数据,数据中key是断言方法名称,而value是前面的第2部分的私有断言方法对象(注意⚠️ :传递函数对象时,函数名末尾不能有括号“()” ,加上括号就是调用函数返回该函数return的值了)
2、实例函数:run_check
源码如下:
def run_check(self, check_type, excepted_result):
logger.info('根据断言类型[%s]进行断言,检查是否满足期望结果:%s'%(check_type, excepted_result))
if check_type == 'none' or excepted_result == "":
return self.function['none']()
return self.function[check_type](excepted_resul> t)
这个是开放给外部的方法,传入的参数为check_type(断言类型)和excpted_result(断言数据),然后除了none的情况判断一下
if check_type == 'none' or excepted_result == "":
return self.function'none'
其他的情况直接返回第一部分的 function[check_type](exceptd_result)
return self.function[check_type](excepted_result)