I am writing unit tests for the MCU, which transmits commands via a USB port and checks their response. If one unit test does not work, it makes sense for me to do some debugging in the MCU. Therefore, I would like to disable all unittests, except those that I would like to debug on the MCU side, because if I set a breakpoint somewhere, it could be called by another unittest with different commands.
I went into 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))
To make it simpler, I removed the attr argument and statically changed it to "StepDebug", which is an attribute that I want to set with only one unittest to debug it.
So, the next step for me is to apply this to all class methods automatically. After reading on the Internet, I found the following code that uses a metaclass to decorate all methods using the decorator described above. stack overflow
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 minimal working example
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()
and the error I get:
AttributeError: 'Foo' object has no attribute '__name__'
From what I read, this is what happens when you have an instance instead of a class, but I donβt quite understand how I can use this information to solve my problem.
Can anybody help?