發佈日期:

何用 Playwright 撰寫參數化

網站在測試時有許多不同的「角色」該如何撰寫測試

當網站有許多不同的角色(例如管理員、一般使用者、訪客等)時,撰寫測試可以依照各角色的權限與流程,採用一些共用與參數化的技巧,讓測試能夠穩定且重複執行。

1. 分析與規劃角色需求

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

2. 建立共用的流程與元件

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

3. 參數化測試

  • 利用測試資料陣列:將各角色的測試資料(例如帳號、密碼、預期結果)存成陣列,再透過迴圈或參數化的方式,讓同一份測試腳本覆蓋多個角色。
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();
    }
    // 登出或清除測試狀態
  });
});

爬蟲行為設定避免卡在某個狀況

運用 try/catch 來處理找不到指定元素時所產生的 TimeoutError。流程大致如下:

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

  1. 如果確實是 TimeoutError,就改用「封鎖」這個文字作為元素定位並點擊。
  2. 這表示如果「移除成員」按鈕不在網頁上(或是網頁加載的流程不同),就退而求其次去點擊「封鎖」按鈕。
  3. 應用場景
    • 可能是有些帳號沒有「移除成員」的選項,而需要改用「封鎖」。
    • 也可能是前端顯示的按鈕文字在不同情況下會變化,需要有個備案流程。