我正在为基类及其子类编写测试。 大致如下:
@pytest.fixture()
def bc()
return BaseClass(...)
@pytest.mark.parametrize('param1,param2', [...])
def test_baseclass_func1(bc, param1, param2):
assert ...
@pytest.mark.parametrize('param1,param2', [...])
def test_baseclass_func2(bc, param1, param2):
assert ...
@pytest.mark.parametrize('param1,param2', [xyz])
def test_baseclass_func3(bc, param1, param2):
assert ...
@pytest.mark.parametrize('param1,param2', [xyz])
def test_subclass1_func3(param1, param2):
sc1 = SubClass1(...)
assert ...
@pytest.mark.parametrize('param1,param2', [xyz])
def test_subclass2_func3(param1, param2):
sc1 = SubClass2(...)
assert ...
因此,我希望使用固定的BaseClass实例,没有明显的理由在子类上使用Fixture,并且希望避免对func3进行3次测试复制粘贴。
我最好的选择是再使用一个参数化:
@pytest.mark.parametrize('classtype', [
(BaseClass,),
(SubClass1,),
(SubClass2,),
])
@pytest.mark.parametrize('param1,param2', [xyz])
def test_func3(classtype, param1, param2):
class_inst = classtype()
assert ...
但是由于它需要一个额外的BaseClass实例,我想有一个更好的解决方案。我想念什么技巧?
答案 0 :(得分:2)
如果我理解正确,则可以使用indirect parametrization将类参数转换为传递给测试的实例:
List<String> allIds = Stream.of(
person.baseballPlayers.stream().map(BaseballPlayer::getId),
person.mmaFighters.stream().map(MmaFighter::getId),
person.rugbyPlayers.stream().map(RugbyPlayer::getId))
.flatMap(Function.identity())
.collect(Collectors.toList());
由于@pytest.fixture(scope='session')
def instance(request):
cls = request.param
instance = cls()
yield instance
# cleanup instance here if necessary
@pytest.mark.parametrize('instance', (BaseClass, SubClass1, SubClass2,), indirect=True)
@pytest.mark.parametrize('param1,param2', (('spam', 'foo'), ('eggs', 'bar')))
def test_func3(instance, param1, param2):
assert instance.func3(param1, param2) == 'bacon'
固定装置是会话范围的,因此所有创建的实例都将创建一次并在整个测试会话中重复使用。如果您需要更复杂的实例创建,则可以在灯具中进行,以保持测试的清洁。重复使用instance
固定装置的示例:
bc
答案 1 :(得分:1)
也许您对这样的治具感兴趣,该治具在不被调用之前不会创建BaseClass
实例:
@pytest.fixture
def callable_bc():
def _bc():
return BaseClass(...)
return _bc
@pytest.mark.parametrize('classtype', [
(BaseClass,),
(SubClass1,),
(SubClass2,),
])
@pytest.mark.parametrize('param1,param2', [xyz])
def test_func3(classtype, param1, param2, callable_bc):
class_inst = classtype() if classtype != BaseClass else callable_bc()
assert ...