多pytest文件中conftest、fixture结构优化及测试用例复用方案
优化方案推荐
针对你的需求,这里提供两种高效的代码结构优化方案,核心目标是复用测试用例+确保每个数据集只生成一次(避免重复执行耗时操作):
方案一:基于pytest参数化Fixture(推荐,符合pytest生态)
这种方式利用pytest的fixture参数化特性,将测试用例与数据生成逻辑解耦,同时通过session级别作用域保证每个数据集仅生成一次。
步骤1:在conftest.py中定义参数化Fixture
把数据生成逻辑和参数化配置放在conftest.py中,让所有测试文件共享:
import pytest import pandas as pd from typing import Dict def get_list_of_dfs_somewhere(param: str) -> Dict[str, pd.DataFrame]: # 你的原有数据生成逻辑,这里模拟耗时操作 print(f"生成数据集 {param}(耗时10分钟)") return {"df1": pd.DataFrame(), "df2": pd.DataFrame()} # session级别:整个测试会话中,每个param对应的dfs仅生成一次 @pytest.fixture(scope="session", params=["one", "two", "three"]) def dfs(request): return get_list_of_dfs_somewhere(request.param)
步骤2:编写通用测试用例
在单独的测试文件(比如test_dfs.py)中编写一次测试用例,pytest会自动为每个参数执行所有测试:
def test_dfs_type(dfs): assert isinstance(dfs, dict) def test_contains_required_dfs(dfs): assert "df1" in dfs assert "df2" in dfs def test_dfs_not_empty(dfs): for df in dfs.values(): assert not df.empty
方案优势
- 代码极简,无需重复编写测试类
session级Fixture确保每个数据集仅生成一次,即使多个测试文件也能复用- 支持单独运行某类测试:比如执行
pytest -k "one"仅测试参数为"one"的数据集
方案二:基于类继承+类级Fixture(面向对象风格)
如果你偏好面向对象的测试结构,可以通过父类定义通用测试用例,子类仅指定参数,同时用类级Fixture保证每个子类的数据集仅初始化一次。
代码实现
import pytest import pandas as pd from typing import Dict def get_list_of_dfs_somewhere(param: str) -> Dict[str, pd.DataFrame]: print(f"生成数据集 {param}(耗时10分钟)") return {"df1": pd.DataFrame(), "df2": pd.DataFrame()} # 父类:包含所有通用测试用例 class BaseTestDFS: # 子类需重写此参数 param: str = None # 类级Fixture:每个子类仅执行一次初始化 @pytest.fixture(scope="class", autouse=True) def setup_dfs(self): self.dfs = get_list_of_dfs_somewhere(self.param) def test_dfs_type(self): assert isinstance(self.dfs, dict) def test_contains_required_dfs(self): assert "df1" in self.dfs assert "df2" in self.dfs # 子类1:仅指定参数 class TestOne(BaseTestDFS): param = "one" # 子类2:仅指定参数 class TestTwo(BaseTestDFS): param = "two" # 子类3:仅指定参数 class TestThree(BaseTestDFS): param = "three"
方案优势
- 保持类式结构,逻辑清晰,适合习惯面向对象的开发者
- 支持单独运行某子类测试:比如执行
pytest test_file.py::TestOne仅测试第一个数据集
关键注意事项
- Fixture作用域:必须设置
scope="session"(方案一)或scope="class"(方案二),避免重复执行耗时的数据集生成操作 - 只读数据:由于你的数据集在测试中不会被修改,无需担心并发或数据污染问题
- 运行效率:两种方案都能保证每个数据集仅生成一次,最大化节省时间
内容的提问来源于stack exchange,提问作者javierlu
相关产品推荐
相关产品推荐

