如何扩展pytest基类并重写fixture
我有一个基础测试类,这个类里实现了一些我想重复使用的测试。我的想法是从这个类继承,并重写一个叫做“fixture”的东西,以便给基础类的测试提供必要的输入数据。大概是这样的:
base_class.py
class TestBase:
@pytest.fixture(scope="module")
def base_settings(self) -> dict:
return None
def test_settings(base_settings):
assert base_settings["value_a"] > base_settings["value_b"]
test_my_class.py
class TestMyClass(TestBase):
# override the base_settings fixture in TestBase
@pytest.fixture(scope="module")
def base_settings(self) -> dict:
return {"value_a": 4, "value_b": 3}
}
现在,当我执行 test_my_class.py 时,我希望 test_settings
测试能通过(因为 value_a 大于 value_b),但实际上它却说 base_settings 是 None——这意味着它使用了基础类里的 fixture,而不是 TestMyClass 里的那个。我该怎么解决这个问题呢?我也尝试过通过 __init__
方法传递参数,但似乎在 pytest 中不支持这样做。
1 个回答
0
我刚刚在pytest 8.0.1中测试了一下,结果和你预期的一样。可能发生的情况是,pytest会自动执行你的TestBase
,这是因为你把它命名为Test...
,所以它就像其他测试类一样被收集起来了。
在下面的例子中,运行了2个测试,其中一个失败是因为我把value_a
和value_b
都设置为3
,这样做是为了证明在不同的测试类之间,测试的环境确实被覆盖了:
import pytest
class Base:
@pytest.fixture(scope="class")
def base_settings(self) -> dict:
return None
def test_settings(self, base_settings):
assert base_settings["value_a"] > base_settings["value_b"]
class TestMyClassA(Base):
@pytest.fixture(scope="class")
def base_settings(self) -> dict:
return {"value_a": 4, "value_b": 3}
class TestMyClassB(Base):
@pytest.fixture(scope="class")
def base_settings(self) -> dict:
return {"value_a": 3, "value_b": 3}
注意:我把scope
改成了class
,因为这样看起来更合理,但原来的module
也应该可以正常工作。