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

时间:2019-06-18 09:45:02

标签: python pytest decorator

我想为用pytest编写的测试创建一个装饰器。我的问题是,在调用decorator时,pytest引发了一个异常,即decorator尚未获取参数“ 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的参数化测试兼容的装饰器?

1 个答案:

答案 0 :(得分:1)

这是因为decorator_example用具有完全不同签名的包装函数test_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