pytest中如何实现mocker类一次初始化供多个测试用例复用
问题解答
完全可以,这是pytest测试中消除重复样板代码的常规操作,推荐用pytest fixture封装公共的打补丁、实例初始化逻辑,既可以实现一次编写多处复用,还能保证测试用例之间的隔离性,不会出现测试状态互相污染的问题。
具体实现方式
首先定义一个默认方法级作用域的fixture(pytest fixture默认就是方法级,每个测试用例运行时都会独立执行一次逻辑),把公共的mocker.patch.object和实例初始化逻辑放进去:
import pytest # 保留原有依赖引入,比如retailtableclasses的导入 @pytest.fixture def patched_daterow(mocker): # 统一完成__init__方法的mock mocker.patch.object(retailtableclasses.DateRow, '__init__', return_value=None) # 返回全新的DateRow实例 return retailtableclasses.DateRow()
之后所有需要用到这个打了补丁的DateRow实例的测试方法,直接把patched_daterow作为参数传入即可,不用再重复写补丁和初始化代码:
class Test_DateRow: def test_make_calender_year(self, patched_daterow): patched_daterow.DATE = "9999-01-01" assert patched_daterow.make_calender_year() == "9999" def test_make_month(self, patched_daterow): patched_daterow.MONTH_NUMBER_ISO = 1 assert patched_daterow.make_month() == "January"
注意事项
- 不要为了省代码直接把打补丁、实例初始化的逻辑放到测试类的类属性、或者
setup_class类级别的初始化方法里。这种写法只会在类下所有测试运行前执行一次,一个测试方法里修改了实例属性,会残留到后续其他测试用例中,很容易导致偶发的测试失败,破坏测试隔离性。 - 上述fixture写法的执行效果和你原来每个方法单独写补丁、初始化的效果完全一致,每个测试方法拿到的都是全新打补丁生成的独立实例,没有行为差异。
- 后续如果需要调整mock逻辑(比如新增其他需要mock的依赖方法、修改
__init__的mock返回值),只需要修改fixture里的一处代码即可,不用逐个调整测试方法。
内容的提问来源于stack exchange,提问作者Mark Wekking
相关产品推荐
相关产品推荐

