How do I make pytest fixtures work with decorated functions?

Each Answer to this Q is separated by one/two green lines.

py.test seems to fail when I decorate test functions which has a fixture as an argument.

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

In this simple example, I get the following error:

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

Is there a way to fix this, preferably without modifying the decorator too much? (Since the decorator is used outside testing code too.)

It looks like functools.wraps does not do the job well enough, so it breaks py.test’s introspection.

Creating the decorator using the decorator package seems to do the trick.

import decorator

def deco(func):
    def wrapper(func, *args, **kwargs):
        return func(*args, **kwargs)
    return decorator.decorator(wrapper, func)

Fixture feature depends on test function signature.

If you can change wrapper signature as follow, it will works.

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

If you can’t change it, make another decorator:

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

And decorate test_somthing with deco_x:

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


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .