Skipping all unit tests, but one in Python using decorators and metaclasses

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?

+2
python metaclass decorator unit-testing attributeerror
May 08 '15 at 10:03
source share
2 answers

Ok, I found a way to have the functionality 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 

Now I get all the tests that were missed, except the ones that I added the StepDebug attribute.

The only insignificant thing about this is that the output does not report all the other tests as missed, but rather as successful.

 ..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) 

PS Why when copying the output after the indentation of 4 spaces, it is not included in the code block? I also tried 8 spaces and this did not work. In the end, I added 4 spaces to each line. Is there a smarter way?

0
May 09 '15 at 10:21
source share

https://stackoverflow.com/questions/89378/ ... uses decorators to initialize environment settings

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

and decorating test classes and / or methods that should be excluded through f.ex.

 @unittest.skipIf(MCU) 

it can be called

 MCU=1 python # test file etc 

The only insignificant thing about this is that the output does not report all other tests as missed, but rather as successful.

This marks missed tests as s .

0
Aug 15 '17 at 7:20
source share



All Articles