如何让pytest遍历for循环所有用例后再失败,而非中途退出
解决pytest循环测试中途终止的问题
方法1:收集所有失败后统一报告
把循环中出现的所有异常收集到列表里,等所有测试项执行完毕后,再一次性抛出所有失败信息。
修改后的代码示例:
@pytest.fixture def library(): return Library(spec_dir=service_spec_dir) @pytest.fixture def services(library): return list(library.service_map.keys()) def test_properties(library, services): failures = [] for service_name in services: model = library.models[service_name] proxy = library.get_service(service_name) if len(model.properties) != 0: for prop in model.properties: try: method = getattr(proxy, f'get_{prop.name}') method() except Exception as ex: failures.append(f"服务[{service_name}]的属性[{prop.name}]测试失败: {str(ex)}") # 所有测试执行完后,若有失败则汇总抛出 if failures: pytest.fail("\n".join(failures), pytrace=False)
方法2:使用pytest子测试(subtest)
pytest支持Python的subtest功能,每个子测试会独立记录结果,即使某个子测试失败,后续的测试仍会继续执行,最终在报告中显示所有失败的子测试。
代码示例:
import pytest @pytest.fixture def library(): return Library(spec_dir=service_spec_dir) @pytest.fixture def services(library): return list(library.service_map.keys()) def test_properties(library, services): for service_name in services: model = library.models[service_name] proxy = library.get_service(service_name) if len(model.properties) != 0: for prop in model.properties: with pytest.subtest(service=service_name, property=prop.name): method = getattr(proxy, f'get_{prop.name}') method()
这种方式的优势是每个子测试的结果会单独展示,你能清晰看到每个失败项的具体信息,且不会中断整个测试流程。
方法3:动态生成测试用例
如果想让每个服务+属性组合成为独立的测试用例(在测试报告中单独显示),可以使用pytest_generate_tests钩子函数,在测试收集阶段动态生成参数。不过需要提前加载服务列表(确保spec_dir是固定可提前获取的):
import pytest # 提前加载服务列表 service_spec_dir = "你的spec路径" library = Library(spec_dir=service_spec_dir) SERVICE_PROPERTIES = [] for service_name in library.service_map.keys(): model = library.models[service_name] if len(model.properties) != 0: SERVICE_PROPERTIES.extend([(service_name, prop.name) for prop in model.properties]) def pytest_generate_tests(metafunc): if "service_prop_pair" in metafunc.fixturenames: metafunc.parametrize("service_prop_pair", SERVICE_PROPERTIES) @pytest.fixture def library(): return Library(spec_dir=service_spec_dir) def test_properties(library, service_prop_pair): service_name, prop_name = service_prop_pair proxy = library.get_service(service_name) method = getattr(proxy, f'get_{prop_name}') method()
这种方式会把每个服务属性组合变成独立的测试用例,执行时逐个运行,全部执行完毕后展示所有失败用例。
内容的提问来源于stack exchange,提问作者BhanuKiran
相关产品推荐
相关产品推荐

