Playwright進階篇(二):API 測試與攔截

POM 基本概念與優勢
為什麼需要 POM?
Page Object Model 是一種測試設計模式,旨在解決自動化測試中的常見挑戰:
-
代碼可維護性
- 將頁面元素和操作邏輯集中管理
- 降低重複代碼
- 簡化測試腳本邏輯
-
測試穩定性
- 元素定位集中管理
- 易於修改和更新
- 降低元素變化對測試的影響
-
代碼複用
- 封裝常用的頁面操作
- 減少重複勞動
- 提高測試開發效率
設計基本 Page Object 類別
元素封裝與操作方法示例
import { Page, Locator } from '@playwright/test';
class LoginPage {
// 頁面元素定義
private page: Page;
private usernameInput: Locator;
private passwordInput: Locator;
private loginButton: Locator;
// 構造函數
constructor(page: Page) {
this.page = page;
this.usernameInput = page.locator('#username');
this.passwordInput = page.locator('#password');
this.loginButton = page.locator('button[type="submit"]');
}
// 登入操作方法
async login(username: string, password: string) {
await this.usernameInput.fill(username);
await this.passwordInput.fill(password);
await this.loginButton.click();
// 可選:等待登入後的頁面載入
await this.page.waitForURL('/dashboard');
}
// 驗證方法
async isLoginErrorDisplayed(): Promise<boolean> {
return this.page.locator('.error-message').isVisible();
}
}
export default LoginPage;
簡單實例:從腳本到 POM
重構測試案例
import { test, expect } from '@playwright/test';
import LoginPage from './pages/LoginPage';
test('用戶登入流程', async ({ page }) => {
// 使用 POM
const loginPage = new LoginPage(page);
// 導航到登入頁面
await page.goto('/login');
// 使用封裝的登入方法
await loginPage.login('testuser', 'password123');
// 驗證登入結果
expect(await loginPage.isLoginErrorDisplayed()).toBeFalsy();
});
組織複雜頁面結構
元件化與層次結構
// 複雜頁面的組件示例
class DashboardPage {
private sideMenu: Locator;
private userProfile: Locator;
private mainContent: Locator;
constructor(page: Page) {
this.sideMenu = page.locator('.side-menu');
this.userProfile = page.locator('.user-profile');
this.mainContent = page.locator('.main-content');
}
// 組件相關方法
async navigateToSection(section: string) {
await this.sideMenu.getByText(section).click();
}
}
共用元素與行為
基礎類別與繼承
// 基礎頁面類別
class BasePage {
protected page: Page;
constructor(page: Page) {
this.page = page;
}
// 通用方法
async waitForLoadState() {
await this.page.waitForLoadState('networkidle');
}
async takeScreenshot(name: string) {
await this.page.screenshot({ path: `screenshots/${name}.png` });
}
}
// 繼承基礎類別
class ProductPage extends BasePage {
private productList: Locator;
constructor(page: Page) {
super(page);
this.productList = page.locator('.product-list');
}
// 特定頁面方法
async getProductCount(): Promise<number> {
return this.productList.locator('.product-item').count();
}
}
POM 最佳實踐
避免常見陷阱
-
不要在 Page Object 中編寫斷言
- 保持 Page Object 專注於操作
- 斷言邏輯放在測試腳本中
-
保持方法的單一職責
- 每個方法只做一件事
- 避免複雜的方法邏輯
-
使用有意義的方法名稱
- 描述性的方法命名
- 提高代碼可讀性
維護技巧
- 定期審查和重構 Page Object
- 使用集中的元素定位策略
- 為複雜交互創建專門的方法
- 考慮使用工廠模式管理 Page Object
- 保持 Page Object 輕量且專注
結論
Page Object Model 是一種強大的測試設計模式,可以顯著提高 Playwright 測試的可維護性和可讀性。通過正確實踐,您可以建立更robust、更易於維護的自動化測試套件。
分享這篇文章: