通过使用装饰器和元类跳过所有单元测试,但跳过Python中的一个 [英] Skipping all unit tests but one in Python by using decorators and metaclasses

查看:88
本文介绍了通过使用装饰器和元类跳过所有单元测试,但跳过Python中的一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写用于MCU的单元测试,该MCU通过USB端口通信命令并检查其响应. 如果一个单元测试失败,那么对我来说,在MCU中进行一些调试是很有意义的. 因此,我想禁用除要在MCU端调试的单元测试以外的所有单元测试,因为如果我在某个地方设置了断点,则它可能会被另一个使用不同命令的单元测试触发.

I am writing unit tests for an MCU that communicates commands through the USB port and checks their response. If one unit test fails it makes sense for me to do some debugging in the MCU. Therefore I would like to disable all unittests except for the one that I would like to debug on the MCU side because if I set a breakpoint somewhere it might get triggered by another unittest with different commands.

我去了python文档,发现这段代码是一个装饰器,它将跳过所有没有属性的单元测试.

I went to the python docs and found this code which is a decorator that will skip all unittests that don't have an attribute.

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",这是我仅想在一个单元测试中设置的属性,以便对其进行调试.

In order to make it more simple I deleted the attr argument and statically changed it to 'StepDebug' which is an attribute that I want to set in only one unittest in order to debug it.

因此,下一步是对我自动将其应用于所有类方法. 在网上阅读后,我发现以下代码使用元类来用上述装饰器装饰所有方法. https://stackoverflow.com/a/6308016/3257551

So the next step is for me to apply this for all my class methods automatically. After reading around on the webs I found the following code that uses a metaclass in order to decorate all methods with the above decorator. https://stackoverflow.com/a/6308016/3257551

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

所以我的最低工作示例是

So my minimum working example is

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__'

据我了解,这是当您有一个实例而不是一个类,但是我不太了解如何使用这些信息来解决我的问题时发生的事情.

From what I read this is something that happens when instead of a class you have an instance but I don't quite understand how I can use this information to solve my problem.

有人可以帮忙吗?

推荐答案

好,我找到了一种具有所需功能的方法. 我将装饰器更改为:

Ok I found a way to have the functionality that I want. I changed the decorator to:

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"的那些测试之外,其他所有测试都将被跳过.

Now I get all tests skipped except the ones that I have added an attribute StepDebug.

唯一的次要问题是输出不会报告所有其他测试为已跳过,而是报告为成功.

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

..F..
======================================================================
FAIL: test_ddd (__main__.Foo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./Documents/programs/Python/mwe.py", line 23, in     decorated
    return obj(*a, **kw)
  File "./Documents/programs/Python/mwe.py", line 39, in     test_ddd
    self.assertTrue(False)
AssertionError: False is not true

----------------------------------------------------------------------
Ran 5 tests in 0.014s

FAILED (failures=1)

P.S.为什么在缩进4个空格后复制输出时,它不会进入代码块?我也尝试了8个空格,这是行不通的.最终,我在每行中添加了4个空格.有没有更聪明的方法?

P.S. Why when copying the output after indenting 4 spaces it doesn't go into a code block? I tried 8 spaces as well and it wouldn't work. Eventually I added 4 spaces to each line. Is there a smarter way?

这篇关于通过使用装饰器和元类跳过所有单元测试,但跳过Python中的一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