Nose 忽略使用自定义装饰器的测试
我的 Python 代码中有一些相对复杂的集成测试。我使用自定义装饰器极大地简化了它们,我对结果非常满意。这是我的装饰器的一个简单示例:
def specialTest(fn):
def wrapTest(self):
#do some some important stuff
pass
return wrapTest
测试可能如下所示:
class Test_special_stuff(unittest.TestCase):
@specialTest
def test_something_special(self):
pass
这非常有效,并且由 PyCharm 的测试运行程序执行,没有任何问题。但是,当我使用 Nose 从命令行运行测试时,它会跳过使用 @specialTest 装饰器的任何测试。 我尝试将装饰器命名为 testSpecial,因此它符合默认规则,但随后我的 FN 参数未通过。
我怎样才能让 Nose 执行这些测试方法并按预期对待装饰器?
解决方案
感谢 madjar,我通过使用 functools.wraps 并更改包装器的名称将代码重组为如下所示,从而实现了此工作:
from functools import wraps
def specialTest(fn):
@wraps(fn)
def test_wrapper(self,*args,**kwargs):
#do some some important stuff
pass
return test_wrapper
class Test_special_stuff(unittest.TestCase):
@specialTest
def test_something_special(self):
pass
I have some relatively complex integration tests in my Python code. I simplified them greatly with a custom decorator and I'm really happy with the result. Here's a simple example of what my decorator looks like:
def specialTest(fn):
def wrapTest(self):
#do some some important stuff
pass
return wrapTest
Here's what a test may look like:
class Test_special_stuff(unittest.TestCase):
@specialTest
def test_something_special(self):
pass
This works great and is executed by PyCharm's test runner without a problem. However, when I run a test from the commandline using Nose, it skips any test with the @specialTest decorator.
I have tried to name the decorator as testSpecial, so it matches default rules, but then my FN parameter doesn't get passed.
How can I get Nose to execute those test methods and treat the decorator as it is intended?
SOLUTION
Thanks to madjar, I got this working by restructuring my code to look like this, using functools.wraps and changing the name of the wrapper:
from functools import wraps
def specialTest(fn):
@wraps(fn)
def test_wrapper(self,*args,**kwargs):
#do some some important stuff
pass
return test_wrapper
class Test_special_stuff(unittest.TestCase):
@specialTest
def test_something_special(self):
pass
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我没记错的话,nose 会根据它们的名称加载测试(名称以 test_ 开头的函数)。在您发布的代码片段中,您没有在包装函数中复制函数的
__name__
属性,因此返回的函数的名称是wrapTest
并且鼻子认为它不是测试。将函数属性复制到新函数的一种简单方法是使用
functools.wraps
。If I remember correctly, nose loads the test based on their names (functions whose name begins with test_). In the snippet you posted, you do not copy the
__name__
attribute of the function in your wrapper function, so the name of the function returned iswrapTest
and nose decides it's not a test.An easy way to copy the attributes of the function to the new one is to used
functools.wraps
.