当前位置: 首页 > news >正文

Playwright Python 教程:高级篇

文章目录

    • **目标**
    • **一、网络拦截与模拟(Network Interception & Mocking)**
      • **1. 基本请求/响应拦截**
      • **2. 根据条件修改响应**
      • **3. 模拟网络错误**
    • **二、认证与持久化状态**
      • **1. 保存和恢复认证状态**
      • **2. 多用户场景测试**
    • **三、高级浏览器配置**
      • **1. 模拟设备和地理位置**
      • **2. 代理设置**
    • **四、录制视频与追踪**
      • **1. 录制测试视频**
      • **2. 使用追踪记录**
    • **五、与 Pytest 集成**
      • **1. 基本 Pytest 集成**
      • **2. 使用 Pytest Fixtures**
      • **3. 参数化测试**
    • **六、实战:完整的端到端测试示例**
    • **高级篇总结**
    • **最佳实践建议**

目标

本篇将带你探索 Playwright 的高级功能,让你能够构建更加专业、强大和高效的自动化测试解决方案。我们将涵盖网络拦截、认证持久化、高级配置、视频录制以及与测试框架的集成。


一、网络拦截与模拟(Network Interception & Mocking)

Playwright 允许你拦截和修改网络请求,这对于模拟 API 响应、测试错误处理或减少对外部服务的依赖非常有用。

1. 基本请求/响应拦截

from playwright.sync_api import sync_playwrightdef test_api_interception():with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()# 启用请求拦截page.route("**/api/users", lambda route: route.fulfill(status=200,content_type="application/json",body='{"id": 123, "name": "Mock User"}'))page.goto("https://example.com/user-profile")# 此时页面对 /api/users 的请求将返回我们模拟的数据page.click("#refresh-user")browser.close()

2. 根据条件修改响应

def test_conditional_interception():with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()def handle_route(route):if "api/items" in route.request.url:# 修改响应route.fulfill(status=200,body='[{"id": 1, "name": "Mock Item"}]')else:# 继续正常请求route.continue_()# 注册路由处理程序page.route("**/*", handle_route)page.goto("https://example.com/items")browser.close()

3. 模拟网络错误

def test_network_failure():with sync_playwright() as p:browser = p.chromium.launch(headless=False)page = browser.new_page()# 模拟网络错误page.route("**/api/data", lambda route: route.abort())page.goto("https://example.com/data-page")# 验证错误处理assert page.is_visible("text=Failed to load data")browser.close()

二、认证与持久化状态

1. 保存和恢复认证状态

import os
from playwright.sync_api import sync_playwrightdef test_auth_persistence():with sync_playwright() as p:browser = p.chromium.launch(headless=False)context = browser.new_context()page = context.new_page()# 执行登录操作page.goto("https://example.com/login")page.fill("#username", "testuser")page.fill("#password", "testpass")page.click("#login-btn")# 等待登录完成page.wait_for_url("**/dashboard")# 保存认证状态到文件context.storage_state(path="auth_state.json")browser.close()def test_using_saved_auth():with sync_playwright() as p:browser = p.chromium.launch(headless=False)# 使用保存的认证状态创建上下文context = browser.new_context(storage_state="auth_state.json")page = context.new_page()# 直接访问需要认证的页面page.goto("https://example.com/dashboard")# 验证已登录状态assert page.is_visible("text=Welcome, testuser")browser.close()

2. 多用户场景测试

def test_multiple_users():with sync_playwright() as p:browser = p.chromium.launch(headless=False)# 创建两个独立的上下文(模拟两个用户)user1_context = browser.new_context()user1_page = user1_context.new_page()user2_context = browser.new_context()user2_page = user2_context.new_page()# 用户1登录user1_page.goto("https://example.com/login")user1_page.fill("#username", "user1")user1_page.fill("#password", "pass1")user1_page.click("#login-btn")user1_page.wait_for_url("**/dashboard")# 用户2登录user2_page.goto("https://example.com/login")user2_page.fill("#username", "user2")user2_page.fill("#password", "pass2")user2_page.click("#login-btn")user2_page.wait_for_url("**/dashboard")# 验证两个用户独立会话assert user1_page.is_visible("text=Welcome, user1")assert user2_page.is_visible("text=Welcome, user2")browser.close()

