【问题标题】:Create decorator compatible with pytest.mark.parametrize创建与 pytest.mark.parametrize 兼容的装饰器
【发布时间】:2019-06-18 09:45:02
【问题描述】:

我想为我用 pytest 编写的测试创建一个装饰器。我的问题是,调用装饰器时,pytest 会引发装饰器没有参数“test_params”的异常。

装饰器示例:

def decorator_example(fn):

    def create(*args, **kwargs):
        # any code here
        return fn(*args, **kwargs)

return create

测试示例:

@pytest.mark.parametrize(
    "test_params",
    [
        pytest.param("own_parameters")
    ])
@decorator_example
def test_1(self, fixture1, fixture2, test_params):
    pass

并捕获异常:

ValueError: <function create at address> uses no argument 'test_params'

如何创建与 pytest 的参数化测试兼容的装饰器?

【问题讨论】:

    标签: python pytest decorator


    【解决方案1】:

    那是因为 decorator_exampletest_1 函数替换为具有完全不同签名的包装函数 create,从而破坏了 pytest 内省(例如,检查 create 是否有参数 test_params 失败,因为有只有*args**kwargs 可用)。您需要使用functools.wraps 来模仿包装函数的签名:

    import functools
    
    
    def decorator_example(fn):
    
        @functools.wraps(fn)    
        def create(*args, **kwargs):
            # any code here
            return fn(*args, **kwargs)
    
        return create
    

    Python 2.7 兼容性

    您可以使用decorator 包。照常安装

    $ pip install decorator
    

    上面的例子是:

    import decorator
    
    
    def decorator_example(fn):
        def create(fn, *args, **kwargs):
            return fn(*args, **kwargs)
        return decorator.decorator(create, fn)
    

    或者使用six:

    import six
    
    
    def decorator_example(fn):
    
        @six.wraps(fn)    
        def create(*args, **kwargs):
            # any code here
            return fn(*args, **kwargs)
    
        return create
    

    【讨论】:

    • 对不起,但它不起作用。现在,当我调用包装方法时,然后“创建”函数称为 test_1,错误变为 ValueError: &lt;function test_1 at address&gt; uses no argument 'test_params'
    • 注意:我使用python 2.7
    • 不用担心 - 这就是接受按钮的用途。我已经尝试了您在问题中提供的代码并且它有效。你能用失败的例子更新有问题的代码吗?
    • 啊,我明白了——functools.wraps 在 Python 2.7 的情况下是不够的;使用decorator 包。让我用一个例子来更新答案。
    • 我添加了一个使用decorator的例子,看看吧。
    猜你喜欢
    • 2021-05-09
    • 2014-09-23
    • 2017-01-20
    • 2019-04-30
    • 2014-02-13
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 2017-02-04
    相关资源
    最近更新 更多