装饰器适用于功能,但不适用于类

时间:2018-06-27 17:17:58

标签: python python-2.7 python-unittest python-decorators

需要一些帮助来纠正装饰器的单元测试。我不确定如何满足单元测试的要求。 这种装饰器的想法是,如果传入True,则将测试标记为期望的失败。否则,可以仅运行测试。此装饰器适用于测试函数,但不适用于类定义 >

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_sometest()正好有1个参数。卸下装饰器即可运行测试。将装饰器移到功能顶部可以运行测试。

历史记录...我的一个平台运行正常,而另一个平台运行不正常。我想允许一个平台运行所有测试,而另一个平台将被标记为预期的故障。当然,我不想使用跳过或跳过。因为那将不允许有效的平台运行。将它们标记为预期的失败也将不起作用,因为一个平台将返回意外的成功。设置了ExpectedFailureIf()后,每个平台都将正确报告,一旦问题解决,这些测试将报告为意外成功。修复后,它将通知我。对我来说,这似乎是更好的结果。

1 个答案:

答案 0 :(得分:3)

在Python 3上,您的代码运行正常。 implementation of unittest.expectedFailure在那里更好,并且在对类或函数进行修饰时都能正常工作。

在Python 2上,unittest.expectedFailure is only designed to work on functions

这里是可在Python 2上运行的替代软件。

Compare-Object @{ one=1 } @{ two=2 }

结果:

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)

警告!

意外成功不会使测试运行失败的事实是Python中的错误!早在2014年1月(Python 3.4)中就解决了该错误,但是由于向后兼容的问题,此错误修正未合并到2.7的分支中(请参阅issue20165上的评论)。因此,很遗憾,现在是Python 2 "feature"

如果这对您来说是个大问题,请考虑升级到更多recent Python version和/或使用better test runner