装饰器叠加

装饰器叠加

欢迎关注我呀~「测试游记」「zx94_11」

在使用pytest+allure进行自动化脚本开发的时候,在case头部需要增加很多装饰器才能使报告按照预期格式展示

例如我需要报告展示如下:

报告展示

那我需要编写的代码为:

1
2
3
4
5
6
@allure.feature('大模块')
@allure.story('子模块')
@allure.title('这个test_b')
@allure.issue('url', '问题单:xxx')
def test_b():
print('ok')

现在需要将他们变成一行

1
2
3
4
5
6
@compose(feature='大模块', 
story='子模块',
title='这个test_b',
issue=('url', '问题单:xxx'))
def test_b():
print('ok')

为了实现这个目标,先来回忆一下装饰器运行的方式,可以阅读一下「测试开发进阶(四)」。

拿出一部分上面allure代码:

1
2
3
@allure.feature('大模块')
def test_b():
print('ok')

其实就相当于:

1
test_b = allure.feature('大模块')(test_b)

所以整一份就是:

1
2
3
4
5
6
7
8
test_b = allure.feature('大模块')(
allure.story('子模块')(
allure.title('这个test_b')(
allure.issue('url', '问题单:xxx')(
test_b)
)
)
)

不过按照装饰器的调用顺序的话,应该是allure.issue是第一个,所以要把它整个给倒过来,但是对于allure来说这个顺序并不是很重要。

1
2
3
4
5
6
7
test_b = allure.issue('url', '问题单:xxx')(
allure.title('这个test_b')(
allure.story('子模块')(
allure.feature('大模块')(test_b)
)
)
)

编写一个函数接受不定长的参数:

1
2
def compose(**kwargs):
pass

因为它要作为一个装饰器,所以需要在内部再写一个函数并返回

1
2
3
4
5
def compose(**kwargs):
def deco(f):
...
return f
return deco

...中出入传入的参数

为了偷懒,所以入参没加上allure,需要人为进行一次处理,使用列表推导式快速的拿到:

1
_kwargs = [('allure.' + key, value) for key, value in kwargs.items()]

按照上面说的需要倒过来执行,所以使用reversed把列表倒一下

每次都重新赋值feval(allurefunc)(f)

1
2
3
4
5
6
for allurefunc, param in reversed(_kwargs):
if param:
f = eval(allurefunc)(param)(f)
else:
f = eval(allurefunc)(f)
return f

为了防止找不到allure模块,增加一下它

1
builtins.__dict__.update({'allure': allure})

所以完整代码:https://github.com/zx490336534/ZXTestFrame/blob/master/zxapi/utils/allureoperator.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- 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

当然这份代码也可以改变成任意的装饰器叠加

 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
您的支持将鼓励我继续创作!