如何使用双层@pytest.mark.parametrize实现两个表格的逐单元格测试
解决方案
你预想的写法无法实现,因为@pytest.mark.parametrize是在测试收集阶段(所有测试用例运行前)执行的,无法获取上层测试函数运行时的动态参数。要实现每个单元格独立校验、单个失败不影响其他测试的需求,直接用双层@pytest.mark.parametrize展开所有测试组合即可:
完整实现代码
import pytest import pandas as pd import warnings # 预先定义测试数据并转为DataFrame expected_df = pd.DataFrame({ "Parametre 1":{"Objet 1":"Yes","Objet 2":"Yes","Objet 3":"Yes"}, "Parametre 2":{"Objet 1":"No","Objet 2":"Yes","Objet 3":"Yes"} }) obtained_df = pd.DataFrame({ "Parametre 1":{"Objet 1":"Non","Objet 2":"Yes","Objet 3":"Yes"}, "Parametre 2":{"Objet 1":"No","Objet 2":"Yes","Objet 3":"Yes"} }) # 双层parametrize展开所有「对象+参数列」的组合,每个组合对应1个独立测试用例 @pytest.mark.parametrize("objet", expected_df.index.values) @pytest.mark.parametrize("column", expected_df.columns.values) def test_cell(objet, column): # 校验对象存在于实际结果中 assert objet in obtained_df.index.values, f"对象{objet}不存在于实际结果表" obtained_cell = obtained_df.loc[objet, column] expected_cell = expected_df.loc[objet, column] # 按规则校验 if expected_cell == 'Yes': assert obtained_cell == expected_cell, f"校验失败:对象{objet}的{column}列,预期{expected_cell},实际{obtained_cell}" else: if obtained_cell == 'Yes': warnings.warn(UserWarning(f"标注错误:对象{objet}的{column}列预期非Yes,实际为Yes"))
效果说明
pytest会自动生成 3个对象 × 2个参数列 = 6个独立测试用例,任意一个用例断言失败都不会中断其他用例的执行,完全符合你的需求。
如果不想在测试函数内做单元格取值,也可以提前把所有测试参数预生成,用单层parametrize实现:
# 提前构造所有测试参数 test_params = [] for objet in expected_df.index: for column in expected_df.columns: test_params.append(( objet, column, expected_df.loc[objet, column], obtained_df.loc[objet, column] )) @pytest.mark.parametrize("objet, column, expected_cell, obtained_cell", test_params) def test_cell(objet, column, expected_cell, obtained_cell): if expected_cell == 'Yes': assert obtained_cell == expected_cell, f"校验失败:对象{objet}的{column}列,预期{expected_cell},实际{obtained_cell}" else: if obtained_cell == 'Yes': warnings.warn(UserWarning(f"标注错误:对象{objet}的{column}列预期非Yes,实际为Yes"))
内容的提问来源于stack exchange,提问作者Nathanb96
相关产品推荐
相关产品推荐

