2012-08-30 45 views
1

在我的测试代码的工作,我有以下几点:pytest参数化的装饰不是** kwargs

@pytest.mark.parametrize(("title", "description", 'site'), [ 
         ("abc", "this is a proper description","minecraft.net"), 
         ("proper title","short","minecraft.net"), 
         ("proper title", "this is a proper description","bol"), 
         ("","this is a proper description","minecraft.net"), 
         ("proper title","","minecraft.net"), 
         ("proper title","this is a proper description",""), 
         ("proper title","this is a proper description","ftp://myftp.nl") 
     ]) 
@ae_test(loggedin = True) 
def test_mod_model_create_validation(title, description,site): 
    ... testing code .... 

因此,参数化功能,试图通过参数我自己@ae_test装饰返回的功能,它看起来像这样:

def ae_test(prob=1.00,loggedin=False,is_admin=False): 
    def create_wrapper(func): 
     def run_test(*args,**kwargs): 
      ... test setup code ... 
      func(*args,**kwargs) 
      ... test teardown code ... 

此已经工作了我所有的测试,到目前为止,但参数化功能是抱怨:

ValueError: <function run_test at 0x1029b55f0> has no argument 'title' 
在pytest/python.py发生

这个错误就行638

在响应第一评论,以下是完整的堆栈跟踪:

==================================== ERRORS ==================================== 
___________________ ERROR collecting test_content_models.py ____________________ 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/runner.py:120: in __init__ 
>    self.result = func() 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/main.py:304: in _memocollect 
>  return self._memoizedcall('_collected', lambda: list(self.collect())) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/main.py:228: in _memoizedcall 
>   res = function() 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/main.py:304: in <lambda> 
> return self._memoizedcall('_collected', lambda: list(self.collect())) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/python.py:207: in collect 
>     res = self.makeitem(name, obj) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/python.py:218: in makeitem 
>   collector=self, name=name, obj=obj) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/main.py:141: in call_matching_hooks 
>  return hookmethod.pcall(plugins, **kwargs) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/core.py:425: in pcall 
>  return self._docall(methods, kwargs) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/core.py:432: in _docall 
>   res = mc.execute() 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/core.py:350: in execute 
>   res = method(**kwargs) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/python.py:103: in pytest_pycollect_makeitem 
>    return collector._genfunctions(name, obj) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/python.py:232: in _genfunctions 
>  gentesthook.pcall(plugins, metafunc=metafunc) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/core.py:425: in pcall 
>  return self._docall(methods, kwargs) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/core.py:432: in _docall 
>   res = mc.execute() 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/core.py:350: in execute 
>   res = method(**kwargs) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/python.py:37: in pytest_generate_tests 
>   metafunc.parametrize(*p.args, **p.kwargs) 
/Library/Python/2.7/site-packages/pytest-2.2.4-py2.7.egg/_pytest/python.py:638: in parametrize 
>     raise ValueError("%r has no argument %r" %(self.function, arg)) 
E     ValueError: <function run_test at 0x1029b55f0> has no argument 'title' 
=========================== 1 error in 0.36 seconds ============================ 

,但真正的问题接缝回落到parameterize寻找一个名为“标题”的论点并没有找到它。这是因为我使用** kw语法。我期待的参数化函数只是在那里写一个字典。

+0

它在哪里回溯到(在638出现错误,但在哪里呢这个铅) ,上面的一行? –

+0

添加栈跟踪 – bigblind

回答

3

你可能最好的时候使用decorator.decorator装饰装饰你的ae_test装饰转换为签名保留装饰:

from decorator import decorator 

def ae_test(prob=1.00,loggedin=False,is_admin=False): 
    @decorator 
    def run_test(func, *args, **kwargs): 
     ... test setup code ... 
     func(*args,**kwargs) 
     ... test teardown code ... 
    return run_test 
+0

我的'run_test'函数可以保存'(* arg,** kwargs)',所以它可以用于具有不同签名的函数吗? – bigblind

+0

@ sys.stderr绝对地,'decorator.decorator'将捕获'create_wrapper'的返回值并恢复它的签名,使它看起来像'func'。 – ecatmur

+0

@acatmur现在,在装饰'create_wrapper'后,我得到这个错误:“ypeError:create_wrapper()只需要1个参数(给出4)”。这是因为create_wrapper只能使用该函数。我必须使用这个三嵌套函数语法才能将参数传递给我的装饰器。但是,将装饰器的一个函数深入移植到'run_test'中,它实际上使用了4个参数,导致了这个错误(我已经包含了代码行:first = inspect.getargspec(caller)[0] [ 0]#first arg \ n E IndexError:列表索引超出范围' – bigblind