Pytest类作用域fixture调用参数化类作用域fixture时行为异常
核心原因
你遗漏了pytest间接参数化与fixture生命周期绑定的核心规则:间接参数化的fixture实例生命周期,优先和参数化本身的作用域绑定,而非完全由fixture声明的scope参数决定。
你当前使用的pytest 7.0.1版本中,写在类或测试方法上的@pytest.mark.parametrize默认作用域为function级:即便你给iteration、some_fixture都声明了scope='class',只要iteration是被函数级参数化驱动的间接参数化fixture,pytest就会为每一组参数值生成独立的fixture实例,所有依赖该fixture的同级别fixture(也就是你写的some_fixture),也会跟随每个参数实例完成创建、销毁流程,表现得和function作用域一致。
你之前尝试给parametrize添加scope='class'参数不生效,是因为这个配置项是pytest 7.1版本才正式上线的功能,7.0.1版本无法识别该参数,自然不会生效。
运行逻辑对应说明
你贴出的执行输出完全符合上述规则:
- 运行第一组参数
iteration=1时,pytest为该参数值创建一套class级fixture实例(包括iteration和依赖它的some_fixture),执行对应测试用例 - 切换到第二组参数
iteration=2前,上一组参数绑定的fixture集合已经完成对应测试执行,会先触发销毁逻辑(对应输出中先打印some_fixture-class-end、iteration-class-end),再为新参数值创建新的fixture实例,执行第二个测试用例 - 所有参数组执行完成后,最后一组参数绑定的fixture才会触发销毁逻辑
当你移除some_fixture对iteration的依赖后,some_fixture不再和多实例的参数化fixture绑定,就会回归class级fixture的默认行为,整个测试类仅创建一次。
解决方案
根据你的实际场景二选一即可:
- 方案一:将pytest版本升级到7.1及以上,之后给parametrize标记显式添加
scope='class'配置,即可让整个测试类的所有参数组共用同一套class级fixture实例,修改后的标记写法如下:@pytest.mark.parametrize('iteration', range(1, ITERATIONS + 1), indirect=True, scope='class') - 方案二:如果暂时无法升级pytest,可以将参数化逻辑从测试标记迁移到
pytest_generate_tests钩子中,手动指定参数化作用域为class级,避免默认函数级参数化拆分fixture实例。
内容的提问来源于stack exchange,提问作者igor
相关产品推荐
相关产品推荐

