生成html的测试报告,报告优化,将接口返回都给展示
简介:一个excel文件代表一个项目,一个项目中的每个sheet就是一个模块,一个模块中写正常用例和异常用例,extract列用来提取返回参数中的数据,提取后将保存于variables.ini配置文件中,引用时用${变量}引用变量或者${func()}引用自定义方法,如随机数生成方法。运行前先指定环境,根据环境匹配对应环境的域名,可以选择项目、模块、具体用例进行运行。运行后生成测试报告。django实现web前端页面,不用再关注代码进行接口自动化。用jenkins实现定时运行,异常时发邮件告警。分层:
用例前后置✅
variablini文件:自定义的方法
⏸1用django实现web调用,页面的方式进行选择运行项目,模块,并可查看报告
使用conftest.py和fixture来实现
# 用例运行前后置的操作
@pytest.fixture(scope='module', autouse=True)
def setup_teardown(request):
variable_ini = '%s/config/variable.ini' % BASEDIR # 保存变量文件
# 1.所有用例运行前,清空variable.ini中[response]下的变量
options = Config(variable_ini).get_options('response')
print('运行前操作:
1.删除response下的optons变量%s' % options)
if options:
for option in options:
Config(variable_ini).rm_option('response', option)
yield
print('运行后操作:
暂无。')
一个excel文件就是一个项目,一个项目中的每个sheet就是一个模块,一个模块中写正常用例和异常用例
提取数据进行数据关联——>难点
⏸1用jenkins进行定时运行
提取变量:
# 提取参数
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] # jsonpath进行模糊匹配
Config(vaiable_ini).write_varables(section='response',
option=extract.get(k),
value=value
)
except NameError:
print('返回参数提取异常:', traceback.format_exc())
指定环境:Run函数运行是,先确定环境:fixfure函数通过读取ini配置文件中的配置信息,进行传入环境参数,进而在测试用例里通过服务名,组合成对应环境的url指定范围:
excel表格中用path,运行时通过输入环境参数,和表中的服务名,在ini配置文件中进行匹配对应的域名,和path组合成完整的urlenv_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)
生成allure测试报告,优化报告
⏸测试结果回填excel表
⏸有异常时发送邮件,并带附件
用例管理✅
接口自动化框架架构
引用变量和自定义方法变量:
# 参数引用${variable}、${func()}
def quote(headers, payloads)->tuple:
'''re.sub()进行动态替换'''
'''
1.re.findall() 匹配到所有的${} 和 ${func()} 各返回一个列表,
2.检查是否存在于ini配置文件中,存在则re.sub替换,重新赋值给新的headers或payloads变量
3.用反射的方式检查类中是否有这个方法,有则执行,返回结果,然后再re.sub替换或replace(),重新赋值给headers或payloads变量
'''
# 正则匹配到所有引用变量列表,格式如:['random()', 'token', 'name']
headers_virables_quotes = re.findall(r'${(.*?)}', headers)
payloads_virables_quotes = re.findall(r'${(.*?)}', payloads)
valiadate_ini = '%s/config/variable.ini' % BASEDIR
# 对headers的操作
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) # 注意:header的value必须都是字符串
else:
raise Exception('没有找到对应变量${%s}' % hvq)
else:
# 在ini文件中判断是否存在变量
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)
# 对payloads的操作
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:
# 在ini文件中判断是否存在变量
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
run运行时选择环境与指定用例执行范围✅
✅生成测试报告
url组合✅
⏸10.指定执行错误的用例、跳过用例、运行冒烟用例等
⏸日志实现
✅用一列来专门提取数据,格式是字典,key为被赋值的变量,value为jsonpath要查询的接口返回的字段key,运行时判断如果有需要提取数据,则将数据进行保存到ini配置文件中✅引用时通过${变量}方式提取,用re库操作,rsub()或直接replace()进行替换✅引用自定义函数,${func()}进行引用,用反射原理来执行函数并返回内容,然后rsub()或者replace()进行替换。
文章为作者独立观点,不代表观点