You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在py.test测试失败时调用debug方法?(Selenium场景)

刚好我之前做复杂Selenium自动化测试时也碰到过类似的需求,给你几个亲测可行的方案,你可以根据自己的场景选:

方案1:在Driver Fixture中嵌入异常捕获逻辑

这是最直接的方式,把debug逻辑和driver的生命周期绑定在一起,不管是初始化阶段还是测试执行阶段出问题,都能触发调试:

import pytest
from selenium import webdriver

def debug(driver):
    """自定义调试函数,包含截图、打印源码和关闭driver"""
    try:
        # 保存截图,用会话ID命名避免覆盖
        driver.save_screenshot(f"debug_screenshot_{driver.session_id}.png")
        # 打印页面源码,也可以保存到文件方便查看
        print("\n=== 调试用页面源码开始 ===")
        print(driver.page_source)
        print("=== 调试用页面源码结束 ===\n")
    finally:
        # 不管调试步骤是否成功,都确保关闭driver,避免浏览器残留
        driver.quit()

@pytest.fixture(scope="function")
def driver():
    # 初始化driver,这里可以加你的复杂初始化流程
    driver = webdriver.Chrome()
    try:
        # 这里可以放初始化操作,比如设置隐式等待、登录前置操作等
        driver.implicitly_wait(10)
        yield driver  # 把driver交给测试函数使用
    except Exception as e:
        # 初始化或测试过程中抛出异常时,调用debug函数
        debug(driver)
        raise  # 重新抛出异常,让pytest标记测试为失败状态
    finally:
        # 如果测试正常完成,正常关闭driver
        driver.quit()

这个方案的优势:

  • 不需要修改每个测试函数,逻辑集中在fixture里
  • 覆盖了初始化阶段和测试执行阶段的所有异常
  • 确保driver一定会被关闭,不会有残留进程

方案2:用Pytest全局钩子统一处理异常

如果希望全局所有测试用例都自动触发debug逻辑,可以用pytest的pytest_exception_interact钩子,它会在测试抛出异常时自动触发:

import pytest

def debug(driver):
    try:
        driver.save_screenshot(f"debug_{driver.session_id}.png")
        # 把页面源码保存到HTML文件,比打印更方便查看
        with open(f"page_source_{driver.session_id}.html", "w", encoding="utf-8") as f:
            f.write(driver.page_source)
        print(f"调试信息已保存:截图和页面源码(会话ID:{driver.session_id})")
    finally:
        driver.quit()

@pytest.hookimpl(tryfirst=True)
def pytest_exception_interact(node, call, report):
    # 检查当前测试用例是否依赖driver fixture
    if "driver" in node.fixturenames:
        # 获取当前测试用例使用的driver实例
        driver = node.funcargs["driver"]
        # 调用调试函数
        debug(driver)

这个方案的优势:

  • 完全无侵入,不需要修改fixture或测试函数
  • 全局生效,所有用到driver的测试用例出问题都会自动调试
  • 可以通过会话ID区分不同测试的调试文件,避免覆盖

方案3:在单个测试函数中手动捕获异常

如果只需要针对特定测试用例做调试,或者想在关键步骤单独处理,可以直接在测试函数里用try-except包裹:

def test_login_flow(driver):
    try:
        # 关键操作:打开页面、输入账号密码等
        driver.get("my page")
        # 其他测试步骤...
    except Exception as e:
        # 出现异常时调用debug
        debug(driver)
        raise  # 必须重新抛出异常,否则pytest会认为测试通过

这个方案的优势:

  • 灵活性高,只针对需要调试的测试用例生效
  • 可以精确控制哪些步骤触发调试逻辑

注意事项:

  1. 不管用哪个方案,debug函数里一定要用finally块来关闭driver,确保即使截图/打印源码失败,也不会残留浏览器进程
  2. 如果你的driver fixture是class或module级别的,要注意调试后driver被关闭,后续测试可能需要重新初始化
  3. 可以根据需求扩展debug函数,比如保存cookies、打印控制台日志等,方便定位问题

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:31:37