為什麼 API 整合測試需要一張明確的相依圖

執行順序變成碰運氣測試在執行器剛好挑到的順序下通過,換一台機器就失敗。接著有人裝了一個排序外掛,問題就此固定下來。
一個失敗看起來像二十個建立資源的那一步失敗,下游全部跟著失敗,螢幕上滿是紅色。找出第一個真正的失敗本身就變成一項工作。
平行執行並不安全不知道誰依賴誰,就無法安全地同時執行任何東西。於是測試套件只能維持序列執行,而且很慢。

讓相依關係變得明確

解法是讓每個測試宣告自己需要什麼、產出什麼。有了這些資訊,執行器就能推導出安全的執行順序,互不相干的分支可以平行跑,而某一步失敗時,依賴它的測試會被標記為略過而不是失敗。原本二十列紅色,變成一個失敗加十九個略過,除錯體驗完全不同。

這正是 Endpoint Tests 與 Integration Tests 的差別:前者一次涵蓋一條路由,後者則是多步驟的呼叫鏈,前一個回應會餵進下一個步驟。

值傳遞的問題

建立資源的呼叫會回傳一個識別碼,後面的步驟都需要它。把它寫死,測試就只能成功一次;把它擷取下來,整條鏈才能把資料正確往下傳。寫成文字聽起來理所當然,但這正是上個月還會通過的測試套件今天卻失敗的最常見原因。

呼叫鏈中的清理

整合測試比端點測試製造更多狀態,而且製造的順序帶有相依關係,拆解時必須尊重這個順序。你不能在刪除訂單之前先刪掉客戶。只有綁定「這次執行實際建立了什麼」、並依相依關係反向進行的清理,才能在並行執行下存活。

有四件事決定一套 API 測試能不能撐過第一年:會過期的工作階段、只存在於執行期的值、彼此相依的呼叫,以及沒人清掉的資料。TestSprite 以 Auto-Authentication、Dynamic Variables、Dependency Chains 和 Auto-Cleanup 處理這些問題,詳見 API 測試文件。

當呼叫鏈在第四步失敗時該怎麼做

宣告相依關係的價值,最清楚展現在失敗結果長什麼樣子,而這份結果的閱讀順序值得先知道。

第一,確認問題出在這一步本身,還是出在它的輸入。收到錯誤識別碼的步驟之所以失敗,是因為上游產出了錯的東西;去修那一步只是在治標。

第二,確認它在乾淨狀態下是否也會失敗。一條跑第一次會過、重跑就失敗的鏈,是在告訴你清理沒有發生;那和你正在看的問題是兩回事,而且往往更重要。

第三,到這時候才去看端點本身。多數情況下,有價值的資訊都在前兩項檢查裡——這也是為什麼一份攤平的紅色清單,除錯成本遠高於一張只有一個失敗和十九個略過的相依圖。

把呼叫鏈維持得短

一條十二步的鏈在第九步失敗,既難診斷又重跑得慢。三到五步、涵蓋一個使用者意圖,才是能一直派上用場的長度。鏈太長通常代表兩段使用者旅程被合在一起了。

開始使用

終端機

npm install -g @testsprite/testsprite-cli
testsprite setup

如果你不想安裝任何東西,儀表板也能做到同樣的事。命令列能做的其他事情,全都寫在 CLI 儲存庫。

從儀表板連接儲存庫,測試就會從你原本就會產生的部署開始執行;或者,你也可以改成在自己的工作流程裡加上一個步驟。

TestSprite 如何讓相依圖變得明確

每個測試案例都會宣告自己需要什麼、產出什麼,Dependency Chains 再據此推導出安全的執行順序。互不相干的分支可以平行執行;某一步失敗時,依賴它的案例會被標記為略過而不是失敗,於是二十列紅色變成一個失敗加十九個略過。

值的傳遞交給 Dynamic Variables 處理,因此鏈上帶的是建立呼叫實際回傳的識別碼,而不是某個人貼上去的數字。Auto-Cleanup 會依相依關係反向清掉每次執行所建立的東西,這正是並行執行能夠安全進行的原因。

好處在呼叫鏈第一次斷掉時就會顯現。你看到的是一個明確指出分歧點的失敗,而不是滿螢幕要逐條讀過去的紅色——這是五分鐘就能定位,和賠上一整個下午的差別。

這和端對端測試有什麼不同?

端對端測試通常是透過介面進行。API 整合測試則是在服務層跑同樣的使用者旅程,速度更快,也能更精準地指出失敗發生在哪裡。

整合測試該使用真實的相依服務嗎?

就整合測試而言,是的,這正是重點。把你要整合的對象模擬掉,回答的是另一個問題。

步驟之間的測試資料要怎麼處理?

擷取每一步的產出,再往下傳給後續步驟。共用的預置資料很方便,直到兩條鏈碰到同一筆記錄為止。

鏈上有第三方服務怎麼辦?

有沙箱環境就用它。沒有的話,就把那一步隔離出來,並接受這條鏈存在一個邊界。

我們需要多少整合測試?

每一段重要的使用者旅程一個,而不是每一種端點組合一個。組合是無限的,旅程不是。

簡短版本

要嘛把相依圖宣告出來,要嘛永遠都在為它除錯。

API 整合測試談的是一連串的步驟,而這些步驟背後有一張相依圖。讓每個測試宣告自己需要什麼、產出什麼,你就能換到安全的執行順序、平行執行,以及讀得懂的失敗結果。用擷取取代寫死數值,並把呼叫鏈維持得短。