abstract test case using python unittest abstract test case using python unittest python python

abstract test case using python unittest


I didn't quite understand what do you plan to do --the rule of thumb is "not to be smart with tests" - just have them there, plain written.

But to achieve what you want, if you inherit from unittest.TestCase, whenever you call unittest.main() your "abstract" class will be executed - I think this is the situation you want to avoid.

Just do this:Create your "abstract" class inheriting from "object", not from TestCase. And for the actual "concrete" implementations, just use multiple inheritance:inherit from both unittest.TestCase and from your abstract class.

import unittestclass Abstract(object):    def test_a(self):        print "Running for class", self.__class__class Test(Abstract, unittest.TestCase):    passunittest.main()

update: reversed the inheritance order - Abstract first so that its defintions are not overriden by TestCase defaults, as well pointed in the comments bellow.


There's a very simple way that everyone has missed so far. And unlike several of the answers, it works with all test drivers, rather than failing the minute you switch between them.

Simply use inheritence as usual, then add:

del AbstractTestCase

at the end of the module.


Multiple inheritance isn't a great option here, chiefly for the two following reasons:

  1. None of the methods in TestCase use super() so you'd have to list your class first for methods like setUp() and tearDown() to work.
  2. pylint will warn that the base class uses self.assertEquals() etc which aren't defined on self at that point.

Here's the kludge I came up with: turn run() into a no-op for the base class only.

class TestBase( unittest.TestCase ):  def __init__( self, *args, **kwargs ):    super( TestBase, self ).__init__( *args, **kwargs )    self.helper = None    # Kludge alert: We want this class to carry test cases without being run    # by the unit test framework, so the `run' method is overridden to do    # nothing.  But in order for sub-classes to be able to do something when    # run is invoked, the constructor will rebind `run' from TestCase.    if self.__class__ != TestBase:      # Rebind `run' from the parent class.      self.run = unittest.TestCase.run.__get__( self, self.__class__ )                              else:      self.run = lambda self, *args, **kwargs: None  def newHelper( self ):    raise NotImplementedError()  def setUp( self ):    print "shared for all subclasses"    self.helper = self.newHelper()  def testFoo( self ):    print "shared for all subclasses"    # test something with self.helperclass Test1( TestBase ):  def newHelper( self ):    return HelperObject1()class Test2( TestBase ):  def newHelper( self ):    return HelperObject2()