【第三方Web UI自动化软件测试工具Playwright使用指南】
Playwright是一个Web自动化测试框架工具,支持Chromium、Firefox和WebKit,提供可靠的端到端测试能力。
环境安装与配置
1.安装Playwright
# 使用 npm 安装
npm init playwright@latest# 或使用 yarn
yarn create playwright# 或全局安装
npm install -g @playwright/test# 安装浏览器(推荐)
npx playwright install
2.第一个测试用例
// tests/basic.spec.js
const { test, expect } = require('@playwright/test');test('基本导航测试', async ({ page }) => {// 导航到页面await page.goto('https://zmtests.com');// 断言页面标题await expect(page).toHaveTitle('Example Domain');// 截图await page.screenshot({ path: 'example.png' });
});test('元素交互测试', async ({ page }) => {await page.goto('https://zmtests.com');// 点击元素await page.click('a');// 填写表单await page.fill('#username', 'testuser');await page.fill('#password', 'password123');await page.click('#login-btn');// 等待导航await page.waitForURL('**/dashboard');
});
选择器使用
// tests/selectors.spec.js
const { test, expect } = require('@playwright/test');test('选择器使用', async ({ page }) => {await page.goto('https://zmtests.com');// 各种选择器用法await page.click('button'); // CSS 选择器await page.click('#submit-btn'); // ID 选择器await page.click('.btn-primary'); // Class 选择器await page.click('text=登录'); // 文本选择器await page.click('[data-testid="login-btn"]'); // 属性选择器await page.click('button:has-text("Submit")'); // 包含文本// XPathawait page.click('//button[contains(@class, "primary")]');// 组合选择器await page.click('form >> .submit-btn');
});
3. 高级功能
页面对象模型 (Page Object Model)
// pages/login-page.js
class LoginPage {constructor(page) {this.page = page;this.usernameInput = page.locator('#username');this.passwordInput = page.locator('#password');this.loginButton = page.locator('#login-btn');this.errorMessage = page.locator('.error-message');}async navigate() {await this.page.goto('https://zmtests.com/login');}async login(username, password) {await this.usernameInput.fill(username);await this.passwordInput.fill(password);await this.loginButton.click();}async getErrorMessage() {return await this.errorMessage.textContent();}
}module.exports = { LoginPage };
测试用例使用页面对象
// tests/login.spec.js
const { test, expect } = require('@playwright/test');
const { LoginPage } = require('../pages/login-page');test('用户登录测试', async ({ page }) => {const loginPage = new LoginPage(page);// 导航到登录页await loginPage.navigate();// 执行登录await loginPage.login('testuser', 'password123');// 验证登录成功await expect(page).toHaveURL('**/dashboard');await expect(page.locator('.welcome-message')).toContainText('欢迎');
});test('登录失败测试', async ({ page }) => {const loginPage = new LoginPage(page);await loginPage.navigate();// 使用错误凭据登录await loginPage.login('wronguser', 'wrongpass');// 验证错误消息const errorMessage = await loginPage.getErrorMessage();expect(errorMessage).toContain('用户名或密码错误');
});
钩子
// fixtures/auth-setup.js
const { test: baseTest, expect } = require('@playwright/test');// 扩展基础测试夹具
const test = baseTest.extend({authenticatedPage: async ({ page }, use) => {// 登录逻辑await page.goto('https://zmtests.com/login');await page.fill('#username', 'testuser');await page.fill('#password', 'password123');await page.click('#login-btn');await page.waitForURL('**/dashboard');// 使用已认证的页面await use(page);// 测试后清理await page.click('#logout');},apiContext: async ({ playwright }, use) => {// 创建 API 上下文const apiContext = await playwright.request.newContext({baseURL: 'https://api.zmtests.com',extraHTTPHeaders: {'Authorization': 'Bearer token123',},});await use(apiContext);await apiContext.dispose();}
});module.exports = { test, expect };
使用自定义夹具
// tests/dashboard.spec.js
const { test, expect } = require('../fixtures/auth-setup');test('仪表板功能测试', async ({ authenticatedPage }) => {// 使用已认证的页面await authenticatedPage.goto('/dashboard');// 验证仪表板内容await expect(authenticatedPage.locator('.user-welcome')).toBeVisible();await expect(authenticatedPage.locator('.stats-cards')).toHaveCount(4);
});test('API 集成测试', async ({ apiContext }) => {// 直接测试 APIconst response = await apiContext.get('/users/1');expect(response.status()).toBe(200);const userData = await response.json();expect(userData.name).toBe('John Doe');
});
配置和运行
Playwright 配置文件
// playwright.config.js
const { defineConfig, devices } = require('@playwright/test');module.exports = defineConfig({// 测试目录testDir: './tests',// 超时设置timeout: 30000,expect: { timeout: 5000 },// 并行执行fullyParallel: true,workers: process.env.CI ? 2 : undefined,// 报告器reporter: [['html'],['json', { outputFile: 'test-results.json' }],['junit', { outputFile: 'results.xml' }]],// 全局设置use: {baseURL: 'https://zmtests.com',trace: 'on-first-retry',screenshot: 'only-on-failure',video: 'retain-on-failure',},// 项目配置(不同浏览器/设备)projects: [{name: 'chromium',use: { ...devices['Desktop Chrome'] },},{name: 'firefox',use: { ...devices['Desktop Firefox'] },},{name: 'webkit',use: { ...devices['Desktop Safari'] },},{name: 'mobile-chrome',use: { ...devices['Pixel 5'] },},{name: 'mobile-safari',use: { ...devices['iPhone 12'] },},],// Web 服务器(可选)webServer: {command: 'npm run start',url: 'http://localhost:3000',reuseExistingServer: !process.env.CI,},
});
运行测试
# 运行所有测试
npx playwright test# 运行特定文件
npx playwright test login.spec.js# 运行特定项目
npx playwright test --project=chromium# 有UI模式运行
npx playwright test --ui# 调试模式
npx playwright test --debug# 生成测试报告
npx playwright show-report