iT邦幫忙

2025 iThome 鐵人賽

DAY 11
1

前一篇我們理解了 Playwright 的 async / await 機制如何讓測試能夠一步步按照順序執行,現在來談談 Playwright 另一個執行測試時很重要機制:「逾時」(Timeout),超過一定時間就不再等待,回傳錯誤並中止測試。因為 Playwright 有 auto-waiting 以及 auto-retry,因此必須運用「逾時」(Timeout)設定一個合理的等待時間以驗證結果,原因如下:

1. 避免無限等待
萬一某個元素或預期的事件遲遲不出現,或某些原因導致它根本不出現,如果沒有 Timeout,測試可能就永遠卡在這一步。
2. 防止資源浪費
在 CI/CD 中,設定 Timeout,以免浪費 Runner 的資源與時間,影響 pipeline 的執行。
3. 控制測試速度
我們預期進到某個頁面應該顯示某個元素,但畫面上可能根本就不會顯示,這時候不應該無限制等待,應該視為失敗,立刻結束測試並回傳錯誤。

我們在 Day 07 ~ Day 08 介紹內建 matcher 時與進階技巧時有提到,自動重試(Auto-retry) 的 matcher 具有「自動等待」(Auto-wating)的特性,預設為 5 秒,能夠加入參數,設定個別斷言的 Timeout 時間。除了 matcher 能夠設定 Timeout 之外,還有多個可配置的 Timeout 設定,讓我們能彈性設置以應對各種測試場景:

Global Timeout

針對所有測試總和時間的限制,避免某些原因導致所有測試都錯誤時,測試時間過於冗長。

  • 預設值:無
  • 全域設定:
    // playwright.config.ts
    import { defineConfig } from '@playwright/test';
    
    export default defineConfig({
      // 設定 Global Timeout 為一小時
      globalTimeout: 60 * 60 * 1000,
    });
    

Test Timeout

針對單一測試的設定,計時範圍涵蓋測試本身、fixtures 初始化與設定時間, 以及 hooks (如beforeEachbeforeAllafterAll) 的所有執行時間總和。

  • 預設值: 30000ms (30 秒)
  • 個別設定:
    test('test', async ({ page }) => {
      // 設定 Timeout 為 3 分鐘   
      test.setTimeout(3 * 60 * 1000);
    
      // ...測試步驟
    });
    
    test('test', async ({ page }) => {
      // Test Timeout 的三倍
      test.slow();
      // ...測試步驟
    });
    

Navigation Timeout

針對開啟網頁時設定 Timeout,避免網頁回應時間過長,造成資源浪費。

  • 預設值:無
  • 個別設定:
    test('test', async ({ page }) => {
      // 設定前往目標網址 Timeout 為 10 秒
      await page.goto('/', { timeout: 10 * 1000 });
    
      // ...測試步驟
    });
    

Action Timeout

可以為某個動作加上 Timeout,讓測試時間更加合理

  • 預設值:無
  • 個別設定:
    test('test', async ({ page }) => {
      // 設定點擊某個元素 Timeout 為 5 秒
      await page.locator.click({ timeout: 5 * 1000 });
      // 設定輸入內容 Timeout 為 5 秒
      await page.locator.fill('cat', { timeout: 5 * 1000 });  
    
      // ...測試步驟
    });
    

Expect Timeout

  • 預設值:5000ms (5 秒)
  • 個別設定:
    test('test', async ({ page }) => {
      // ...測試步驟
    
      // 在 matcher 設定 Timeout,即為這個斷言的個別 Timeout
      await expect(page.locator).toBeVisible({ timeout: 10 * 1000 });
    
      // ...測試步驟
    });
    

全域設定

以上 Timeout 都能在 playwright.config.ts全域設定

// playwright.config.ts
import { defineConfig } from '@playwright/test';
    
export default defineConfig({
    // 設定每個測試 Timeout
    timeout: 5 * 60 * 1000,
    
    // 設定每個斷言 Timeout
    expect: {
        timeout: 10 * 1000,
    },
    
    use: {
        // 設定前往目標網址 Timeout
        navigationTimeout: 10 * 1000
        // 設定每個動作 Timeout
        actionTimeout: 5 * 1000,
    },
    
    // 此專案內每個測試 Timeout
    projects: [
    {
      name: 'cat',
      timeout: 60 * 1000,
    },
});

Timeout 優先權

以全域設定為基礎,如果全域沒有設定則以預設為基礎,再由 hooks 設定疊加 / 覆蓋(這部份在下一篇一併探討)或個別設定覆蓋,一般來說,local 設定 > global 設定,也就是離測試越靠近越優先:
https://ithelp.ithome.com.tw/upload/images/20250920/20168913ZeNAsQk0cF.png


到這裡,我們我們已經學會了如何掌控「時間」,懂得如何透過設定 Timeout 來應對各種場景,接下來,我們將認識 Hooks:before/describe/after 的設置,幫助我們建立更有結構、可複用性更高的測試腳本。


上一篇
Day 10:秩序的守護者|async / await 同步你與瀏覽器的時空
系列文
Playwright 玩家攻略:從新手村到魔王關11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言