通过使用decorator和元类跳过Python中除一个之外的所有单元测试

2021-04-11 22:49:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为一个MCU编写单元测试,该MCU通过USB端口通信命令并检查它们的响应。 如果一个单元测试失败了,我可以在MCU中进行一些调试。 因此,我想禁用所有的unittests,除了我想在MCU端调试的那个,因为如果我在某个地方设置断点,它可能会被另一个使用不同命令的unittest触发。在

我在python文档中找到了这段代码,它是一个装饰器,它将跳过所有没有属性的单元测试。在

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

为了使它更简单,我删除了attr参数,并将其静态更改为“StepDebug”,这是一个我只想在一个unittest中设置的属性,以便调试它。在

因此,下一步是自动将此应用于所有类方法。 在浏览了一下网站之后,我发现了以下代码,它使用元类来用上面的装饰器装饰所有的方法。 https://stackoverflow.com/a/6308016/3257551

^{pr2}$

所以我最起码的例子是

import unittest

def decorating_meta(decorator):
    class DecoratingMetaclass(type):
        def __new__(self, class_name, bases, namespace):
            for key, value in list(namespace.items()):
                if callable(value):
                    namespace[key] = decorator(value)
            return type.__new__(self, class_name, bases, namespace)

    return DecoratingMetaclass

def skipUnlessHasattr(obj):
    if hasattr(obj, 'StepDebug'):
        return lambda func : func
    return unittest.skip("{!r} doesn't have {!r}".format(obj, 'StepDebug'))

class Foo(unittest.TestCase):
    __metaclass__ = decorating_meta(skipUnlessHasattr)
    def test_Sth(self):
        self.assertTrue(False)

if __name__ == '__main__':
    unittest.main()

我得到的错误是:

AttributeError: 'Foo' object has no attribute '__name__'

从我所读到的,这是当你有一个实例而不是一个类时发生的事情,但是我不太明白如何使用这些信息来解决我的问题。在

有人能帮忙吗?在

2条回答
网友
1楼 ·

https://stackoverflow.com/a/44804070/1587329使用修饰符,通过环境参数初始化

MCU = os.getenv('MCU', False)

以及装饰通过f.ex排除的测试类和/或方法

^{pr2}$

这可以称为

MCU=1 python # test file etc

The only minor thing with this is that the output doesn't report all the other tests as skipped but rather as a success.

这将跳过的测试标记为s。在

网友
2楼 ·

好吧,我找到了一种方法来实现我想要的功能。 我把装修工改成:

def skipUnlessHasattr(obj):
    if hasattr(obj, 'StepDebug'):
        def decorated(*a, **kw):
            return obj(*a, **kw)
        return decorated
    else:
        def decorated(*a, **kw):
            return unittest.skip("{!r} doesn't have {!r}".format(obj, 'StepDebug'))
        return decorated

现在我跳过了所有的测试,除了添加了属性StepDebug的测试。在

唯一次要的一点是,输出并没有报告所有其他测试都被跳过,而是报告为成功。在

^{pr2}$

另外,为什么在缩进4个空格后复制输出时它没有进入代码块?我也试了8个空格,但没用。最后我给每行加了4个空格。有没有更聪明的方法?在

相关问题