如果有任何問題或建議,歡迎隨時聯繫我:
過去幾天,我們一頭栽進了「單元測試」的世界。我們學會了如何像個鐘錶師傅一樣,細心地檢測每一個微小的齒輪(函式)和零件(元件),確保它們都運作得分毫不差。
但這引出了一個重要的問題:
一個由無數個完美零件組裝起來的系統,就保證能完美運作嗎?
答案是:不一定。
打個比方:你可能擁有世界上最頂級的引擎、最順滑的變速箱、和抓地力最強的輪胎(所有零件的單元測試都完美通過)。但是,如果連接引擎和變速箱的螺絲尺寸不對,這台車依然動彈不得。要發現這個問題,你必須把引擎和變速箱整合起來測試。
更進一步,就算車子能動了,它能在真實的賽道上順利跑完一圈嗎?這就需要一次端到端 (End-to-End) 的完整測試。
這就是我們今天要探討的主題:測試金字塔 (The Testing Pyramid)。它是一個經典的模型,幫助我們理解不同測試類型之間的關係與權衡,指導我們建立一個健康、高效的測試策略。
測試金字塔是一個形象的比喻,它將軟體測試由下到上分為三層:
這個金字塔結構蘊含了幾個關鍵的權衡:
層級 | 執行速度 | 維護成本 | 測試範疇 | 整合信心 | 數量 |
---|---|---|---|---|---|
E2E 測試 | 最慢 | 最高 | 整個應用 | 最高 | 少量 |
整合測試 | 中等 | 中等 | 多個單元 | 中等 | 中量 |
單元測試 | 最快 | 最低 | 單一單元 | 最低 | 大量 |
一個健康的測試策略,其不同類型測試的數量分佈,應該要像一個金字塔,而不是一個甜筒(大量昂貴的 E2E 測試)或沙漏(缺乏整合測試)。
Vitest
, Jest
。BaseInput
和 BaseButton
原子元件組成。ProductCard
元件列表。LoginForm
測試,其實已經算是一個小型的整合測試,因為它測試了 label
, input
, button
這些單元如何整合起來完成一次登入操作。Vitest
+ @testing-library/vue
是進行整合測試的絕佳組合。cy.visit('/login')
:打開登入頁面。cy.get('#username').type('my-user')
:在使用者名稱欄位輸入文字。cy.get('#password').type('my-pass')
:在密碼欄位輸入文字。cy.get('button[type=submit]').click()
:點擊登入按鈕。cy.url().should('include', '/dashboard')
:斷言頁面跳轉到了儀表板。cy.contains('Welcome, my-user')
:斷言頁面上出現了歡迎訊息。Cypress
, Playwright
是這個領域的兩大巨頭。金字塔模型給我們的啟示是:不要試圖用 E2E 測試覆蓋所有細節!這是一個常見且昂貴的錯誤,被稱為「冰淇淋甜筒反模式 (Ice Cream Cone Anti-Pattern)」。
一個健康的策略應該是:
今天,我們從單一的測試層級中跳脫出來,鳥瞰了整個自動化測試的宏觀戰略。
沒有哪一種測試是萬靈丹。一個成熟的工程團隊,會善用不同測試的優缺點,將它們合理地配置在金字塔的各個層級,以最小的成本,換取最大的信心。
明天,我們將回到程式碼,探討 Vue 專案中一個非常實用的主題:效能優化 (Performance Optimization)。
測試金字塔 (Testing Pyramid)
單元測試 (Unit Test)
整合測試 (Integration Test)
端到端測試 (End-to-End Test)
測試範疇 (Scope)
整合信心 (Confidence)
Cypress
Playwright
冰淇淋甜筒反模式 (Ice Cream Cone Anti-Pattern)