Python unit test with base and sub class

前端 未结 15 2165
独厮守ぢ
独厮守ぢ 2020-11-28 18:44

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         


        
相关标签:
15条回答
  • 2020-11-28 19:13

    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
    
    0 讨论(0)
  • 2020-11-28 19:13

    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.

    0 讨论(0)
  • 2020-11-28 19:14

    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()
    
    0 讨论(0)
提交回复
热议问题