前端面試問測試時,重點通常不是背 Jest API,而是你能不能判斷:
- 哪些功能需要測
- 應該用哪一層測試
- 怎麼避免測試太脆弱
- 如何把測試放進 CI
Unit、Integration、E2E 差在哪?
| 類型 | 測試範圍 | 優點 | 缺點 |
|---|---|---|---|
| Unit | 單一 function、hook、module | 快、容易定位錯誤 | 可能離真實流程太遠 |
| Integration | 多個元件或模組一起運作 | 接近使用者行為 | setup 比 unit 多 |
| E2E | 從瀏覽器操作完整系統 | 最接近真實使用者 | 慢、環境與資料較難管理 |
好的測試策略不是全部寫 E2E,也不是只測 utility function,而是依風險分層。
Unit Test 適合測什麼?
適合輸入輸出明確的邏輯:
- formatter
- validator
- price calculation
- reducer
- 資料轉換
function calculateTotal(price: number, quantity: number) {
return price * quantity;
}
it("calculates total", () => {
expect(calculateTotal(100, 3)).toBe(300);
});Integration Test 適合測什麼?
React 元件通常更適合從使用者角度測,而不是直接測 internal state。
render(<LoginForm />);
await user.type(screen.getByLabelText("Email"), "ray@example.com");
await user.type(screen.getByLabelText("Password"), "password");
await user.click(screen.getByRole("button", { name: "登入" }));
expect(await screen.findByText("登入成功")).toBeInTheDocument();React Testing Library 的核心精神是:測試使用者看得到、操作得到的行為。
E2E 適合測什麼?
E2E 適合最重要、跨頁面的核心流程:
- 註冊與登入
- 結帳
- 付款
- 建立訂單
- 權限導頁
- 主要 CRUD 流程
test("user can login", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("ray@example.com");
await page.getByLabel("Password").fill("password");
await page.getByRole("button", { name: "登入" }).click();
await expect(page).toHaveURL("/dashboard");
});Playwright 可以控制真實瀏覽器,也能做 screenshot、network mock、跨瀏覽器測試。
Mock 越多越好嗎?
不是。
mock 太多會讓測試只證明 mock 能正常運作,卻沒有驗證真實整合。
我的原則:
- 第三方服務、付款、email 可以 mock
- API integration test 可以用 MSW 攔 request
- 核心 E2E 保留少量真實後端流程
- 不要 mock 自己正在測的行為
哪些功能優先測?
可以依風險排序:
- 壞掉會直接影響營收或資料的流程
- 使用者最常走的流程
- 過去常發生 regression 的地方
- 複雜條件與權限
- 純展示、低風險區域
不需要為了 coverage 數字測每一行。
常見追問
Snapshot test 有什麼問題?
大型 snapshot 很難 review,UI 小改就大量更新,久了容易變成無腦接受。它適合穩定且輸出較小的結構,不適合作為主要 UI 測試策略。
測試很 flaky 怎麼辦?
避免固定 sleep,改等待可觀測條件;隔離測試資料;使用穩定 selector;確保每個測試能獨立執行。
CI 要跑哪些測試?
PR 階段跑 lint、type-check、unit、integration;核心 E2E 可以在 PR 或 staging 部署後跑。較慢的完整 suite 可排程執行。
面試回答模板
我會依風險建立測試分層。純函式和資料轉換用 unit test;React 畫面與 API 狀態互動用 Testing Library 做 integration test;登入、付款、權限等核心流程用 Playwright 做少量 E2E。測試重點是使用者行為與重要 contract,不追求為了 coverage 而測 implementation detail,並會把 lint、type-check 和主要測試放進 CI。