如何为继承同一接口的多个实现类编写pytest参数化测试用例
优雅实现方案
推荐两种可直接复用、扩展性强的实现方式,优先选择第二种解耦度更高的方案:
方案1:单fixture多参数组合
直接把实现类和输入值合并为fixture的参数,适合参数间关联度高的场景:
import pytest from xxx import A, B1, B2, input1, input2, expectation class TestA: # 直接定义所有参数组合,也可以用itertools.product自动生成 @pytest.fixture(params=[ (B1, input1), (B1, input2), (B2, input1), (B2, input2) ]) def some_data(self, request): impl_cls, input_val = request.param return impl_cls(input_val) @pytest.mark.parametrize("with_object", [pytest.lazy_fixture("some_data")]) def test_do_something(self, with_object): assert with_object.do_something() == expectation
如果后续要新增实现类或者输入参数,直接往fixture的params里加对应项即可。如果组合较多可以用itertools.product简化写法:
from itertools import product # params部分替换为: params=list(product([B1, B2], [input1, input2]))
方案2:拆分fixture(更推荐)
把实现类、输入值拆分为独立fixture,完全解耦,后续扩展成本最低:
import pytest from xxx import A, B1, B2, input1, input2, expectation class TestA: # 实现类参数fixture,新增实现类仅需修改这里 @pytest.fixture(params=[B1, B2]) def impl_cls(self, request): return request.param # 输入值参数fixture,新增测试输入仅需修改这里 @pytest.fixture(params=[input1, input2]) def input_val(self, request): return request.param @pytest.fixture def some_data(self, impl_cls, input_val): return impl_cls(input_val) # 原测试代码完全不需要修改 @pytest.mark.parametrize("with_object", [pytest.lazy_fixture("some_data")]) def test_do_something(self, with_object): assert with_object.do_something() == expectation
这种方案下,新增B3实现类只要往impl_cls的params里加B3,新增input3只要往input_val的params里加input3,所有相关测试会自动覆盖所有组合,不需要改其他代码。
内容的提问来源于stack exchange,提问作者Bubaya
相关产品推荐
相关产品推荐

