如何使用Pytest运行JSON文件中定义的可变数量测试用例
解决pytest批量执行JSON测试用例的问题
问题根源分析
- 循环测试无法定位失败用例:你把所有测试用例放在单个
test_xxx函数的循环里执行,pytest会将整个函数视为一个测试项,断言失败时只会提示该函数失败,无法区分具体是哪个用例出错。 - 参数化测试报错:你的
load_test_cases返回了整个JSON字典(包含Tests键),而非Tests对应的测试用例列表。pytest会把字典的键(比如"Tests")作为参数传入测试函数,自然会触发string indices must be integers错误。
修正后的实现方案
1. 正确加载测试用例
修改加载函数,直接返回测试用例列表:
import json def load_test_cases(): with open('tests.cfg') as f: data = json.load(f) return data['Tests'] # 返回具体的测试用例列表,而非整个字典
2. 参数化测试实现
使用参数化让每个测试用例独立执行,同时为每个用例设置可识别的ID:
import pytest import subprocess import filecmp import os @pytest.mark.parametrize("test_case", load_test_cases(), ids=lambda x: x['name']) def test_executable_output(test_case): # 替换配置中的路径占位符(根据实际环境调整) exe_path = test_case['exe'].replace('%path_to_exe%', '/your/actual/exe/path') log_dir = test_case['logdir'].replace('%path_to_logdir%', '/your/actual/log/dir') reference_dir = test_case['referencedir'].replace('%path_to_referencedir%', '/your/actual/reference/dir') expression_file = test_case['expression'] # 确保日志目录存在 os.makedirs(log_dir, exist_ok=True) # 构造并执行命令,将输出写入指定文件 cmd = [exe_path, test_case['arguments'], expression_file] output_file = os.path.join(log_dir, expression_file) with open(output_file, 'w') as f: # check=True会在命令执行失败时直接抛出异常 subprocess.run(cmd, stdout=f, stderr=f, check=True) # 对比输出文件与参考文件 reference_file = os.path.join(reference_dir, expression_file) assert filecmp.cmp(output_file, reference_file), f"测试用例 {test_case['name']} 输出与参考文件不一致"
关键优化点
- 独立测试项:每个测试用例会被pytest视为单独的测试项,执行时会显示
test_executable_output[test1]、test_executable_output[test2]这样的名称,断言失败时可直接定位到具体用例。 - 路径占位符替换:通过
replace处理配置中的%path_to_exe%等占位符,适配实际运行环境。 - 明确的断言提示:断言失败时会直接显示出错的测试用例名称,快速定位问题。
内容的提问来源于stack exchange,提问作者GreenGrassTunnel
相关产品推荐
相关产品推荐