三、高级浏览器配置

1. 模拟设备和地理位置

def test_device_simulation():with sync_playwright() as p:# 使用预定义的设备配置(如 iPhone 11)iPhone_11 = p.devices["iPhone 11"]browser = p.chromium.launch(headless=False)# 创建带有设备模拟的上下文context = browser.new_context(**iPhone_11)page = context.new_page()page.goto("https://example.com")# 验证移动视图assert page.viewport_size["width"] == 414  # iPhone 11 宽度browser.close()def test_geolocation():with sync_playwright() as p:browser = p.chromium.launch(headless=False)# 设置地理位置和权限context = browser.new_context(geolocation={"longitude": 116.397128, "latitude": 39.916527},  # 北京permissions=["geolocation"])page = context.new_page()page.goto("https://maps.example.com")# 触发地理位置请求page.click("#get-location")# 验证位置相关功能assert page.is_visible("text=Beijing")browser.close()

2. 代理设置

def test_with_proxy():with sync_playwright() as p:browser = p.chromium.launch(headless=False,proxy={"server": "http://myproxy.com:8080","username": "user","password": "pass"})context = browser.new_context()page = context.new_page()page.goto("https://example.com")# 验证页面加载成功assert page.title() == "Example Domain"browser.close()

四、录制视频与追踪

1. 录制测试视频

def test_with_video_recording():with sync_playwright() as p:browser = p.chromium.launch(headless=False)# 启用视频录制context = browser.new_context(record_video_dir="videos/")page = context.new_page()# 执行测试操作page.goto("https://example.com")page.click("a")page.wait_for_timeout(1000)# 关闭上下文会自动保存视频context.close()browser.close()

2. 使用追踪记录

def test_with_tracing():with sync_playwright() as p:browser = p.chromium.launch(headless=False)context = browser.new_context()# 开始追踪context.tracing.start(screenshots=True, snapshots=True)page = context.new_page()page.goto("https://example.com")page.click("a")# 停止追踪并保存context.tracing.stop(path="trace.zip")browser.close()# 查看追踪记录
# 使用命令: playwright show-trace trace.zip

五、与 Pytest 集成

1. 基本 Pytest 集成

# test_example.py
import pytest
from playwright.sync_api import Page, expectdef test_example_page(page: Page):page.goto("https://example.com")expect(page).to_have_title("Example Domain")def test_login(page: Page):page.goto("https://example.com/login")page.fill("#username", "testuser")page.fill("#password", "testpass")page.click("#login-btn")expect(page).to_have_url("**/dashboard")

2. 使用 Pytest Fixtures

# conftest.py
import pytest
from playwright.sync_api import Playwright, Browser, BrowserContext@pytest.fixture(scope="session")
def browser(playwright: Playwright):# 启动浏览器(会话级别,所有测试共享)browser = playwright.chromium.launch(headless=False)yield browserbrowser.close()@pytest.fixture
def context(browser: Browser):# 为每个测试创建新的上下文context = browser.new_context()yield contextcontext.close()@pytest.fixture
def page(context: BrowserContext):# 为每个测试创建新的页面page = context.new_page()yield pagepage.close()# test_with_fixtures.py
def test_with_fixtures(page):page.goto("https://example.com")assert page.title() == "Example Domain"

3. 参数化测试

import pytest@pytest.mark.parametrize("username,password,expected", [("correct", "correct", True),("wrong", "correct", False),("correct", "wrong", False),
])
def test_login_combinations(page, username, password, expected):page.goto("https://example.com/login")page.fill("#username", username)page.fill("#password", password)page.click("#login-btn")if expected:expect(page).to_have_url("**/dashboard")else:expect(page).to_have_url("**/login")expect(page).to_have_text("Invalid credentials")

六、实战:完整的端到端测试示例

