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

playwright 最佳实践

playwright 最佳实践

Playwright 是由微软开发的现代化 E2E 自动化测试框架。

🎬 一、Playwright 简介

1. Playwright 是什么?

Playwright 是由微软开发的现代化 E2E 自动化测试框架,支持多浏览器(Chromium、Firefox、WebKit)和多语言(Node.js、Python、Java、C#),特别适合做 UI 自动化测试和爬虫。

示例代码

import { test, expect } from '@playwright/test';test('使用 Google 搜索', async ({ page }) => {// 进入 google 搜索页await page.goto('https://www.google.com');// 模拟手动输入 Playwrightawait page.fill('input[name="q"]', 'Playwright');// 模拟回车确认搜索await page.keyboard.press('Enter');// 校验await expect(page.locator('#search')).toContainText('Playwright');
});

2. Playwright 能做什么?

  • 端到端自动化测试
    • 登录、下单、支付、弹窗、表单交互等全流程模拟
  • 浏览器爬虫
    • 提取页面信息,模拟滚动、点击、登录等
  • 回归测试
    • CI/CD 中检测新版本是否破坏 UI 功能
  • 可视化回归测试
    • 截图、视频、trace,查看测试中实际发生了什么

3. Playwright 特性

特性说明
✅ 多浏览器支持支持 Chromium (Chrome/Edge)FirefoxWebKit (Safari)
✅ 多语言支持支持 JavaScript/TypeScriptPythonJavaC#/.NET
✅ 自动等待机制自动等待元素出现、可点击、导航完成等,不容易出 flaky(随机失败)测试
✅ 原生支持 iframe、多页签轻松处理复杂页面中的 iframe、弹窗、多标签页
✅ 内置测试运行器自带功能完整的 test runner(类似 Jest + Mocha + Chai + Puppeteer)
✅ 网络拦截与 Mock可模拟后端接口,进行无网络依赖测试
✅ 跨平台运行支持 Windows、macOS、Linux、本地/CI 环境运行
✅ 丰富调试工具提供 UI trace viewer、codegen 工具、screenshot/video trace

🚀 二、Playwright 实践

1. Playwright 安装依赖

tests/├── login.spec.ts├── dashboard.spec.ts└── utils/└── auth.ts
playwright.config.ts

官网参考

$ npm init playwright@latest
# 或手动安装
$ npm install -D @playwright/test
$ npx playwright install

2. 测试用例基础结构

如何编写测试用例

import { test, expect } from '@playwright/test';
// test.describe 理解为测试分组
test.describe('用户模块', () => {// test 理解为定义了一个测试用例test('登录', () => {// 登录相关测试});test('注册', () => {// 注册相关测试});
});

3. 常见 API 用法

✅ 页面导航 & 交互

await page.goto('https://example.com');        // 打开页面
await page.click('text=Sign in');              // 点击按钮或链接
await page.fill('#username', 'myname');        // 填写输入框
await page.press('#input', 'Enter');           // 模拟按键
await page.selectOption('select#role', 'admin'); // 选择下拉框选项

✅ 元素等待

await page.waitForSelector('#submit-btn');        // 等待出现并可见
await page.waitForSelector('.modal', { state: 'hidden' });  // 等待消失
await expect(page.locator('h1')).toHaveText('Hello');       // 推荐写法

✅ 截图 / 视频 / Trace

await page.screenshot({ path: 'screenshot.png' });   // 截图
await page.context().tracing.start({ screenshots: true, snapshots: true });
await page.context().tracing.stop({ path: 'trace.zip' });  // 查看 UI 行为

✅ 请求拦截 / mock 接口

await page.route('**/api/**', route =>route.fulfill({ status: 200, body: JSON.stringify({ data: [] }) })
);

4. 模块封装

封装一个登录模块

// login.page.ts
export class LoginPage {constructor(private page: Page) {}async login(username: string, password: string) {await this.page.fill('#user', username);await this.page.fill('#pass', password);await this.page.click('text=Login');}
}

5. 配置项

  • 自定义配置项
// playwright.config.ts
import { defineConfig } from '@playwright/test';export default defineConfig({use: {// Emulates `'prefers-colors-scheme'` media feature.colorScheme: 'dark',// Context geolocation.geolocation: { longitude: 12.492507, latitude: 41.889938 },// Emulates the user locale.locale: 'en-GB',// Grants specified permissions to the browser context.permissions: ['geolocation'],// Emulates the user timezone.timezoneId: 'Europe/Paris',// Viewport used for all pages in the context.viewport: { width: 1280, height: 720 },},
});

5. demo 演示

  • ✅ 示例 1:模拟登录
import { test, expect } from '@playwright/test';test.describe('登录功能', () => {test.beforeEach(async ({ page }) => {await page.goto('https://yourapp.com/login');});test('登录成功跳转到首页', async ({ page }) => {await page.fill('#username', 'robbie');await page.fill('#password', 'correct_password');await page.click('button[type="submit"]');await expect(page).toHaveURL(/dashboard/);await expect(page.locator('text=欢迎回来')).toBeVisible();});test('登录失败提示错误', async ({ page }) => {await page.fill('#username', 'robbie');await page.fill('#password', 'wrong_password');await page.click('button[type="submit"]');await expect(page.locator('.error')).toHaveText('用户名或密码错误');});
});
  • ✅ 示例 2:等待 loading 消失再点击按钮
test('加载后点击按钮', async ({ page }) => {await page.goto('https://yourapp.com/profile');// 等待 loading 动画结束await page.waitForSelector('.loading-spinner', { state: 'hidden' });// 再点击保存按钮await page.click('button.save');await expect(page.locator('.toast')).toHaveText('保存成功');
});
  • ✅ 示例 3:表单验证(空值、错误格式)
test('表单校验错误提示', async ({ page }) => {await page.goto('https://yourapp.com/register');await page.click('button[type="submit"]');await expect(page.locator('#email-error')).toHaveText('邮箱不能为空');await expect(page.locator('#password-error')).toHaveText('密码不能为空');
});
  • ✅ 示例 4:打开弹窗并验证内容
test('打开弹窗并验证内容', async ({ page }) => {await page.goto('https://yourapp.com');await page.click('button.view-detail');await page.waitForSelector('.modal-content');await expect(page.locator('.modal-title')).toHaveText('详情信息');
});
  • ✅ 示例 5:拦截并 Mock 接口返回数据
test('拦截接口并返回自定义数据', async ({ page }) => {await page.route('**/api/user/info', route =>route.fulfill({status: 200,contentType: 'application/json',body: JSON.stringify({ name: '测试用户', id: 1 }),}));await page.goto('https://yourapp.com/user');await expect(page.locator('.username')).toHaveText('测试用户');
});
  • ✅ 示例 6:截图用于 UI 回归测试
test('页面截图', async ({ page }) => {await page.goto('https://yourapp.com/dashboard');await page.screenshot({ path: 'screenshots/dashboard.png', fullPage: true });
});
  • ✅ 示例 7:使用 test.step 添加步骤标记(增强 Trace 可读性)
test('使用步骤结构化流程', async ({ page }) => {await test.step('打开登录页', async () => {await page.goto('https://yourapp.com/login');});await test.step('填写登录表单', async () => {await page.fill('#username', 'robbie');await page.fill('#password', '123456');});await test.step('点击登录按钮并跳转', async () => {await page.click('button[type="submit"]');await expect(page).toHaveURL(/dashboard/);});
});
  • ✅ 示例 8:使用 test.use 指定不同登录状态

Playwright 支持通过 test.use() 给某些 describe 套件设置专属上下文(例如已登录用户):

test.describe.use({ storageState: 'logged-in-state.json' });test('已登录用户访问主页', async ({ page }) => {await page.goto('https://yourapp.com');await expect(page.locator('.username')).toHaveText('robbie');
});

参考文档

  • playwright 官方网站
  • playwright 指引文档
  • playwright API
  • playwright 发布记录
http://www.xdnf.cn/news/15974.html

相关文章:

  • 【web安全】SQL注入与认证绕过
  • MPLS-LDP
  • 小红书 MCP 服务器
  • ADC和DMA简述
  • 渗透笔记(XSS跨站脚本攻击)
  • Linux之dpkg--命令的用法
  • 软件测试-Bug
  • 41.FeignClient整合Sentinel
  • 【C++】C++入门
  • 氛围编码(Vice Coding)的工具选择方式
  • [CVPR]DVFL-Net:用于时空动作识别的轻量级蒸馏视频调焦网络
  • 华为开源自研AI框架昇思MindSpore应用案例:基于ERNIE模型实现对话情绪识别
  • Spring 事务和事务传播机制
  • CSS 单位完全指南:掌握 em、rem、vh、vw 等响应式布局核心单位
  • 仙盟数据库应用-外贸标签打印系统 前端数据库-V8--毕业论文-—-—仙盟创梦IDE
  • 单链表专题
  • docker compose 编排容器 mysql Springboot应用
  • 使用pnpm安装项目的生产依赖dependencies和开发依赖devDependies及pnpm工作空间等简单使用方法说明
  • 全面解析MySQL(2)——CRUD基础
  • SQL 调优第一步:EXPLAIN 关键字全解析
  • HTTP1-HTTP2-HTTP3简要概述
  • day 12 看门狗外设
  • 运行时常量池 和 字符串常量池 区别
  • 【数据集】NOAA 全球监测实验室(GML)海洋边界层(MBL)参考简介
  • 虚拟机VMware安装国产桌面系统统信UOS
  • 传输层协议 TCP
  • 【Python数据采集】Python爬取小红书搜索关键词下面的所有笔记的内容、点赞数量、评论数量等数据,绘制词云图、词频分析、数据分析
  • docker-compose启动前后端分离项目(单机)
  • ARFoundation系列讲解 - 101 VisionPro 真机调试
  • MySQL EXPLAIN 解读