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

标签 python pytest decorator

我想为我用 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 的参数化测试兼容的装饰器?

最佳答案

那是因为 decorator_example替换 test_1带有包装函数的函数create具有完全不同的签名,打破 pytest内省(introspection)(例如,检查 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

关于python - 创建与 pytest.mark.parametrize 兼容的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56646230/

相关文章:

python - requests post 函数中的 Pytest 装置

ios - 在另一个函数中快速包装函数

python - 创建一个可以访问参数和函数的装饰器

python - Django-从POST请求,JavaScript Fetch API获取值

python - python中不允许嵌套类中的类变量的原因是什么?

Python 3 - 类型错误 : can only concatenate str (not "bytes") to str

python - PyTest 中单个测试的覆盖标记

python - python2中的Monkeypatching类方法

Javascript函数装饰器设计模式

python - WireShark 消息