import pytest
from playwright.sync_api import Page, expectdef test_complete_ecommerce_flow(page: Page):# 1. 浏览产品page.goto("https://demo-shop.example.com")expect(page).to_have_title("Demo Shop")# 2. 搜索产品page.fill("#search-input", "laptop")page.click("#search-button")expect(page).to_have_url("**/search?q=laptop")# 3. 查看产品详情page.click(".product-item:first-child")expect(page).to_have_url("**/product/")# 4. 添加到购物车page.click("#add-to-cart")expect(page.locator("#cart-count")).to_have_text("1")# 5. 查看购物车page.click("#view-cart")expect(page).to_have_url("**/cart")# 6. 结账page.click("#checkout")expect(page).to_have_url("**/checkout")# 7. 填写配送信息page.fill("#name", "John Doe")page.fill("#address", "123 Main St")page.fill("#city", "Anytown")page.select_option("#country", "US")page.click("#continue-to-payment")# 8. 填写支付信息(使用模拟)page.route("**/api/payment", lambda route: route.fulfill(status=200,body='{"success": true, "transactionId": "12345"}'))page.fill("#card-number", "4242424242424242")page.fill("#expiry", "12/25")page.fill("#cvv", "123")page.click("#complete-purchase")# 9. 验证订单确认expect(page).to_have_url("**/order-confirmation")expect(page).to_have_text("Thank you for your order!")

高级篇总结

通过本篇学习,你已经掌握了 Playwright 的高级功能:

  1. 网络拦截与模拟:能够拦截和修改网络请求,实现 API 模拟和错误测试。
  2. 认证持久化:保存和恢复登录状态,提高测试效率。
  3. 高级浏览器配置:模拟设备、地理位置和代理设置。
  4. 录制与追踪:录制测试视频和使用追踪功能进行调试。
  5. Pytest 集成:使用行业标准测试框架组织测试用例。

这些高级技能将使你能够构建更加专业、可靠和高效的自动化测试解决方案。

最佳实践建议

  1. 保持测试独立:每个测试应该能够独立运行,不依赖其他测试的状态。
  2. 使用页面对象模式:将页面元素和操作封装成类,提高代码可维护性。
  3. 合理使用等待:优先使用 Playwright 的自动等待和显式等待,避免固定等待。
  4. 定期维护选择器:随着前端代码变化,定期更新和维护元素选择器。
  5. 并行执行测试:利用 Playwright 的并行执行能力加快测试速度。
http://www.dtcms.com/a/359395.html

相关文章:

  • JDK 22 Windows 64位安装教程(含环境变量配置+验证步骤+附安装包下载)
  • Qwen3_moe模型代码解析
  • 数据结构与算法:线段树(三):维护更多信息
  • 运筹说 第141期 | 启发式算法:用简单规则、破解复杂问题
  • WEB漏洞挖掘篇(一) 基本概念、十大常見WEB漏洞
  • 自底向上了解CPU的运算
  • Google 的 Agent2Agent 协议 (A2A):带示例的指南
  • 「日拱一码」068 机器学习——迁移学习TL
  • SIEPIC工具和PDK安装
  • C#语言入门详解(17)字段、属性、索引器、常量
  • 云计算与服务器
  • 【C#】在一个任意旋转的矩形(由四个顶点定义)内绘制一个内切椭圆
  • 在AlmaLinux或CentOS 8上编译安装ZLMediaKit流媒体服务器
  • Mysql中事务隔离级别有哪些?
  • 【行业洞察】多智能体的风口浪尖--微软MagenticOne/UI
  • android中常见布局及其约束
  • 鸿蒙创新赛活动——Mac提交压缩失败后续
  • [linux仓库]解剖Linux内核:文件描述符(fd)的‘前世今生’与内核数据结构探秘
  • 如何绕过 disable-devtool.js 打开控制台
  • mac Monterey 安装erlang23
  • 【高级】系统架构师 | 信息系统基础
  • Wi-Fi技术——MAC特性
  • Java提供高效后端支撑,Vue呈现直观交互界面,共同打造的MES管理系统,含完整可运行源码,实现生产计划、执行、追溯一站式管理,提升制造执行效率
  • 基于EHO与BP神经网络分类模型的特征选择方法研究(Python实现)
  • 现代C++性能陷阱:std::function的成本、异常处理的真实开销
  • HarmonyOS 应用开发:基于API 12+的现代化实践
  • 第4章从一条记录说起-InnoDB记录结构
  • openssl使用SM2进行数据加密和数据解密
  • Linux中卸载和安装Nginx
  • 第24章学习笔记|用正则表达式解析文本文件(PowerShell 实战)