接口自动化框架搭建,持续更新中。。。
接口自动化框架架构
简介:
一个excel文件代表一个项目,一个项目中的每个sheet就是一个模块,一个模块中写正常用例和异常用例,extract列用来提取返回参数中的数据,提取后将保存于variables.ini配置文件中,引用时用${变量}引用变量或者${func()}引用自定义方法,如随机数生成方法。运行前先指定环境,根据环境匹配对应环境的域名,可以选择项目、模块、具体用例进行运行。运行后生成测试报告。django实现web前端页面,不用再关注代码进行接口自动化。用jenkins实现定时运行,异常时发邮件告警。
分层:
; 1.用例管理✅
一个excel文件就是一个项目,一个项目中的每个sheet就是一个模块,一个模块中写正常用例和异常用例
2.提取数据进行数据关联 ——>难点
✅用一列来专门提取数据,格式是字典,key为被赋值的变量,value为jsonpath要查询的接口返回的字段key,运行时
判断如果有需要提取数据,则将数据进行保存到ini配置文件中
✅引用时通过${变量}方式提取,用re库操作,re.sub()或直接replace()进行替换
✅引用自定义函数(如要生成随机数等),${func()}进行引用,用反射原理来执行函数并返回内容,然后re.sub() 或者 replace()进行替换。
提取变量:
def extract(extract, res_text):
vaiable_ini = '%s/config/variable.ini' % BASEDIR
try:
if extract and isinstance(eval(extract), dict):
extract = eval(extract)
print(type(res_text))
for k, v in extract.items():
value = str(jsonpath.jsonpath(json.loads(res_text), '$..%s' % v))[1:-1]
Config(vaiable_ini).write_varables(section='response',
option=extract.get(k),
value=value
)
except NameError:
print('返回参数提取异常:', traceback.format_exc())
variable.ini文件:
自定义的方法
引用变量和自定义方法变量(有部分代码写的冗余,暂不进行优化):
def quote(headers, payloads)->tuple:
"""re.sub()进行动态替换"""
"""
1.re.findall() 匹配到所有的${} 和 ${func()} 各返回一个列表,
2.检查是否存在于ini配置文件中,存在则re.sub替换,重新赋值给新的headers或payloads变量
3.用反射的方式检查类中是否有这个方法,有则执行,返回结果,然后再re.sub替换或replace(),重新赋值给headers或payloads变量
"""
headers_virables_quotes = re.findall(r'\$\{(.*?)\}', headers)
payloads_virables_quotes = re.findall(r'\$\{(.*?)\}', payloads)
valiadate_ini = '%s/config/variable.ini' % BASEDIR
for hvq in headers_virables_quotes:
if hvq.endswith('()'):
if hasattr(CustomFunc(), hvq[:-2]):
fun = getattr(CustomFunc(), hvq[:-2])
value = fun()
headers = headers.replace('${%s}' % hvq, "\'%s\'" % value)
else:
raise Exception('没有找到对应变量${%s}' % hvq)
else:
if Config(valiadate_ini).has_option('custom', hvq):
quote_value = Config(valiadate_ini).read_variables('custom', hvq)
headers = headers.replace('${%s}' % hvq, quote_value)
elif Config(valiadate_ini).has_option('response', hvq):
quote_value = Config(valiadate_ini).read_variables('response', hvq)
headers = headers.replace('${%s}' % hvq, quote_value)
else:
raise Exception('没有找到对应变量${%s}' % hvq)
for pvq in payloads_virables_quotes:
if pvq.endswith('()'):
if hasattr(CustomFunc(), pvq[:-2]):
fun = getattr(CustomFunc(), pvq[:-2])
value = fun()
payloads = payloads.replace('${%s}' % pvq, str(value))
else:
raise Exception('没有找到对应变量${%s}' % pvq)
else:
if Config(valiadate_ini).has_option('custom', pvq):
quote_value = Config(valiadate_ini).read_variables('custom', pvq)
payloads = payloads.replace('${%s}' % pvq, quote_value)
elif Config(valiadate_ini).has_option('response', pvq):
quote_value = Config(valiadate_ini).read_variables('response', pvq)
payloads = payloads.replace('${%s}' % pvq, quote_value)
else:
raise Exception('没有找到对应变量${%s}' % pvq)
return headers, payloads
3.url组合✅
excel表格中用path,运行时通过输入环境参数,和表中的服务名,在ini配置文件中进行匹配对应的域名,和path组合成完整的url
env_host.ini:
url_util():
def url_util(host_dev, svr_name, path)->str:
if host_dev == 'dev':
host = Config(Run.env_ini).read_variables('host-dev', svr_name)
elif host_dev == 'test':
host = Config(Run.env_ini).read_variables('host-test', svr_name)
else:
host = Config(Run.env_ini).read_variables('host-yace', svr_name)
url = 'http://%s%s' % (host, path)
4.run运行时选择环境与指定用例执行范围✅
指定环境:
Run函数运行是,先确定环境:fixfure函数通过读取ini配置文件中的配置信息,进行传入环境参数,进而在测试用例里通过服务名,组合成对应环境的url
指定范围:
def handel_data(self, *args) ->list:
if len(args) 0:
raise Exception("请输人正确的运行用例范围,如:全部-->all,项目-->project,项目、模块-->project, module1, module2")
all_cases = []
excel_files = os.listdir('%s/data/excelcases' % BASEDIR)
excel_files.pop(excel_files.index('__init__.py'))
if args[0] in ['all', '全部']:
for excel_file in excel_files:
path = '%s/data/excelcases/%s' % (BASEDIR, excel_file)
result_values = list(self.read_excel(path).values())
for result_value in result_values:
for value in result_value:
all_cases.append(value)
return all_cases
elif args[0] in ['冒烟', '正常']:
print('走冒烟')
for excel_file in excel_files:
path = '%s/data/excelcases/%s' % (BASEDIR, excel_file)
result_values = list(self.read_excel(path).values())
for result_value in result_values:
for value in result_value:
if '冒烟' in value['case_name'] or '正常' in value['case_name']:
all_cases.append(value)
print("all cases:\n", all_cases)
return all_cases
else:
if args[0] not in excel_files:
raise Exception('%s项目excel文件不存在,请核实!', args[0])
else:
path = '%s/data/excelcases/%s' % (BASEDIR, args[0])
result = self.read_excel(path)
print(result)
result_new = {}
args_modules = args[1:]
result_keys = list(result.keys())
if len(args_modules) == 0:
result_values = list(result.values())
for result_value in result_values:
for case in result_value:
all_cases.append(case)
else:
for arg in args_modules:
if arg not in result_keys:
raise Exception('%s项目中不存在模块%s' % (args[0], arg))
else:
result_new[arg] = result[arg]
result_values = list(result_new.values())
for result_value in result_values:
for value in result_value:
all_cases.append(value)
return all_cases
5.用例前后置✅
使用conftest.py 和 fixture来实现
@pytest.fixture(scope='module', autouse=True)
def setup_teardown(request):
variable_ini = '%s/config/variable.ini' % BASEDIR
options = Config(variable_ini).get_options('response')
print("运行前操作:\n1.删除response下的optons变量%s" % options)
if options:
for option in options:
Config(variable_ini).rm_option('response', option)
yield
print("运行后操作:\n暂无。")
✅6.生成测试报告
生成html的测试报告,报告优化,将接口返回都给展示
生成allure测试报告,优化报告
⏸7.测试结果回填excel表
⏸8.日志实现
⏸9.有异常时发送邮件,并带附件
⏸10.指定执行错误的用例、跳过用例、运行冒烟用例等
⏸11.用django实现web调用,页面的方式进行选择运行项目,模块,并可查看报告
⏸12.将项目容器化运行
⏸13.用jenkins进行定时运行
Original: https://blog.csdn.net/qq_44663072/article/details/123249575
Author: 董林夕
Title: 接口自动化框架搭建 pytest
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/772595/
转载文章受原作者版权保护。转载请注明原作者出处!