前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >装饰器叠加

装饰器叠加

作者头像
zx钟
发布2019-09-09 17:48:31
8460
发布2019-09-09 17:48:31
举报
文章被收录于专栏:测试游记测试游记测试游记

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

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

报告展示

那我需要编写的代码为:

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

现在需要将他们变成一行

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

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

拿出一部分上面allure代码:

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

其实就相当于:

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

所以整一份就是:

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)
        )
    )
)

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

def compose(**kwargs):
   pass

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

def compose(**kwargs):
   def deco(f):
      ...
      return f
   return deco

...中出入传入的参数

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

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

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

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

for allurefunc, param in reversed(_kwargs):
    if param:
        f = eval(allurefunc)(param)(f)
    else:
        f = eval(allurefunc)(f)
return f

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

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

完整代码:

https://github.com/zx490336534/ZXTestFrame/blob/master/zxapi/utils/allureoperator.py

# -*- 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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档