跳轉到

4.3 處理網路與 API:攔截與 Mock#

為什麼要攔截網路?#

E2E 測試依賴真實後端時:

  1. 慢:每次測試都打真實 API、真實資料庫
  2. 不穩:後端資料變了,測試就跟著壞
  3. 測不了極端情況:怎麼手動觸發「伺服器 500」?

解法:攔截(route)網路請求,回傳假資料(Mock)。

攔截請求:回傳假資料#

test("商品清單應該正確顯示", async ({ page }) => {
  // 攔截 /api/products,回傳假資料
  await page.route("**/api/products", async (route) => {
    await route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify([
        { id: 1, name: "蘋果", price: 30 },
        { id: 2, name: "香蕉", price: 15 },
      ]),
    });
  });

  await page.goto("https://my-site.com/products");
  await expect(page.getByText("蘋果")).toBeVisible();
  await expect(page.getByText("香蕉")).toBeVisible();
});
  • page.route(模式, 處理函式):符合模式的請求會被攔截
  • ** 是萬用字元,**/api/products 符合任何網域下的這個路徑
  • route.fulfill(...):直接回傳假回應,請求不會真的發出

模擬錯誤情境#

Mock 的最大價值:輕鬆觸發手動做不出的情況:

// 模擬伺服器錯誤
await page.route("**/api/products", async (route) => {
  await route.fulfill({ status: 500 });
});

// 驗證錯誤處理 UI
await page.goto("https://my-site.com/products");
await expect(page.getByText("載入失敗,請稍後再試")).toBeVisible();

// 模擬網路斷線
await page.route("**/api/**", route => route.abort());

修改真實回應#

不回假資料,而是攔截後改一改再放行:

await page.route("**/api/user", async (route) => {
  const response = await route.fetch();       // 放行到真實後端
  const json = await response.json();
  json.name = "測試使用者";                    // 修改回應
  await route.fulfill({ response, json });
});

用 API 準備測試資料(比 UI 操作快)#

登入、建立測試資料等前置工作,用 request fixture 直接打 API,比透過 UI 操作快十倍:

test("已登入使用者可以看到訂單", async ({ page, request }) => {
  // 用 API 登入(繞過 UI)
  const loginRes = await request.post("https://my-site.com/api/login", {
    data: { email: "user@test.com", password: "password123" },
  });
  const { token } = await loginRes.json();

  // 把 token 塞進 localStorage,讓頁面認為已登入
  await page.addInitScript((t) => {
    localStorage.setItem("token", t);
  }, token);

  await page.goto("https://my-site.com/orders");
  await expect(page.getByText("我的訂單")).toBeVisible();
});

心法:UI 操作只留給「被測試的行為」本身;前置準備(登入、造資料)走 API,極端情況(500、斷線)用 route mock。快又穩。