为何不能在测试中直接调用pytest fixture?
为什么不能直接调用pytest fixture?附带参数fixture的正确用法
为什么直接调用fixture会报错?
pytest的fixture不是普通函数,它是由pytest框架全权管理的组件。框架会负责:
- 处理fixture的生命周期(比如测试前初始化、测试后清理)
- 实现依赖注入(自动传递fixture给测试函数)
- 控制作用域(比如module级、session级的fixture复用)
- 处理fixture之间的依赖关系
当你直接调用被@pytest.fixture装饰的函数时,等于绕过了pytest的管理机制,框架无法完成上述工作,所以会抛出错误提示你必须通过参数注入的方式使用。
你的fixture存在的小问题
先修正你代码里的两处语法错误:
open(file_path / f"{file_name"少了闭合的},应该是file_path / f"{file_name}"- 返回类型注解
-> json错误,json是模块不是类型,应该用-> dict(或者-> Any,如果不确定返回结构)
带参数fixture的正确用法:工厂模式
因为你的fixture需要动态传入sub_directory和file_name,不能直接用普通的参数注入,这时候用工厂模式最合适:
- 让fixture返回一个内部函数,这个内部函数接收你需要的参数
- 测试函数通过参数注入拿到这个工厂函数,再调用它传入具体参数
修正后的fixture代码:
import json from pathlib import Path import pytest @pytest.fixture() def get_fixture_data_for(): def _get_data(sub_directory: str, file_name: str) -> dict: file_path = Path(__file__).parent / sub_directory with open(file_path / file_name, 'r') as j: data = json.load(j) return data return _get_data
对应的测试代码:
def test_file_is_valid(get_fixture_data_for): data = get_fixture_data_for('some_subdir', 'some_filename.json') # 后续测试逻辑 ...
为什么要这么设计?
这种模式既保留了pytest对fixture的管理能力(比如如果给这个fixture设置scope="session",整个测试会话只会创建一次工厂函数),又能满足你动态传参的需求。如果直接调用fixture,不仅会触发错误,还会失去pytest提供的所有fixture特性,比如无法复用实例、无法执行清理逻辑等。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

