web-dev-qa-db-ja.com

装飾された関数でpytestフィクスチャを機能させるにはどうすればよいですか?

引数としてフィクスチャを持つテスト関数を装飾すると、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).

できればデコレータをあまり変更せずに、これを修正する方法はありますか? (デコレータはテストコードの外部でも使用されるためです。)

32
jck

Functools.wrapsは十分に機能していないように見えるため、py.testの内省を破ります。

decorator パッケージを使用してデコレータを作成するとうまくいくようです。

import decorator

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

フィクスチャ機能は、テスト関数のシグネチャに依存します。

次のようにラッパーの署名を変更できる場合は、機能します。

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_somthingdeco_x

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