如何为PyTest传入命令行文件路径参数加载为Pandas DF
PyTest 命令行动态传入CSV文件路径实现方案
不需要用常规的@pytest.mark.parametrize做静态参数化,直接用PyTest自带的钩子+fixture机制就能实现,全程不用改测试脚本内部代码,同事拿到直接传参就能跑,具体实现分三步:
1. 注册自定义命令行参数
在测试用例同级目录下的conftest.py(没有就新建一个)里加钩子函数,注册--csv-path参数用来接收文件路径:
import pytest from pathlib import Path def pytest_addoption(parser): parser.addoption( "--csv-path", action="store", default=None, help="待数据校验的目标CSV文件路径,支持相对/绝对路径", type=Path )
这里直接指定参数类型为Path,自动处理跨平台路径格式问题,不用自己写字符串转路径的兼容逻辑。
2. 编写公共加载fixture
还是在conftest.py里加会话级fixture,统一处理参数读取、路径合法性校验、CSV加载成Pandas DF的逻辑,所有用例可以直接复用:
@pytest.fixture(scope="session") def load_target_csv(request): csv_path = request.config.getoption("--csv-path") # 没传参直接给出明确提示,不用等pandas抛底层IO错误 if not csv_path: pytest.fail("未指定待校验CSV文件,请执行命令时添加--csv-path参数,示例:pytest test_data_validate.py --csv-path ./prod_data/order_202405.csv") if not csv_path.exists(): pytest.fail(f"指定的CSV文件不存在,请检查路径:{csv_path.resolve()}") if csv_path.suffix.lower() != ".csv": pytest.fail(f"仅支持.csv格式文件,当前传入文件后缀为{csv_path.suffix}") import pandas as pd # 直接返回加载好的DF,用例里不用重复写读文件代码 return pd.read_csv(csv_path)
fixture设为session级别的好处是整个测试流程只会读一次文件,不会每个校验用例都重复做IO加载,校验逻辑多的时候能省不少时间。
3. 测试用例直接调用fixture
你之前写的校验逻辑基本不用改,直接把fixture作为参数传入即可:
# test_data_validate.py def test_duplicate_value_check(load_target_csv): # 原有重复值排查逻辑,直接用传入的DF即可 dup_cnt = load_target_csv.duplicated().sum() assert dup_cnt == 0, f"数据集存在{dup_cnt}条重复记录" def test_field_dtype_check(load_target_csv): # 原有数据类型校验逻辑 expected_type_map = { "order_id": "int64", "pay_time": "datetime64[ns]", "pay_amount": "float64" } for col, expected_type in expected_type_map.items(): actual_type = str(load_target_csv[col].dtype) assert actual_type == expected_type, f"字段[{col}]类型不符合要求,预期{expected_type},实际{actual_type}"
使用方式
同事拿到脚本之后,不需要改任何代码,直接在命令行执行时传参即可:
- 单文件校验:
pytest test_data_validate.py --csv-path ./test_data/user_info.csv - 批量跑目录下所有校验用例:
pytest ./data_check_suite/ --csv-path /data/prod/202405_sales.csv
如果后续需要支持一次传入多个CSV批量校验,只要把pytest_addoption里的action参数从store改成append,fixture里循环读取所有路径返回DF列表即可,核心校验逻辑不用调整。
内容的提问来源于stack exchange,提问作者bobbyburrito
相关产品推荐
相关产品推荐

