在使用pytest allure进行自动化脚本开发的时候,在case头部需要增加很多装饰器才能使报告按照预期格式展示
例如我需要报告展示如下:
报告展示
那我需要编写的代码为:
代码语言:javascript复制@allure.feature('大模块')
@allure.story('子模块')
@allure.title('这个test_b')
@allure.issue('url', '问题单:xxx')
def test_b():
print('ok')
现在需要将他们变成一行
代码语言:javascript复制@compose(feature='大模块',
story='子模块',
title='这个test_b',
issue=('url', '问题单:xxx'))
def test_b():
print('ok')
为了实现这个目标,先来回忆一下装饰器运行的方式,可以阅读一下「测试开发进阶(四)」。
拿出一部分上面allure
代码:
@allure.feature('大模块')
def test_b():
print('ok')
其实就相当于:
代码语言:javascript复制test_b = allure.feature('大模块')(test_b)
所以整一份就是:
代码语言:javascript复制test_b = allure.feature('大模块')(
allure.story('子模块')(
allure.title('这个test_b')(
allure.issue('url', '问题单:xxx')(
test_b)
)
)
)
不过按照装饰器的调用顺序的话,应该是allure.issue
是第一个,所以要把它整个给倒过来,但是对于allure来说这个顺序并不是很重要。
test_b = allure.issue('url', '问题单:xxx')(
allure.title('这个test_b')(
allure.story('子模块')(
allure.feature('大模块')(test_b)
)
)
)
编写一个函数接受不定长的参数:
代码语言:javascript复制def compose(**kwargs):
pass
因为它要作为一个装饰器,所以需要在内部再写一个函数并返回
代码语言:javascript复制def compose(**kwargs):
def deco(f):
...
return f
return deco
在...
中出入传入的参数
为了偷懒,所以入参没加上allure
,需要人为进行一次处理,使用列表推导式快速的拿到:
_kwargs = [('allure.' key, value) for key, value in kwargs.items()]
按照上面说的需要倒过来执行,所以使用reversed
把列表倒一下
每次都重新赋值f
:eval(allurefunc)(f)
for allurefunc, param in reversed(_kwargs):
if param:
f = eval(allurefunc)(param)(f)
else:
f = eval(allurefunc)(f)
return f
为了防止找不到allure模块,增加一下它
代码语言:javascript复制builtins.__dict__.update({'allure': allure})
完整代码:
https://github.com/zx490336534/ZXTestFrame/blob/master/zxapi/utils/allureoperator.py
代码语言:javascript复制# -*- coding:utf-8 -*-
"""
@Describe: 简化allure装饰器头部
@Author: zhongxin
@Time: 2019-09-03 19:42
@Email: 490336534@qq.com
"""
import builtins
import allure
def compose(**kwargs):
"""
将头部ALlure装饰器进行封装
可以采用:
feature='主要功能模块'
story='分支功能模块'
issue=('', '666')
的方式入参数
:param kwargs:
:return:
"""
def deco(f):
builtins.__dict__.update({'allure': allure})
_kwargs = [('allure.' key, value) for key, value in kwargs.items()]
for allurefunc, param in reversed(_kwargs):
if param:
f = eval(allurefunc)(param)(f)
else:
f = eval(allurefunc)(f)
return f
return deco
当然这份代码也可以改变成任意的装饰器叠加