有一次我用 AI 把規格、測試、後端修正和上版流程跑了一輪。程式碼真的生得很快,快到我還沒喝完一杯咖啡,它已經改了好幾個模組。
那天最後花最多時間的,卻不是寫程式。
我在補測試、修測試抓到的 bug、整理測試資料、接假伺服器,還要確認整套東西絕對不會碰到正式帳號。AI 把「寫出來」壓到幾分鐘,「證明它真的對」還是花了幾個小時。
那次之後,我不太敢再用產出多少程式碼衡量 AI 開發有沒有變快。
看起來會跑,業務行為還是可能錯
那天抓到一個很典型的問題。批次工作收到失敗結果後,有把失敗清單回傳,卻忘了把那些工作標成「需要人工處理」。
API 沒有噴錯,畫面也拿得到回應。單看程式碼,每一段都很合理。但失敗的工作會卡在原本狀態,沒有人知道要接手。
這種錯最麻煩,因為它不是語法錯,也不是服務起不來。它要拿業務規則去問:「失敗後,狀態應該變成什麼?」才抓得到。
最後那批模組補出 70 條單元測試。數字本身不是重點,重點是其中一條把這個真 bug 釘出來了。
我把測試分成不同距離
我不會用 100 條 E2E 去保護所有細節。越接近真實使用者,測試越慢、相依越多,也越容易因環境波動失敗。
我會把它們分成幾層:
| 測試層 | 它負責回答的問題 |
|---|---|
| 單元測試 | 某個業務規則或狀態轉換對不對 |
| 整合測試 | 幾個模組和真實資料庫接起來後是否正常 |
| UI/Component | Loading、空資料、錯誤和操作狀態是否正確 |
| E2E | 使用者從登入到完成主要流程是否走得通 |
底層測試便宜,適合跑很多;最上層測試只守住少量重要流程。人工驗收還是要留,但把每次改版都一樣的點擊工作交給人,速度一定追不上 AI 改程式的頻率。
Mock E2E 很快,但它只驗到前端
那次我用 Playwright 的 page.route 攔掉後端請求,讓前端收到固定回應。32 條 Mock E2E 都能快速跑,也真的抓到一個回歸:我改了確認按鈕的 data-testid,忘了同步既有測試。
這一層很適合放在 CI。它能驗證按鈕按下去後,前端送了什麼、畫面怎麼變、錯誤有沒有顯示。
但它有一個很清楚的天花板:後端根本沒跑。
前端送對了,不代表後端組出來的外部 API payload 也對;Mock 回一個成功,不代表正式程式真的會打到正確端點。
外部 API 不能拿正式帳號測
我碰到的流程會把內容發到外部平台。要做全端 E2E,就得讓真的後端一路跑到最後。但我不可能為了測試,真的往正式帳號發一篇貼文,再祈禱刪除流程沒有壞。
我後來做了一個 Fake API。它使用和外部平台相同的測試端點形狀,收下後端送來的請求,記錄必要欄位,再回傳平台格式的假結果。
測試可以檢查:
打到哪一個 endpoint。
帳號識別碼是否正確。
文案和圖片網址有沒有送齊。
失敗回應後,系統狀態有沒有正確改變。
Log 裡的 access token 是否已遮罩。
這個小工具也逼出另一個問題:刪除貼文的 URL 被寫死成正式網址。建立貼文可以導向測試環境,刪除卻會往正式平台走。症狀是新增測試都正常,一跑刪除就準備連外。原因是程式只有一半使用可設定的 base_url。
修法不是在測試裡特判,而是把所有外部端點都放到同一個可替換設定,並在測試環境加上禁止連外的保護。
假平台越像真的,安全邊界越要明確
Fake API 不是隨便在本機開個服務就算完成。我會要求幾個限制:
只能在測試設定啟用。
測試憑證和正式憑證完全分開。
Token 在落 Log 前就遮罩。
CI 預設不能連到外部平台網域。
測試結束後清掉收到的 payload。
如果要用本機 DNS 或憑證,讓正式程式碼在不修改主流程的情況下導向 Fake API,隔離要做得更嚴。這種做法很接近真實,也因此更不能讓設定誤入正式環境。
Docker 解決的是重現,不是真理
全端 E2E 同時需要資料庫、後端、Fake API、前端和測試資料。Docker Compose 很適合把它們寫成同一份環境,讓本機與 CI 都能用相同指令啟動和清理。
不過我不會說用了 Docker,所有失敗就一定是程式邏輯。映像版本、健康檢查、網路和啟動順序仍然可能出錯。Docker 真正幫到我的,是把環境差異縮小,並讓這些差異有檔案可查,不再藏在某台電腦裡。
docker compose -f compose.e2e.yml up -d --wait
dotnet test tests/E2E
docker compose -f compose.e2e.yml down -v
最後的 -v 會移除 compose 建立的具名與匿名 volume。這正是測試需要的重置行為,也表示不能拿同一份指令去清理保存正式資料的環境。
那一天真正完成的東西
回頭看,那天的產出不是幾個 commit,而是一條可以重跑的驗證路線:
70 條單元測試守住業務規則。
32 條 Mock E2E 守住前端主要流程。
Fake API 接住外部發布,不碰正式帳號。
Docker Compose 把全端環境變成可啟動、可清理的設定。
測試抓到狀態漏改、測試識別碼不同步和正式 URL 寫死等問題。
如果沒有後面這些,AI 只是更快交出一批「看起來完成」的程式碼。
我現在願意讓 AI 多做一點,不是因為它更有自信,而是因為失敗時有測試會紅、有 payload 可以查、有環境可以重建。能把錯誤變成明確訊號後,速度才真的有用。