Python Decorator适用于函数,但不适用于类
需要一些帮助来纠正unittest的装饰程序。我不确定如何满足单元测试的要求此装饰程序的想法是,如果传入True,则将测试标记为预期失败。否则,只允许测试运行。此修饰符适用于测试函数,但不适用于类定义Python Decorator适用于函数,但不适用于类,python,python-2.7,python-unittest,python-decorators,Python,Python 2.7,Python Unittest,Python Decorators,需要一些帮助来纠正unittest的装饰程序。我不确定如何满足单元测试的要求此装饰程序的想法是,如果传入True,则将测试标记为预期失败。否则,只允许测试运行。此修饰符适用于测试函数,但不适用于类定义 import unittest def expectedFailureIf(expFailure): if expFailure: return unittest.expectedFailure return lambda func: func @expect
import unittest
def expectedFailureIf(expFailure):
if expFailure:
return unittest.expectedFailure
return lambda func: func
@expectedFailureIf(GetCurrentOS() == kPlatMac) # Fails on Class
class someClass(unittest.TestCase):
#@expectedFailureIf(GetCurrentOS() == kPlatMac) # Works on Function
def test_sometestA(self):
assert True
def test_sometestB(self):
assert False
我得到的错误是test\u sometest()只接受一个参数。删除decorator允许运行测试。将decorator移到函数顶部可以运行测试
历史。。。我的一个平台可以正常工作,而另一个平台不能。我希望允许一个平台运行所有测试,而另一个平台将被标记为预期失败。当然,我不想使用skip或skip if。因为这将不允许有效的平台运行。将它们标记为预期失败也不起作用,因为一个平台将返回意外的成功。使用expectedFailureIf()后,每个平台都将正确地报告,一旦问题得到解决,这些测试将报告为意外成功。事情解决后会通知我的。为了我。。。这似乎是一个更好的结果。在Python3上,您的代码运行良好。在那里更好,并且在类或函数上进行装饰时可以正常工作 在Python2上 这里有一个在Python2上工作的替换
import inspect
import types
import unittest
def expectedFailureIf(condition):
if callable(condition):
condition = condition()
if not condition:
# return identity function for no-op
return lambda x: x
def patch(func_or_class):
if isinstance(func_or_class, types.FunctionType):
return unittest.expectedFailure(func_or_class)
for name, member in inspect.getmembers(func_or_class):
if name.startswith('test') and isinstance(member, types.MethodType):
setattr(func_or_class, name, unittest.expectedFailure(member))
return func_or_class
return patch
@expectedFailureIf(True)
class MyTest(unittest.TestCase):
def test_that_passes(self):
assert 2 + 2 == 4
def test_that_fails(self):
assert 2 + 2 == 5
if __name__ == "__main__":
unittest.main(verbosity=2)
结果:
test_that_fails (__main__.MyTest) ... expected failure
test_that_passes (__main__.MyTest) ... unexpected success
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK (expected failures=1, unexpected successes=1)
警告
在Python中,意外的成功不会使测试运行失败这一事实是一个错误!早在2014年1月(Python3.4)就解决了这个问题,但由于向后兼容性问题,这个错误修复没有合并到2.7的分支中(请参见上的评论)。不幸的是,这就是Python2
如果这是对你的一个协议,请考虑升级到更多和/或使用.< /p>你不需要使用<代码>=Trime< /Cord>。这不是你有问题的原因,但这是你需要做的一切。在其他方面,您的装饰程序与@wim:跳过与预期失败完全相同。跳过表示不运行测试。预期失败运行测试,然后断言测试失败(报告意外成功)。SkipIf可能具有相同的功能,但不同。我希望测试在两个平台上运行。我希望在修复当前故障平台时收到通知。此外,我还为unittest的其他装饰者提供了一些想法,这将使我更好地跟踪“应该”修复的事情。单元测试修饰符有点限制。这是我想学的。好了,我现在明白了。当测试失败被修复并且测试意外通过该平台时,您希望出现测试失败。非常复杂,但现在有意义了。@wim:
skipIf()
条件修饰符的作用与此修饰符的作用完全相同,因此如果OP对此修饰符有问题,那么skipIf
也是一个问题。您使用的是Python 3.x还是2.7?我从您的代码中得到的信息是:在0.000中运行了0个测试如果测试运行,那么测试应该在虚线和状态报告之前返回“test\u some\u test(main.SomeClassTest)…expected failure”。所以测试没有运行。修改您的代码,使其在If条件下包含print“Marked”:并将assert与math替换为assert False。运行测试并发现正在调用和标记装饰程序。不幸的是,测试本身没有运行。错误的是,测试正在运行。把一份打印的声明放进去,或者你自己看看。好的,这太棒了。完全适用于课堂案例。将decorator移到pass函数的顶部会显示:AttributeError:“MyTest”对象对于传递的函数没有属性“name”,而传递的函数的测试通过(main.MyTest)。。。输出顶部的错误语句。太棒了!!这适用于类调用和函数调用。我相信,我理解你在这里所做的,并且应该能够写一些对我的团队有用的其他装饰。