41

当我装饰具有固定装置作为参数的测试函数时,py.test 似乎失败了。

def deco(func):

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)

    return wrapper


@pytest.fixture
def x():
    return 0

@deco
def test_something(x):
    assert x == 0

在这个简单的示例中,我收到以下错误:

TypeError: test_something() takes exactly 1 argument (0 given).

有没有办法解决这个问题,最好不要过多地修改装饰器?(因为装饰器也用于测试代码之外。)

4

2 回答 2

44

看起来 functools.wraps 做得不够好,所以它打破了 py.test 的自省。

使用装饰器包创建装饰器似乎可以解决问题。

import decorator

def deco(func):
    def wrapper(func, *args, **kwargs):
        return func(*args, **kwargs)
    return decorator.decorator(wrapper, func)
于 2013-10-27T05:03:52.460 回答
6

夹具功能取决于测试功能签名。

如果您可以按如下方式更改包装器签名,它将起作用。

def deco(func):
    @functools.wraps(func)
    def wrapper(x):
        return func(x)
    return wrapper

如果无法更改,请制作另一个装饰器:

def deco(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

def deco_x(func):
    @functools.wraps(func)
    def wrapper(x):
        return func(x)
    return wrapper

test_somthing并装饰deco_x

@deco_x
@deco
def test_something(x):
    assert x == 0
于 2013-10-27T05:06:10.467 回答