[issue17519] unittest should not try to run abstract classes

Stephen Thorne report at bugs.python.org
Thu Apr 1 17:05:32 EDT 2021


Stephen Thorne <sthorne at google.com> added the comment:

I have done some experimentation here and thought through this feature request.

The concept we are trying to deliver is: "I would like to share functionality between test classes, by having an abstract parent, with concrete leaves"

The metaclass abc.ABCMeta provides functionality that means two things:

 - any class with this metaclass (so the class and all its subclasses, typically) that have @abc.abstractmethod or @abc.abstractproperty decorated methods will be treated as abstract
 - any class that is treated as abstract will raise an exception immediately, to make it clear to the programmer (and unit tests) that a programming error has occured.

Following this through, we end up with two ways in which this can go  wrong in unit testing if we ask our unit testing framework to not test abstract classes.

This is a complete example, with both failure modes illustrated:

Consider:

class AbstractTestCase(unittest.TestCase, metaclass=abc.ABCMeta):
  ...

class FooTest(AbstractTestCase):
  def foo(self):
    return 1

In this case, AbstractTestCase will not be skipped: this is because without any abstract methods inside it: it's not actually considered 'abstract', and is a concrete class.

In the second case:

class AbstractTestCase(unittest.TestCase, metaclass=abc.ABCMeta):
  @abc.abstractmethod
  def foo(self):
    ...

  @abc.abstractmethod
   def bar(self):
    ...

class FooTest(AbstractTestCase):
  def foo(self):
    return 1

In this case, because AbstractTestCase has 2 abstract methods, it will be skipped. No tests run. But also FooTest will be skipped because it has 1 abstract method, and is therefore also abstract.

If this were a 'normal' program, we would see an exception raised when FooTest is instanciated, but because we're skipping tests in abstract classes, we skip all the tests and exit with success.

My gut feeling on this is that what we really want is a decorator that says: Skip this class, and only this class, explicitly. All subclasses are concrete, only this one is abstract.

----------
nosy: +sthorne

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue17519>
_______________________________________


More information about the Python-bugs-list mailing list