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

使用自定义Playwright-Python浏览器上下文,如何用Pytest捕获失败用例截图?

问题:Playwright-Python类结构结合pytest实现失败截图

刚接触测试自动化,用Playwright-Python为团队SaaS门户写测试,采用类结构封装Playwright操作,但当前类在__init__中自行初始化sync_playwright、browser、context和page,导致无法在pytest的conftest.py中获取page对象实现失败截图功能。核心需求是捕获失败用例的截图。

原测试代码(sauceAutomation.py):

from playwright.sync_api import Playwright, Page, expect, sync_playwright
import time

class SaucyAutomation:
    def __init__(self):  
        self.playwright = sync_playwright().start()
        self.browser = self.playwright.chromium.launch(headless=False,args=["--start-maximized"])
        self.context = self.browser.new_context(no_viewport=False)
        self.page = self.context.new_page()
        self.environment = None
    
    def login(self, username, password):
        self.page.goto("https://www.saucedemo.com/")
        self.page.locator("//input[@id='user-name']").fill(username)
        self.page.locator("//input[@id='password']").fill(password)
        self.page.locator("//input[@id='login-button']").click()
    
    def burgerNavigate(self,menuItem):
        self.page.locator("//button[@id='react-burger-menu-btn']").click()
        self.page.locator("//a[@id='" + menuItem + "']").click()
    
    def logout(self):
        self.burgerNavigate("logout_sidebar_link")

def test_LoginLogout(): 
    sauceDemo = SaucyAutomation()
    sauceDemo.login("standard_user", "secret_sauce")
    time.sleep(2)
    sauceDemo.logout()

尝试的conftest.py无法正常获取page对象,截图逻辑无法执行。


解决方案

1. 重构测试类,依赖pytest的page fixture

把类的初始化改为接收外部传入的page对象,不再自行创建Playwright实例,适配pytest的fixture体系:

修改后的sauceAutomation.py:

from playwright.sync_api import Page, expect
import time

class SaucyAutomation:
    def __init__(self, page: Page):  
        self.page = page
        self.environment = None
    
    def login(self, username, password):
        self.page.goto("https://www.saucedemo.com/")
        self.page.locator("//input[@id='user-name']").fill(username)
        self.page.locator("//input[@id='password']").fill(password)
        self.page.locator("//input[@id='login-button']").click()
    
    def burgerNavigate(self,menuItem):
        self.page.locator("//button[@id='react-burger-menu-btn']").click()
        self.page.locator("//a[@id='" + menuItem + "']").click()
    
    def logout(self):
        self.burgerNavigate("logout_sidebar_link")

def test_LoginLogout(page): 
    sauceDemo = SaucyAutomation(page)
    sauceDemo.login("standard_user", "secret_sauce")
    time.sleep(2)
    sauceDemo.logout()

2. 完善conftest.py,实现失败截图逻辑

配置Playwright的fixture,并在测试失败时自动截图:

import os
import pytest
from playwright.sync_api import sync_playwright

@pytest.fixture(scope="function")
def page():
    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=False, args=["--start-maximized"])
        context = browser.new_context(no_viewport=False)
        page = context.new_page()
        yield page
        # 测试结束后自动清理资源
        context.close()
        browser.close()

@pytest.hookimpl(tryfirst=True, wrapper=True)
def pytest_runtest_makereport(item, call):
    # 获取测试报告对象
    rep = yield

    # 仅处理测试执行阶段的失败用例
    if rep.when == "call" and rep.failed:
        # 创建screenshots目录(不存在则自动生成)
        screenshot_dir = "screenshots"
        os.makedirs(screenshot_dir, exist_ok=True)
        
        # 生成唯一的截图文件名,避免冲突
        screenshot_path = os.path.join(
            screenshot_dir, 
            f"{item.nodeid.replace('/', '_').replace('::', '_')}.png"
        )
        
        # 从fixture中获取page对象并生成全屏截图
        page = item.funcargs["page"]
        page.screenshot(path=screenshot_path, full_page=True)
        
        # 若使用pytest-html,将截图嵌入测试报告
        pytest_html = item.config.pluginmanager.getplugin("html")
        if pytest_html:
            extra = getattr(rep, "extras", [])
            extra.append(pytest_html.extras.image(screenshot_path))
            rep.extras = extra

    return rep

3. 运行测试

执行命令:

pytest sauceAutomation.py --html=report.html

关键说明

  • 测试类不再自行管理Playwright生命周期,通过pytest fixture注入page对象,确保conftest能获取到有效page实例
  • page fixture的scope设为function,每个测试用例创建独立page,避免测试间状态污染
  • 截图逻辑仅在测试失败时触发,自动保存到screenshots目录,同时支持将截图嵌入pytest-html报告

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:54:51