API 測試裡的五種活動
功能測試。 單一端點是否做對了事,包括在輸入有問題的時候。從這裡開始。其他一切都以它為前提。
整合測試。 一連串的呼叫是否產生正確的結果。大多數使用者看得見的錯誤,其實都出在這裡。
合約測試。 兩個服務對資料結構的認知是否一致。在各自獨立部署時很有價值,但看不出正確性。
另外兩種分別是 負載測試,回答承載量的問題,需要專用的流量產生工具;以及 安全行為測試,主要是授權檢查,應該和功能測試放在一起,而不是排進每季一次的專案活動。
值得採用的執行順序
功能測試,針對重要的那些端點。 包括負向案例。其他一切都建立在這之上。
整合測試,針對你們真實的使用者流程。 每條三到五個步驟,而不是十二個。
在各處加上授權檢查。 成本很低,而物件層級的授權失效是最常被利用的 API 漏洞。
合約測試,如果服務是各自獨立部署的話。 如果你們所有東西都一起部署,就跳過這一步。
負載測試,在發布之前。 放在最後,因為對一個行為本來就不對的端點做負載測試,量到的只是你能錯得多快。
不管你選哪個工具,都會遇到的四個問題
有四件事決定一套 API 測試能不能撐過第一年:會過期的 session、只存在於執行期的值、彼此相依的呼叫,以及沒人清理的資料。TestSprite 以 Auto-Authentication、Dynamic Variables、Dependency Chains 和 Auto-Cleanup 來處理這四件事,詳見 API 測試說明文件。
每個團隊都會以相同的順序碰到這些問題,而且多半是在毫無準備的情況下撞上。一開始就把它們設計進去,決定了一套測試是能長久存活,還是最後被隔離停用。
最關鍵的那一個斷言
要對回應內容做斷言,不能只看狀態碼。該有一筆資料的地方卻回傳 200 加一個空清單,這是個錯誤,但只檢查狀態碼的測試會判定它通過。光是養成這個習慣,抓到的真實缺陷就比任何其他單一改變都多。
前十個測試案例,具體來說
如果測試套件還是空的,最難的是決定從哪裡開始,而泛泛的答案只會浪費一個禮拜。以下這份清單適用於大多數產品。
三個針對你的產品最核心的那個物件:建立它、把它取回來並針對欄位做斷言、刪除它並確認它真的不見了。兩個針對授權:同一個讀取請求,一次不帶憑證,一次帶另一個使用者的憑證。兩個針對輸入:缺少必填欄位,以及數值超出範圍。兩個針對那條讓你在發布前會緊張的流程,不管對你來說那是哪一條。一個針對上次壞掉的那個端點。
十個案例,一個上午就能寫完,而且涵蓋了造成大多數事故的那幾種樣態。之後要往哪裡擴充,應該由實際出問題的地方來決定,而不是由覆蓋率目標來決定,因為後者做出來的測試套件往往又大又不到位。
今天可以從哪裡開始
建一個專案指向你的服務,讓探索流程列出現有的端點,然後在跑任何測試之前先讀過產生出來的測試計畫。這份計畫告訴你的 API 資訊,會比第一次的測試結果還多,而且它正是你把產品知識補進去的地方。
終端機
npm install -g @testsprite/testsprite-cli
testsprite setup
如果你不想安裝任何東西,在儀表板上也能做到同樣的事。命令列能做的其他所有事情,都寫在 CLI 儲存庫。
GitHub App 是一個在 TestSprite 儀表板上設定的 webhook。它會監聽你的 pipeline 原本就會產生的部署事件,所以你的儲存庫完全不用改。
GitHub Actions 則是把這個步驟放進你自己的工作流程裡,從終端機完成設定。
TestSprite 在這五種活動中的位置
功能測試、整合測試,以及安全測試中屬於行為的那一半。它會實際操作執行中的服務,根據一次探索掃描加上你的規格文件產生測試計畫,並涵蓋手寫測試會略過的負向案例。
Auto-Authentication 讓 session 在整趟執行過程中保持有效,Dynamic Variables 在呼叫之間傳遞數值,Dependency Chains 依據每個案例需要什麼、產生什麼來推導執行順序,Auto-Cleanup 則剛好只清掉這次執行所建立的資料。不論用哪種工具,決定一套測試能不能撐過第一年的都是這四件事;把它們做成產品內建的能力,正是「擴充測試」和「維護測試」之間的差別。
合約測試和負載測試仍然是各自獨立的工具,而這套做法可以和兩者並行。你得到的是大多數使用者看得見的缺陷所在的那一層,不必自建框架就能涵蓋,而且每一個 pull request 都會執行。
我們需要多少覆蓋率?
涵蓋那些一旦壞掉你會很難交代的使用流程,再加上每一個牽涉到金流或權限的端點。擴充的依據應該是實際發生的事故,而不是朝著某個百分比前進。
我們應該直接對正式環境測試嗎?
應該對一個具代表性的環境測試。為了配合測試而在正式環境建立和刪除資料,本身就有風險。
我們一定要有規格文件嗎?
有幫助,但不是必要。對執行中的服務做一次探索掃描,加上一份需求文件,就能得到一份可用的測試計畫。
那 mock 呢?
對你無法掌控的第三方服務做 mock。對自己的服務做 mock,測到的只是那個 mock。
測試應該多久跑一次?
功能測試和整合測試在每一個 pull request 都跑,負載測試則安排固定排程。一週跑一次的測試,會在問題發生一週之後才發現它。