Python单元测试基类与子类

193 投票
15 回答
85169 浏览
提问于 2025-04-15 13:50

我现在有几个单元测试,它们共享一组共同的测试。这里有个例子:

import unittest

class BaseTest(unittest.TestCase):

    def testCommon(self):
        print 'Calling BaseTest:testCommon'
        value = 5
        self.assertEquals(value, 5)

class SubTest1(BaseTest):

    def testSub1(self):
        print 'Calling SubTest1:testSub1'
        sub = 3
        self.assertEquals(sub, 3)


class SubTest2(BaseTest):

    def testSub2(self):
        print 'Calling SubTest2:testSub2'
        sub = 4
        self.assertEquals(sub, 4)

if __name__ == '__main__':
    unittest.main()

上面的输出是:

Calling BaseTest:testCommon
.Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 5 tests in 0.000s

OK

有没有办法重写上面的代码,让第一个 testCommon 不被调用呢?

编辑:我希望运行的测试数量从5个变成4个,2个来自SubTest1,另外2个来自SubTest2。看起来Python的unittest会自动运行原来的BaseTest,我需要一种方法来阻止这种情况发生。

15 个回答

39

你可以用一个简单的命令来解决这个问题:

del(BaseTest)

所以代码看起来会是这样的:

import unittest

class BaseTest(unittest.TestCase):

    def testCommon(self):
        print 'Calling BaseTest:testCommon'
        value = 5
        self.assertEquals(value, 5)

class SubTest1(BaseTest):

    def testSub1(self):
        print 'Calling SubTest1:testSub1'
        sub = 3
        self.assertEquals(sub, 3)


class SubTest2(BaseTest):

    def testSub2(self):
        print 'Calling SubTest2:testSub2'
        sub = 4
        self.assertEquals(sub, 4)

del(BaseTest)

if __name__ == '__main__':
    unittest.main()
202

不要使用多重继承,这样做将来会给你带来麻烦

相反,你可以把你的基类放到一个单独的模块里,或者用一个空类把它包起来:

class BaseTestCases:

    class BaseTest(unittest.TestCase):

        def testCommon(self):
            print('Calling BaseTest:testCommon')
            value = 5
            self.assertEqual(value, 5)


class SubTest1(BaseTestCases.BaseTest):

    def testSub1(self):
        print('Calling SubTest1:testSub1')
        sub = 3
        self.assertEqual(sub, 3)


class SubTest2(BaseTestCases.BaseTest):

    def testSub2(self):
        print('Calling SubTest2:testSub2')
        sub = 4
        self.assertEqual(sub, 4)

if __name__ == '__main__':
    unittest.main()

输出结果:

Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK
169

使用多重继承,这样你的公共测试类就不需要直接继承自TestCase。

import unittest

class CommonTests(object):
    def testCommon(self):
        print 'Calling BaseTest:testCommon'
        value = 5
        self.assertEquals(value, 5)

class SubTest1(unittest.TestCase, CommonTests):

    def testSub1(self):
        print 'Calling SubTest1:testSub1'
        sub = 3
        self.assertEquals(sub, 3)


class SubTest2(unittest.TestCase, CommonTests):

    def testSub2(self):
        print 'Calling SubTest2:testSub2'
        sub = 4
        self.assertEquals(sub, 4)

if __name__ == '__main__':
    unittest.main()

撰写回答