PlayWright自动化测试入门:从零开始搭建你的第一个测试脚本

当你在搜索引擎输入"自动化测试"时,总能看到PlayWright这个关键词频繁出现。作为微软开源的现代化测试框架,它正以惊人的速度改变着测试工程师的工作方式。想象一下,你刚接手一个新项目,需要在Chrome、Firefox和Safari上同时验证登录流程的兼容性。传统方式可能需要配置不同的驱动和等待策略,而PlayWright让你用同一套代码就能搞定所有浏览器。

1. 环境准备:搭建你的测试实验室

在开始编写第一个测试脚本前,我们需要确保开发环境准备就绪。与大多数测试框架不同,PlayWright的安装过程经过精心设计,即使是新手也能轻松完成。

1.1 安装Node.js运行环境

PlayWright支持多种语言,但JavaScript/TypeScript版本拥有最完整的特性和最活跃的社区支持。建议从Node.js开始你的PlayWright之旅:

# 检查Node.js是否安装
node -v
# 如果没有安装,推荐使用nvm管理Node版本
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
nvm install --lts

提示:Windows用户可以直接从官网下载安装包,但使用nvm可以更方便地切换不同项目所需的Node版本。

1.2 初始化项目并安装PlayWright

创建一个干净的目录作为你的测试项目空间:

mkdir playwright-demo && cd playwright-demo
npm init -y
npm install --save-dev playwright

安装完成后,PlayWright会自动下载所需的浏览器二进制文件。这个过程可能会花费几分钟,取决于你的网络速度。如果想跳过浏览器下载(比如后续再按需安装),可以使用:

PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --save-dev playwright

1.3 验证安装是否成功

创建一个简单的验证脚本check-install.js:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  console.log(await page.title());
  await browser.close();
})();

运行这个脚本:

node check-install.js

如果看到输出"Example Domain",恭喜你,环境配置已经完成!

2. 编写第一个真正的测试脚本

现在让我们创建一个有实际意义的测试用例:验证GitHub搜索功能。这个例子涵盖了页面导航、元素定位、输入操作和结果断言等核心测试场景。

2.1 创建测试文件结构

建议采用以下目录结构组织你的测试代码:

playwright-demo/
├── tests/
│   ├── github.spec.js
│   └── fixtures/
├── package.json
└── playwright.config.js

2.2 编写GitHub搜索测试

在tests/github.spec.js中添加以下内容:

const { test, expect } = require('@playwright/test');

test('GitHub搜索应该返回相关结果', async ({ page }) => {
  // 导航到GitHub
  await page.goto('https://github.com');
  
  // 定位搜索框并输入查询
  const searchBox = page.getByPlaceholder('Search GitHub');
  await searchBox.click();
  await searchBox.fill('PlayWright');
  
  // 提交搜索
  await page.keyboard.press('Enter');
  
  // 等待结果加载并验证
  await page.waitForSelector('.repo-list-item');
  const firstResult = page.locator('.repo-list-item >> nth=0');
  await expect(firstResult).toContainText('Playwright');
});

这个测试案例展示了几个关键操作:

  • 页面导航:page.goto()加载目标URL
  • 元素定位:getByPlaceholder()和locator()方法
  • 用户输入:fill()和keyboard.press()模拟键盘操作
  • 智能等待:waitForSelector()确保元素加载完成
  • 结果断言:expect()验证测试结果

2.3 运行测试并查看结果

PlayWright提供了多种运行测试的方式。最简单的是直接使用Node运行:

node tests/github.spec.js

但更推荐使用PlayWright Test提供的CLI工具:

npx playwright test

这个命令会自动:

  • 查找所有测试文件
  • 在无头模式下运行测试
  • 生成HTML测试报告

要查看详细的测试报告,可以运行:

npx playwright show-report

3. 掌握核心API:元素定位与操作

PlayWright提供了丰富多样的元素定位策略,理解这些方法是编写稳定测试脚本的关键。

3.1 元素定位策略对比

定位方式示例适用场景优点
CSS选择器page.locator('button.submit')简单元素定位直接,性能好
XPathpage.locator('//button[contains(@class, "submit")]')复杂层级定位灵活强大
文本内容page.getByText('Submit')文本按钮/链接可读性好
占位文本page.getByPlaceholder('Search')输入框定位语义明确
角色定位page.getByRole('button', { name: 'Submit' })可访问性测试符合WAI-ARIA标准
Label关联page.getByLabel('Username')表单输入字段语义化强

提示:优先使用语义化的定位方式(如getByRole、getByText),它们比CSS选择器更能适应UI变化。

3.2 常见元素操作示例

// 输入文本
await page.getByLabel('Username').fill('testuser');

// 勾选复选框
await page.getByRole('checkbox', { name: 'Remember me' }).check();

// 选择下拉选项
await page.locator('select#country').selectOption('US');

// 上传文件
await page.locator('input[type="file"]').setInputFiles('test.png');

// 鼠标悬停
await page.getByText('Profile').hover();

// 拖放操作
const source = page.locator('#draggable');
const target = page.locator('#droppable');
await source.dragTo(target);

3.3 处理动态内容与等待策略

PlayWright内置了智能等待机制,但有时需要更精细的控制:

// 等待元素出现(默认30秒超时)
await page.locator('.loading-spinner').waitFor({ state: 'hidden' });

// 自定义等待条件
await page.waitForFunction(() => {
  return document.querySelectorAll('.item').length >= 5;
});

