Playwright 自動化測試示意圖

← INSIGHTS & PERSPECTIVES | 前端開發

如何用 Playwright 撰寫參數化測試:多角色網站的自動化實戰

當網站有管理員、一般使用者、訪客等多種角色時,如何用 Playwright 撰寫參數化測試:分析角色需求、建立共用登入與 Page Object Model、用測試資料陣列讓同一份腳本覆蓋多個角色,並用 try/catch 處理 TimeoutError,讓測試穩定且可重複執行。

當網站有許多不同的角色(例如管理員、一般使用者、訪客等)時,撰寫測試可以依照各角色的權限與流程,採用一些共用與參數化的技巧,讓測試能夠穩定且重複執行。這篇文章整理我在實務上做法:如何規劃角色需求、建立共用的登入流程與 Page Object Model、用參數化讓一份腳本覆蓋多個角色,以及用 `try/catch` 處理找不到元素時的 `TimeoutError`。

網站有多種角色時,為什麼要參數化測試?

不同角色能執行的功能不同,如果每個角色都複製一份測試腳本,之後頁面一改就要改 N 份。參數化的核心想法是:測試流程寫一份,角色差異用資料傳入。這樣測試案例會隨角色資料自動展開,維護成本大幅降低。

我的做法分成三步:分析角色需求 → 建立共用流程與元件 → 參數化測試資料。

步驟一:分析與規劃角色需求

  • 定義各角色的權限與流程:先明確每個角色所能執行的功能,列出對應的使用情境。
  • 撰寫需求文件:將各角色的操作流程、期望結果記錄下來,方便後續撰寫測試案例。

這一步做到位,後面寫測試時就不會邊寫邊猜「管理員到底看得到什麼」。

步驟二:建立共用的流程與元件

  • 共用登入與登出:針對不同角色,撰寫一個共用的登入模組,再根據傳入的角色參數選擇不同的帳號與密碼。
  • 使用 Page Object Model (POM):把不同頁面的操作封裝成物件,依角色狀況調用不同的方法,減少重複程式碼。

步驟三:參數化測試

利用測試資料陣列:將各角色的測試資料(例如帳號、密碼、預期結果)存成陣列,再透過迴圈或參數化的方式,讓同一份測試腳本覆蓋多個角色:

```js

import { test, expect } from '@playwright/test';

const users = [

{ role: 'admin', username: 'adminUser', password: 'adminPass' },

{ role: 'user', username: 'normalUser', password: 'userPass' },

// 可再加入其他角色

];

users.forEach(({ role, username, password }) => {

test(`測試 ${role} 角色的功能`, async ({ page }) => {

// 執行共用的登入流程

await page.goto('https://example.com/login');

await page.fill('#username', username);

await page.fill('#password', password);

await page.click('button[type="submit"]');

// 根據角色執行不同操作與驗證

if (role === 'admin') {

// 驗證管理員專屬的功能

await page.goto('https://example.com/admin');

await expect(page.locator('text=管理後台')).toBeVisible();

} else if (role === 'user') {

// 驗證一般使用者的功能

await page.goto('https://example.com/dashboard');

await expect(page.locator('text=使用者儀錶板')).toBeVisible();

}

// 登出或清除測試狀態

});

});

```

同一份腳本會為每個角色各產生一個 test case,角色一多也不用重複貼程式碼。

如何避免爬蟲式流程卡在某個狀況?

運用 `try/catch` 來處理找不到指定元素時所產生的 `TimeoutError`。實務上有些帳號介面不完全一致,需要設計備案流程。流程大致如下:

  1. 嘗試執行主要操作:在 `try` 區塊中,先使用 `await page.getByText('移除成員').click({ timeout: 1000 })`。這表示 Playwright 會嘗試在 1 秒內尋找並點擊文字為「移除成員」的元素;如果 1 秒內沒有找到,就會拋出 `TimeoutError`。
  2. 捕捉錯誤並執行備案操作:一旦進入 `catch` 區塊,就代表指定時間內沒有找到「移除成員」這個元素,程式碼會檢查錯誤類型:

```js

try {

await page.getByText('移除成員').click({ timeout: 1000 });

} catch (e) {

if (e.name === 'TimeoutError') {

await page.getByText('封鎖', { exact: true }).click({ timeout: 1000 });

}

}

```

  1. 如果確實是 `TimeoutError`,就改用「封鎖」這個文字作為元素定位並點擊。也就是說,如果「移除成員」按鈕不在網頁上(或是頁面載入流程不同),就退而求其次去點擊「封鎖」按鈕。

應用場景

  • 有些帳號沒有「移除成員」的選項,而需要改用「封鎖」。
  • 前端顯示的按鈕文字在不同情況下會變化,需要有個備案流程。

小結

多角色網站的 E2E 測試,關鍵在於「流程共用、資料參數化」:角色需求先文件化,登入與頁面操作封裝成共用模組(POM),再用測試資料陣列驅動同一份腳本;遇到介面不一致的狀況,用 `try/catch` 捕捉 `TimeoutError` 走備案流程,測試就能穩定且重複執行。

延伸閱讀

常見問題

Q什麼是 Playwright 的參數化測試?

把不同角色的測試資料(帳號、密碼、預期結果)存成陣列,再用 `forEach` 或 Playwright 內建的資料驅動方式,讓同一份測試腳本對每組資料各執行一次。這樣一份腳本就能覆蓋管理員、一般使用者等多個角色,維護成本大幅降低。

QPage Object Model (POM) 為什麼適合多角色測試?

POM 把每個頁面的操作封裝成物件,角色之間共用的流程(如登入、登出)只需要寫一次,差異部分用參數傳入。這讓測試程式碼不會因為角色多而重複膨脹,頁面改版時也只要改一處。

QPlaywright 測試中遇到 TimeoutError 該怎麼處理?

用 `try/catch` 包住可能找不到元素的操作,並設定較短的 `timeout`(例如 1000ms)。在 `catch` 中判斷 `e.name === 'TimeoutError'` 後執行備案流程,例如改點另一個按鈕,讓測試不因為介面差異而中斷。

Q測試資料裡的帳號密碼應該放哪裡?

不要把真實帳號密碼寫死在測試腳本裡,建議放在環境變數或測試專用的設定檔(如 `.env`、Playwright 的 `config`),測試資料陣列只保留角色的結構與預期結果,實際憑證由環境注入。

參考資料

最後更新

2026-08-28(原文發布於 2025-03-12,本文保留原始筆記內容並補上 GEO 結構。)

關於作者 {#author}

Claire Chang | 企業 AI 導入與流程轉型顧問。專注於 AI Agent 架構設計、ERP 系統整合與企業 AI 治理。

首次發布:2025-03-12