pytest:类级参数化与类作用域fixture结合问题求助
问题原因分析
你碰到的ScopeMismatch错误本质是作用域不兼容:@pytest.mark.parametrize装饰测试类时,生成的fruit参数默认是函数作用域(和测试方法同级别),而你定义的get_fruit是类作用域。pytest不允许高作用域的fixture引用低作用域的变量/参数,因为类作用域的fixture初始化时机早于函数作用域参数,无法获取到参数值。
正确实现方案
要实现「每个参数值对应一个测试类实例,类内所有测试共享一次网络调用」的需求,需要将参数化逻辑和类作用域fixture正确绑定,具体可以通过indirect=True参数实现:
import pytest # 标记indirect=True,让参数传递给同名fixture @pytest.mark.parametrize('fruit', ['apple', 'banana'], indirect=True) class TestFruit: @pytest.fixture(scope='class') def fruit(self, request): # 通过request.param获取参数化的水果名称 fruit_name = request.param print(f'Network call to GET {fruit_name}. This is expensive.') return fruit_name def test_fruit_name_valid(self, fruit): print(f'The fruit is {fruit}.') # 根据参数值调整断言,原断言写法会导致测试失败 assert fruit in ['apple', 'banana'] def test_fruit_exists(self, fruit): print(f'Fruit in test_fruit2 is {fruit}') assert fruit in ['apple', 'banana']
关键说明
- indirect=True的作用:告诉pytest不要直接把
apple、banana作为参数传递给测试方法,而是传递给同名的fruitfixture,由fixture处理参数。 - 类作用域fixture的参数获取:通过
request.param拿到参数化的值,确保每个参数对应一个类实例,fixture只执行一次网络调用。 - 修正断言逻辑:原代码中
test_fruit2断言get_fruit == 'orange'必然失败,test_fruit的断言也仅在参数为apple时成立,需要根据实际测试目标调整断言逻辑。
内容的提问来源于stack exchange,提问作者Davina Armstrong
相关产品推荐
相关产品推荐

