为何使用继承时nosetests会以A、AB、ABC模式重复执行测试?
如何在nosetests中避免子类执行父类测试用例,同时保留层级初始化逻辑
看起来你碰到了nosetests继承机制下的常见问题——子类会自动继承并执行父类中所有test_前缀的方法,导致出现你说的A、AB、ABC式重复执行。下面给你两种可行的解决方案,既能保留各层级的setup_class()执行逻辑,又能让每个测试类只运行自己的测试用例:
方案1:分离Setup基类与测试类(推荐)
核心思路是把通用的setup_class和工具方法放到一个不含测试用例的基类中,然后每个测试类单独继承这个基类,只编写自己的测试方法。这样既保留了层级初始化逻辑,又不会继承父类的测试用例。
修改后的代码如下:
from unittest import TestCase # 仅包含通用setup和工具方法,无测试用例 class BaseTestSetup(TestCase): @classmethod def setup_class(cls): print("defining base class stuff") def assert_something(self, expected, actual): assert expected == actual, "failed test" # 第一个测试类,仅继承Setup基类,只写自己的测试 class FirstClass(BaseTestSetup): @classmethod def setup_class(cls): super().setup_class() print("defining first class stuff") def test_first_class(self): self.assert_something(1, 1) # 第二个测试类,按需继承Setup基类或其他Setup类 class SecondClass(BaseTestSetup): @classmethod def setup_class(cls): super().setup_class() # 如果需要复用FirstClass的setup逻辑,可以直接调用 # FirstClass.setup_class() print("defining second class stuff") def test_second_class(self): self.assert_something(5, 4) # ThirdClass继承SecondClass,仅运行自己的测试 class ThirdClass(SecondClass): @classmethod def setup_class(cls): super().setup_class() print("defining third class stuff") def test_third_class(self): self.assert_something(13, 13)
运行nosetests -v test_.py::ThirdClass时,输出会变成:
test_third_class (test_.ThirdClass) ... ok
同时setup_class会按BaseTestSetup → SecondClass → ThirdClass的顺序执行,完全符合你的需求。
方案2:用@nottest标记父类测试方法
如果你不想重构类结构,可以给父类的测试方法加上@nose.tools.nottest装饰器,让nosetests忽略这些方法。这样子类继承后也不会执行父类的测试用例,但父类本身的测试无法单独运行(除非去掉装饰器)。
示例代码:
from unittest import TestCase from nose.tools import nottest class BaseClass(TestCase): @classmethod def setup_class(cls): print("defining base class stuff") def assert_something(self, expected, actual): assert expected == actual, "failed test" class FirstClass(BaseClass): @classmethod def setup_class(cls): super().setup_class() print("defining first class stuff") @nottest def test_first_class(self): self.assert_something(1, 1) class SecondClass(FirstClass): @classmethod def setup_class(cls): super().setup_class() print("defining second class stuff") @nottest def test_second_class(self): self.assert_something(5, 4) class ThirdClass(SecondClass): @classmethod def setup_class(cls): super().setup_class() print("defining third class stuff") def test_third_class(self): self.assert_something(13, 13)
关于测试执行顺序
如果需要指定测试执行顺序,有两种简单方式:
- 给测试方法命名加上数字前缀,比如
test_01_first、test_02_second,nosetests会按字母/数字顺序执行; - 使用
nose-ordering插件,安装后用@order装饰器指定顺序。
内容的提问来源于stack exchange,提问作者Meeky333
相关产品推荐
相关产品推荐

