如何在pytest的UI+API集成框架中仅为UI用例实现失败截图
解决方案
当然可以实现,核心思路是通过自定义pytest标记区分UI和API用例,在浏览器启动逻辑和失败截图逻辑中只针对带UI标记的用例执行。
步骤1:给UI测试用例添加专属标记
在所有UI测试用例的函数/类上添加@pytest.mark.ui标记,API用例则不添加:
# UI测试用例示例 import pytest @pytest.mark.ui def test_login_page(browser): browser.get("https://example.com/login") # 测试逻辑... # API测试用例示例 def test_get_user_api(requests_session): response = requests_session.get("/api/users/1") assert response.status_code == 200
步骤2:修改浏览器启动Fixture,仅针对UI用例生效
在conftest.py中定义browser fixture,通过request对象判断当前测试项是否带有ui标记,只有标记存在时才启动浏览器:
import pytest from selenium import webdriver @pytest.fixture(scope="function") def browser(request): # 检查当前测试用例是否带有ui标记 if "ui" not in request.node.keywords: yield None # API用例直接返回None,不启动浏览器 return driver = webdriver.Chrome() yield driver driver.quit()
步骤3:调整pytest_runtest_makereport钩子,仅为UI用例捕获失败截图
同样在conftest.py的钩子中,先判断测试用例是否带有ui标记,且浏览器实例存在时,才执行截图逻辑:
import pytest import os from datetime import datetime @pytest.mark.hookwrapper def pytest_runtest_makereport(item, call): outcome = yield report = outcome.get_result() # 仅在UI用例执行失败时才截图 if report.when == "call" and report.failed and "ui" in item.keywords: browser = item.funcargs.get("browser") if browser: # 生成截图文件名 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") screenshot_name = f"failed_screenshot_{item.name}_{timestamp}.png" screenshot_path = os.path.join("screenshots", screenshot_name) # 创建截图目录(如果不存在) os.makedirs("screenshots", exist_ok=True) # 保存截图 browser.save_screenshot(screenshot_path) # 可选:将截图路径附加到测试报告中(需安装pytest-html) report.extra = getattr(report, "extra", []) + [ pytest_html.extras.png(screenshot_path) ]
补充说明
- 若未使用
pytest-html生成可视化报告,可直接去掉代码中附加截图到报告的部分。 - 这种标记区分的方式灵活直观,完全适配UI/API混合的测试框架场景,也方便后续扩展其他类型的测试用例规则。
内容的提问来源于stack exchange,提问作者Satyam Agrawal
相关产品推荐
相关产品推荐

