关于 webapp-testing
面向 Web 开发者的 Playwright 测试技能,涵盖浏览器自动化、端到端测试及跨浏览器和移动设备测试,并介绍网络模拟、视觉捕获与可靠测试实践。
主要功能
- 01跨浏览器自动化
- 02界面交互与断言
- 03网络请求模拟
- 04截图、视频与追踪记录
- 05移动设备模拟
- 06测试可靠性实践
适用场景
- 01创建 Web 端到端测试
- 02检查模拟设备上的响应式布局
- 03模拟 API 以控制测试条件
- 04捕获视觉证据以便调试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ autumnsgrove/ claudeskills --skill webapp-testing安装后在 Claude Code 中输入/webapp-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
README.mdexamples/api-mocking.mdecommerce-testing.mdform-testing.mdlogin-testing.mdmobile-testing.mdpage-object-model.mdreferences/best-practices.mdci-cd-integration.mdcommon-pitfalls.mdsetup-configuration.mdscripts/playwright_helper.pytest_examples.py详细介绍
使用 Playwright 测试 Web 应用
概述
Playwright 是一个功能强大的 Web 测试和自动化框架,支持所有现代浏览器(Chromium、Firefox、WebKit)。它提供可靠、快速且功能全面的自动化能力,包括自动等待、网络控制和全面的测试功能。
在以下情况下使用此技能:
- 为 Web 应用创建端到端测试
- 自动化浏览器交互和工作流
- 在多种浏览器和设备上测试
- 验证 UI/UX 功能和无障碍性
- 模拟 API 并拦截网络请求
- 捕获屏幕截图和视频以进行调试
核心功能
多浏览器测试
- Chromium(Chrome、Edge、Brave)
- Firefox(Mozilla Firefox)
- WebKit(Safari 引擎)
- 跨浏览器兼容性测试
- 在多个浏览器中并行执行
元素交互
- 单击、双击、右键单击
- 通过逼真的键盘模拟输入文本
- 选择下拉菜单和复选框
- 悬停和聚焦交互
- 拖放操作
- 文件上传和下载
断言与验证
- 元素可见性和状态检查
- 文本内容验证
- 属性验证
- URL 和导航断言
- 自定义 expect 匹配器
- 用于多项检查的软断言
屏幕截图和视频捕获
- 全页屏幕截图
- 指定元素的截图
- 测试会话的视频录制
- 视觉对比测试
- 用于调试的跟踪文件
网络拦截
- 模拟 API 响应
- 拦截并修改请求
- 监控网络流量
- 测试离线场景
- 性能监控
移动设备模拟
- 100 多种设备预设(iPhone、Pixel、iPad 等)
- 自定义视口配置
- 触摸事件模拟
- 地理位置测试
- 方向变化
核心测试工作流
1. 基本测试设置
使用 Playwright 的自动等待创建简单测试:
import pytest
from playwright.sync_api import Page, expect
def test_homepage_loads(page: Page):
"""Test that homepage loads successfully."""
page.goto("https://example.com")
expect(page).to_have_title("Example Domain")
expect(page.locator("h1")).to_contain_text("Example Domain")
def test_navigation(page: Page):
"""Test navigation between pages."""
page.goto("https://example.com")
page.click("text=More information")
expect(page).to_have_url("https://www.iana.org/domains/reserved")
2. 表单交互
测试表单填写、验证和提交:
def test_login_form(page: Page):
"""Test login form submission."""
page.goto("https://example.com/login")
# Fill form fields
page.fill("#username", "[email protected]")
page.fill("#password", "SecurePassword123")
page.check("#remember-me")
# Submit and verify
page.click("button[type='submit']")
expect(page).to_have_url("https://example.com/dashboard")
expect(page.locator(".welcome-message")).to_be_visible()
3. API 模拟
模拟 API 响应以进行可控测试:
def test_with_mocked_api(page: Page):
"""Test with mocked API response."""
# Mock API response
page.route("**/api/user", lambda route: route.fulfill(
status=200,
content_type="application/json",
body='{"name": "Test User", "premium": true}'
))
page.goto("https://example.com/profile")
expect(page.locator(".user-name")).to_contain_text("Test User")
4. 移动设备模拟
在移动设备上测试响应式设计:
@pytest.fixture
def mobile_page(playwright):
"""Create mobile browser context."""
iphone = playwright.devices['iPhone 12']
browser = playwright.chromium.launch()
context = browser.new_context(**iphone)
page = context.new_page()
yield page
context.close()
browser.close()
def test_mobile_menu(mobile_page: Page):
"""Test mobile navigation."""
mobile_page.goto("https://example.com")
expect(mobile_page.locator(".hamburger-menu")).to_be_visible()
mobile_page.click(".hamburger-menu")
expect(mobile_page.locator(".mobile-menu")).to_be_visible()
5. 视觉回归
捕获屏幕截图以进行视觉对比:
def test_homepage_screenshot(page: Page):
"""Capture homepage screenshot."""
page.goto("https://example.com")
# Full page screenshot
page.screenshot(path="screenshots/homepage.png", full_page=True)
# Element screenshot
page.locator("header").screenshot(path="screenshots/header.png")
# Screenshot with masks for dynamic content
page.screenshot(
path="screenshots/dashboard.png",
mask=[page.locator(".timestamp"), page.locator(".session-id")]
)
关键测试原则
使用可靠的选择器
# ✅ GOOD: Test IDs and semantic selectors
page.click("[data-testid='submit-button']")
page.click("button:text('Submit')")
page.click("role=button[name='Submit']")
# ❌ BAD: Fragile structural selectors
page.click("div > div > button:nth-child(3)")
利用自动等待
# ✅ GOOD: Playwright auto-waits
page.click("button")
expect(page.locator(".result")).to_be_visible()
# ⚠️ Avoid: Manual waits
time.sleep(2) # Only when absolutely necessary
确保测试隔离
# ✅ GOOD: Clean state between tests
@pytest.fixture(autouse=True)
def clear_state(page: Page):
yield
page.context.clear_cookies()
page.evaluate("localStorage.clear()")
处理不稳定测试
# ✅ GOOD: Wait for specific conditions
page.click("button")
page.wait_for_selector(".result")
result = page.locator(".result").text_content()
# ✅ GOOD: Use soft assertions
expect.soft(page.locator(".title")).to_be_visible()
expect.soft(page.locator(".price")).to_contain_text("$")
页面对象模型
使用页面对象模式组织测试,以便于维护:
class LoginPage:
"""Login page object."""
def __init__(self, page: Page):
self.page = page
self.username_input = page.locator("#username")
self.password_input = page.locator("#password")
self.submit_button = page.locator("button[type='submit']")
def login(self, username: str, password: str):
"""Perform login."""
self.username_input.fill(username)
self.password_input.fill(password)
self.submit_button.click()
# Use in tests
def test_login(page: Page):
login_page = LoginPage(page)
login_page.login("[email protected]", "password123")
expect(page).to_have_url("/dashboard")
常见测试模式
身份验证
@pytest.fixture
def authenticated_page(page: Page):
"""Provide authenticated session."""
page.goto("https://example.com/login")
page.fill("#username", "[email protected]")
page.fill("#password", "password")
page.click("button[type='submit']")
page.wait_for_url("**/dashboard")
yield page
文件操作
# Upload
page.set_input_files("#file-input", "path/to/file.pdf")
# Download
with page.expect_download() as download_info:
page.click("a:text('Download')")
download = download_info.value
download.save_as("downloads/file.pdf")
网络监控
requests = []
page.on("request", lambda req: requests.append(req))
page.goto("https://example.com")
# Verify API calls were made
api_requests = [r for r in requests if "/api/" in r.url]
assert len(api_requests) > 0
运行测试
基本命令
# Install Playwright
pip install playwright pytest-playwright
playwright install
# Run all tests
pytest tests/
# Run specific browser
pytest --browser chromium --browser firefox
# Run in headed mode (see browser)
pytest --headed
# Debug mode
PWDEBUG=1 pytest tests/test_login.py
# Parallel execution
pytest -n auto
# Generate test code
playwright codegen https://example.com
配置
请参阅 references/setup-configuration.md,了解:
- 完整的安装说明
- 项目结构设置
- pytest.ini 配置
- TypeScript 的 playwright.config.ts
- CI/CD 集成示例
质量标准
确保测试符合以下标准:
- 测试彼此独立,且可以按任意顺序运行
- 选择器可靠(测试 ID、语义化选择器)
- 具备适当的错误处理和断言
- 失败时捕获屏幕截图/视频
- 不使用硬编码等待(使用自动等待)
- 在测试之间妥善管理并清理状态
更多资源
详细文档
- 设置与配置 - 安装、项目结构和配置
- 最佳实践 - 选择器策略、等待模式、防止测试不稳定
- 常见问题 - 竞态条件、脆弱的选择器、清理问题
- CI/CD 集成 - GitHub Actions、Docker、部署流水线
代码示例
- 登录测试 - 身份验证流程和会话管理
- 表单测试 - 表单验证、文件上传、下拉菜单
- 电子商务测试 - 购物车、结账流程、优惠券
- API 模拟 - 网络拦截、模拟、监控
- 移动端测试 - 设备模拟、触摸事件、响应式设计
- 页面对象模型 - POM 模式实现
辅助脚本
- Playwright 辅助工具 - 用于常见 Playwright 操作的实用函数
- 测试示例 - 完整的测试套件示例
外部资源
- 官方文档:https://playwright.dev
- Python API:https://playwright.dev/python/docs/intro
- TypeScript API:https://playwright.dev/docs/intro
- 最佳实践:https://playwright.dev/docs/best-practices
- 社区 Discord:https://aka.ms/playwright/discord
故障排查
测试不稳定:
- 使用 Playwright 的自动等待,而不是手动休眠
- 确保设置了恰当的等待条件(
wait_for_selector、wait_for_url) - 使用会自动重试的
expect()断言
选择器无法找到元素:
- 使用浏览器 DevTools 确认元素存在
- 使用 Playwright Inspector:
PWDEBUG=1 pytest test.py - 尝试多种选择器策略(文本、角色、test-id)
测试在 CI 中运行缓慢:
- 启用并行执行:
pytest -n auto - 仅在调试时使用有头模式
- 考虑在相关测试间复用浏览器上下文
如需了解更多故障排查技巧,请参阅常见问题。
评论
支持 Markdown