2013-10-27 83 views
22

py.test似乎失敗了,當我裝飾測試函數,它有一個夾具作爲參數。如何使pytest夾具與裝飾功能一起工作?

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). 

有沒有辦法解決這個問題,最好不修改裝飾太多了? (因爲裝飾器也在測試代碼之外使用。)

+1

有趣......似乎好的工作,我只Python 3.6中的'functools.wraps'。 2.7中的失敗 – Anentropic

回答

20

它看起來像functools.wraps不能很好地完成這項工作,所以它打破了py.test的內省。

使用decorator包創建裝飾器似乎有訣竅。

import decorator 

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

知道pytest依賴於裝飾器可能很有用,因此您不需要引入任何新的依賴關係。 – zneak

4

夾具功能取決於測試功能簽名。

如果您可以更改包裝簽名,如下所示,它將起作用。

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 
相關問題