把所有驗證都塞進端到端測試,定位失敗會很慢;只測 ViewModel,又可能漏掉真實按鈕不可點擊、錯誤文字被遮擋等 UI 問題。測試層次應按故障邊界選擇。
三層各有責任
倉儲單元測試驗證緩存優先、錯誤映射、離線隊列與版本衝突,使用可控的假時鐘和假網絡。Widget 測試驗證「載入中仍能看舊訂單」「空態有建立入口」「權限錯誤禁用按鈕」,注入假的倉儲,不依賴真實伺服器。集成測試只保留少數關鍵路徑,如登入、建立訂單、斷網後恢復與再次同步。
| 層次 | 輸入 | 最重要的斷言 |
|---|---|---|
| 單元 | 延遲、衝突、網絡錯誤 | 狀態轉換和數據不變量 |
| Widget | 快照與請求狀態 | 文案、可訪問性和操作入口 |
| 集成 | 真機/模擬器和後端測試環境 | 路由、平台權限與持久化 |
讓失敗可解釋
測試數據固定 ID 與時間,避免用隨機值掩蓋順序問題。對於非同步頁面,明確等待目標狀態而不是固定 sleep。截圖測試只用於佈局穩定的關鍵狀態,不能替代行為斷言;字體、系統縮放和平台差異會影響像素結果。
圍繞一次轉賬建立測試組合
轉賬功能同時包含金額校驗、收款人查詢、確認頁、提交請求和結果頁。先把金額範圍、幣種精度、餘額與費用計算留在不依賴 Widget 的純邏輯層,用單元測試覆蓋邊界值和捨入規則;這些測試快,適合每次提交執行。隨後用 Widget 測試驅動輸入錯誤、加載、確認和失敗恢復,注入假的倉庫與可控時鐘。不要只斷言某段文案存在,還應檢查提交按鈕在請求中禁用、失敗後重新啓用、舊請求不會污染新表單。
真正的集成測試只覆蓋少數關鍵旅程:登錄後進入轉賬、確認收款人、提交、返回記錄。使用受控測試後端或明確標注的模擬環境,測試帳戶與數據隔離;不要把真實資金網絡當成 CI 依賴。系統鍵盤、權限彈窗、深鏈返回和應用進後台,需要在目標平台的真實運行環境再驗一次,Widget 測試無法替代它們。
| 層級 | 關鍵問題 | 示例斷言 |
|---|---|---|
| 單元 | 計算規則正確嗎 | 貨幣精度、手續費與邊界金額 |
| Widget | 交互狀態可恢復嗎 | 請求中防重復、錯誤後可重試 |
| 集成 | 組件協作真實嗎 | 一次提交對應一條服務端記錄 |
| 設備驗收 | OS 行為符合預期嗎 | 鍵盤、後台恢復、弱網 |
防止測試本身掩蓋競態
假倉庫應允許手動決定響應順序,不能總是立即返回成功。至少測試兩次提交競爭、離開頁面後回包、服務器超時但實際成功,以及重復進入結果頁。一次請求是否“成功”應由服務端冪等結果決定,而不是由測試里預設的導航次數猜測。參考:Flutter 測試概覽。
參考:Flutter 測試概覽。
