I currently have a few unit tests which share a common set of tests. Here\'s an example:
import unittest
class BaseTest(unittest.TestCase):
def testCo
Matthew's answer is the one I needed to use since I'm on 2.5 still. But as of 2.7 you can use the @unittest.skip() decorator on any test methods you want to skip.
http://docs.python.org/library/unittest.html#skipping-tests-and-expected-failures
You'll need to implement your own skipping decorator to check for the base type. Haven't used this feature before, but off the top of my head you could use BaseTest as a marker type to condition the skip:
def skipBaseTest(obj):
if type(obj) is BaseTest:
return unittest.skip("BaseTest tests skipped")
return lambda func: func
As of Python 3.2, you can add a test_loader function to a module to control which tests (if any) are found by the test discovery mechanism.
For example, the following will only load the original poster's SubTest1
and SubTest2
Test Cases, ignoring Base
:
def load_tests(loader, standard_tests, pattern):
suite = TestSuite()
suite.addTests([SubTest1, SubTest2])
return suite
It ought to be possible to iterate over standard_tests
(a TestSuite
containing the tests the default loader found) and copy all but Base
to suite
instead, but the nested nature of TestSuite.__iter__
makes that a lot more complicated.
So this is kind of an old thread but I came across this problem today and thought of my own hack for it. It uses a decorator that makes the values of the functions None when acessed through the base class. Don't need to worry about setup and setupclass because if the baseclass has no tests they won't run.
import types
import unittest
class FunctionValueOverride(object):
def __init__(self, cls, default, override=None):
self.cls = cls
self.default = default
self.override = override
def __get__(self, obj, klass):
if klass == self.cls:
return self.override
else:
if obj:
return types.MethodType(self.default, obj)
else:
return self.default
def fixture(cls):
for t in vars(cls):
if not callable(getattr(cls, t)) or t[:4] != "test":
continue
setattr(cls, t, FunctionValueOverride(cls, getattr(cls, t)))
return cls
@fixture
class BaseTest(unittest.TestCase):
def testCommon(self):
print('Calling BaseTest:testCommon')
value = 5
self.assertEqual(value, 5)
class SubTest1(BaseTest):
def testSub1(self):
print('Calling SubTest1:testSub1')
sub = 3
self.assertEqual(sub, 3)
class SubTest2(BaseTest):
def testSub2(self):
print('Calling SubTest2:testSub2')
sub = 4
self.assertEqual(sub, 4)
if __name__ == '__main__':
unittest.main()