unittest discover - 继承的测试方法被执行两次

unittest discover - Inherited test methods being executed twice

情况一

假设我有一个测试 class 我想重复使用,test_doubled.py:

import unittest

class BaseTestCase(unittest.TestCase):
    def test_something(self):
        self.assertTrue(True)

它包含一个单一的 class、BaseTestCase,它继承自 unittest.TestCase 并具有单一的测试方法。

运行 命令行中的测试按预期产生以下输出:

$ python -m unittest discover -p test_doubled.py -v
test_something (test_doubled.BaseTestCase) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

情况二

现在假设我添加第二个模块,test_doubled_2.py,像这样:

from test_doubled import BaseTestCase

class DerivedTestCase(BaseTestCase):
    pass

它继承自 BaseTestCase,因此我希望它具有相同的测试方法,并且该测试方法将被执行。但是,当我 运行 它时,我得到以下输出:

$ python -m unittest discover -p test_doubled_2.py -v
test_something (test_doubled.BaseTestCase) ... ok
test_something (test_doubled_2.DerivedTestCase) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

似乎 运行 方法两次,一次用于派生 class,一次用于基 class。这根本不是我所期望的。

情况三

我怀疑,通过从 test_doubled_2.py 导入 BaseTestCase,整个 BaseTestCase class 都被执行了。 运行这两个测试模块似乎证实了这一点:

$ python -m unittest discover -p test_doubled\*.py -v
test_something (test_doubled.BaseTestCase) ... ok
test_something (test_doubled.BaseTestCase) ... ok
test_something (test_doubled_2.DerivedTestCase) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

运行 两个模块执行相同的测试方法三次,而我希望它只执行两次。

如何让测试方法在情况2只执行一次,在情况3执行两次?


更新

需要说明的是,BaseTestCase 本身应该是一个可用的测试,因此将其设为混入是行不通的。我只想防止它被额外执行。

这是期望的结果:

  1. 运行 只是 test_doubled.py 中的 BaseTestCase 测试:

    $ python -m unittest discover -p test_doubled.py -v
    test_something (test_doubled.BaseTestCase) ... ok
    
    ----------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    OK
    

    这已经可以正常工作了。

  2. 运行 只是 test_doubled_2.py 中的 DerivedTestCase:

    $ python -m unittest discover -p test_doubled_2.py -v
    test_something (test_doubled_2.DerivedTestCase) ... ok
    
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    OK
    

    应该只执行DerivedTestCase BaseTestCase

  3. 运行 两者:

    $ python -m unittest discover -p test_doubled\*.py -v
    test_something (test_doubled.BaseTestCase) ... ok
    test_something (test_doubled_2.DerivedTestCase) ... ok
    
    ----------------------------------------------------------------------
    Ran 3 tests in 0.000s
    
    OK
    

    测试方法恰好执行了两次,一次针对BaseTestcase,一次针对DerivedTestCase

你可以像这样使用 mixin:

# mixin.py
class TestMixin(object):

    def test_something(self):
        self.assertTrue(True)


# test_base.py
import unittest
from .mixin import TestMixin

class BaseTestCase(TestMixin, unittest.TestCase):

    pass


# test_derived.py
import unittest
from .mixin import TestMixin

class DerivedTestCase(TestMixin, unittest.TestCase):

    pass

不要使用多重继承,它以后会咬你的。

使用

中建议的包装方法