创建与 pytest.mark.parametrize 兼容的装饰器

Арт*_*ков 6 python decorator pytest

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

装饰器示例:

def decorator_example(fn):

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

return create
Run Code Online (Sandbox Code Playgroud)

测试示例:

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

并捕获异常:

ValueError: <function create at address> uses no argument 'test_params'
Run Code Online (Sandbox Code Playgroud)

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

hoe*_*ing 3

这是因为用具有完全不同签名的包装函数decorator_example替换该函数,破坏了自省(例如,检查是否有参数失败,因为只有且可用)。您需要使用来模仿包装函数的签名:test_1createpytestcreatetest_params*args**kwargsfunctools.wraps

import functools


def decorator_example(fn):

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

    return create
Run Code Online (Sandbox Code Playgroud)

Python 2.7 兼容性

您可以使用该decorator包。按照平常的方式安装即可

$ pip install decorator
Run Code Online (Sandbox Code Playgroud)

上面的例子将是:

import decorator


def decorator_example(fn):
    def create(fn, *args, **kwargs):
        return fn(*args, **kwargs)
    return decorator.decorator(create, fn)
Run Code Online (Sandbox Code Playgroud)

或者使用six

import six


def decorator_example(fn):

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

    return create
Run Code Online (Sandbox Code Playgroud)