// 网络请求等待
await page.waitForResponse(response => 
  response.url().includes('/api/data') && response.status() === 200
);

// 导航完成等待
await Promise.all([
  page.waitForNavigation(),
  page.click('a.next-page')
]);

4. 高级技巧与最佳实践

当你掌握了基础知识后,这些高级技巧可以显著提升你的测试效率和可靠性。

4.1 跨浏览器测试配置

在playwright.config.js中配置多浏览器测试:

module.exports = {
  projects: [
    {
      name: 'Chromium',
      use: { browserName: 'chromium' },
    },
    {
      name: 'Firefox',
      use: { browserName: 'firefox' },
    },
    {
      name: 'WebKit',
      use: { browserName: 'webkit' },
    },
  ],
};

运行所有浏览器测试:

npx playwright test --project=Chromium --project=Firefox --project=WebKit

4.2 设备模拟与视口设置

PlayWright可以模拟各种移动设备和网络条件:

const { devices } = require('playwright');

// iPhone模拟
const iPhone = devices['iPhone 13'];
const browser = await chromium.launch();
const context = await browser.newContext({
  ...iPhone,
  locale: 'en-US',
  timezoneId: 'America/Los_Angeles'
});

// 网络限速
const slow3G = {
  download: 500 * 1024 / 8, // 500 Kbps
  upload: 500 * 1024 / 8,
  latency: 400 // 400ms
};
await context.setOffline(false);
await context.emulateNetworkConditions(slow3G);

4.3 测试数据管理与复用

使用fixtures避免重复代码:

// tests/fixtures/github-fixture.js
const { test: base } = require('@playwright/test');

exports.test = base.extend({
  githubPage: async ({ page }, use) => {
    await page.goto('https://github.com');
    await page.getByRole('link', { name: 'Sign in' }).click();
    await page.getByLabel('Username or email address').fill('testuser');
    await page.getByLabel('Password').fill('password123');
    await page.getByRole('button', { name: 'Sign in' }).click();
    await use(page);
  },
});

在测试中使用fixture:

const { test } = require('./fixtures/github-fixture');

test('登录后查看个人资料', async ({ githubPage }) => {
  await githubPage.getByRole('button', { name: 'Profile' }).click();
  await expect(githubPage).toHaveURL(/profile/);
});

4.4 常见问题解决方案

元素定位失败:

  • 使用page.pause()进入调试模式
  • 检查元素是否在iframe中
  • 尝试更稳定的定位策略

测试不稳定:

  • 增加test.slow()标记可能耗时的测试
  • 使用test.retries()设置重试次数
  • 避免硬编码等待,改用内置智能等待

跨域问题:

  • 使用browser.newContext()创建隔离的上下文
  • 配置--disable-web-security标志(仅限测试环境)

性能优化:

  • 复用浏览器实例和上下文
  • 并行运行独立测试
  • 使用test.describe.parallel()标记可并行测试组

5. 持续集成与报告生成

将PlayWright测试集成到CI/CD流程中,可以确保每次代码变更都经过自动化验证。

5.1 GitHub Actions配置示例

创建.github/workflows/playwright.yml:

name: PlayWright Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: 16
    - run: npm ci
    - run: npx playwright install --with-deps
    - run: npx playwright test
    - uses: actions/upload-artifact@v3
      if: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

5.2 自定义HTML报告

PlayWright默认生成的HTML报告已经非常实用,但你可以进一步定制:

// playwright.config.js
module.exports = {
  reporter: [
    ['list'],
    ['html', { 
      outputFolder: 'custom-report',
      open: 'never',
      host: '0.0.0.0',
      port: 9323
    }]
  ]
};

5.3 与测试平台集成

PlayWright测试结果可以集成到各种测试管理平台:

// 输出JUnit格式报告
reporter: [
  ['junit', { outputFile: 'results.xml' }]
],

// 输出JSON格式报告
reporter: [
  ['json', { outputFile: 'results.json' }]
],

6. 从入门到精通的进阶路径

当你完成第一个测试脚本后,可以逐步探索PlayWright更强大的功能。

6.1 测试录制与代码生成

PlayWright提供了GUI工具帮助快速生成测试代码:

npx playwright codegen https://example.com

这个命令会:

  1. 打开浏览器窗口和代码生成器
  2. 记录你的操作并实时生成对应代码
  3. 支持复制生成的代码到你的测试文件

6.2 组件测试与视觉回归

结合@playwright/test的组件测试功能:

import { test, expect } from '@playwright/experimental-ct-react';
import Button from './Button';

test('Button组件', async ({ mount }) => {
  const component = await mount(<Button>Click me</Button>);
  await expect(component).toContainText('Click me');
  
  // 视觉对比
  await expect(component).toHaveScreenshot('button.png');
});

6.3 性能测试与追踪

PlayWright可以收集详细的性能指标:

const browser = await chromium.launch();
const page = await browser.newPage();

// 开始性能追踪
await page.context().tracing.start({ screenshots: true, snapshots: true });

await page.goto('https://example.com');
// 执行测试操作...

// 停止追踪并保存结果
await page.context().tracing.stop({ path: 'trace.zip' });

分析追踪文件:

npx playwright show-trace trace.zip

6.4 社区资源与学习路径

  • 官方文档:https://playwright.dev/docs/intro
  • PlayWright中文社区:https://playwright.nodejs.cn/
  • GitHub示例仓库:https://github.com/microsoft/playwright
  • Stack Overflow标签:playwright
  • Discord社区:PlayWright官方频道
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