2024.3.26
SHARE ON |
以現代主流的網頁架構多半是前後端分離式,透過 API 的方式互相溝通,API 測試主要著重在不透過使用者介面,直接測試背後的商業邏輯是否設計正確,同時也可以測試伺服器內各項子服務是否運作正常,溝通順暢,且通常 API 都有嚴謹的定義,因此適合透過自動化的方式進行。
postman 主要的功能是可以送出 http request 來模擬前端呼叫後端 API,並在送出 request 前後經過 script 處理,送出 request 前的 pre-request script 主要用來設定測試案例資料或設定測試用的變數,test script 則用來接收 response 並比較 response 和預期的結果是否一致
每次 request 送出時會依照以下的順序執行 script
整個基本的 request 長的像這樣
最上面設定的 request method 和 request URL,現在看到路徑裡{{APIurl}}
是透過變數的方式動態改變路徑,也可以直接 hardcode 上去,詳情可以見 using variable 的段落
中間是 request 可以設定的內容,如果是 get 方法就可以在 params 裡帶上必要的 query parameter,有驗證的 token 可以帶在 Authorization 欄位,有特殊的 header 就放 header 裡,必要的 header 軟體會依照設定自動生成,例如有設定 Authorization 其實就是自動在 header 欄位生成一個設定 Authorization token 的 key-value pair
body 就放 post 方法裡要帶的內容,有支援各種格式,以 API 測試來說最常使用 raw 裡的 JSON 格式,選用這個模式軟體也會自動在 header 裡帶上 content-type: application/json
再來就是 pre-request script 跟 test 撰寫 javascript 的地方以及其他的設定
最下面就是 response,可以看到 response 的 body,header 和最右邊的 status,如果有撰寫 test 的話就會在 test 的區塊顯示各個測試的結果
所謂的 collection 就是把多個 API 集合起來就可以稱做 collection,以現在的存放架構來說我們有一個關於 backend API 的 collection,下有各個不同功能分區的資料夾(/accout,/user,/animal...),各功能下單一支 API 各有自己的資料夾,每個 request 就是一個 testcase,request 下還可以放置單純做紀錄的 example
那 collection 跟 folder 有什麼區別呢?感覺都是把 API 集合起來而已?
collection | folder | |
---|---|---|
pre-script | 有 | 有 |
test script | 有 | 有 |
scope variable | 有 | 無 |
test runner | 有 | 無 |
從上面這張表來看他們蠻像的,都可以設置 pre-script 和 test script 讓從屬的 API 去執行(回顧最上面的那張圖看看 script 的執行順序)
較大的的差別是最後兩個,collection 有跨整個 collection 的 variable,folder 裡是沒有自己 scope 的 variable 的,另外是 test runner 本身也是以 collection 為單位,他會執行所有從屬的 request test,所以應該要把想一鍵測過的所有 API 放在同一個 collection 下
講解 environment 是因為 postman 提供非常多不同 scope 的 variable,以 AInimal 的情境其實可以不用用到 environment 功能,因為測試的環境只有一個
在現實公司的情境下,測試通常會經過三個環境:內網測試環境、外網測試環境、正式環境,這三個環境下的 API request 都是相同的,但可能會有些許環境變數的不同就可以放在這裡,例如 base URL 在測試環境可能是/devel/animial/...,正式環境下是/animial...,這時就可以透過快速切換環境來帶入指定的環境變數
postman 的 variable scope 如下
scope | method |
---|---|
pm.globals | pm.globals.set("variable_key", "variable_value"); |
pm.collectionVariables | pm.collectionVariables.set("variable_key", "variable_value"); |
pm.environment | pm.environment.set("variable_key", "variable_value"); |
pm.variables | pm.variables.set("variable_key", "variable_value"); |
越上層可視範圍越大,但取用優先順序也越低,例如 local 和 global 下都有相同 key = email 的 variable,如果寫{{email}}
會優先取用 local 下 email 的值
因為每支 API 各自的 endpoint URL 都不同,但可以藉由各獨立資料夾的 pre-script 來拼出 URL
//設定environment variable baseurl = "https://devel.ainimal.io/api"//設定environment variable APIurl = ""//在accout folder的pre-script加上pm.environment.set("APIurl",pm.environment.get("baseurl") + "/account")//在register folder的pre-script加上pm.environment.set("APIurl",pm.environment.get("APIurl") + "/register")
可以在 body 裡使用{{variable}}
後使用 pre-script 動態設定 body 內容
情境:測試註冊新帳號 API 為了讓 email 不重複,在 email 中帶上 timestamp
body:
{ "email": "{{newEmail}}", "pwd": "APItest", "nickname": "APItest", "birth": "1999-09-09", "gender": "male", "thirdParty": 0}
pre-script
let emailWithDate = "APItest" + Date.now().toString() + "@gmail.com"pm.variables.set("newEmail",emailWithDate)
postman 整合 javascript 中的 Chai assertion library 進行測試,細節的語法可以參考官方文件(放在下方的 reference),附上幾個簡單的範例說明
情境:當註冊 email 已經重複
//測試回傳的狀態是否為200pm.test("Status code is 200", function () { pm.response.to.have.status(200);});//測試回傳是否帶有名為message的keypm.test("Return message", function () { let jsonData = pm.response.json(); pm.expect(jsonData).to.have.key("message");});//測試JSON body裡message的value是否為2pm.test("Valid return message", function () { let jsonData = pm.response.json(); pm.expect(jsonData.message).to.eql(2);});
開頭會是一個由 pm.test 包起來的 function,第一個參數放這支 test 的名稱,第二個參數再傳入一個有機會吐出 assertion error 的 function,pm.test 會針對吐出來的 assertion error 顯示測試的結果
(註:此處為了示範 FAIL,故意 expect 會有一個 messag 的 key)
一個 test 裡面也可以有複數個 expect,當其中一個 expect 吐出 assertion error 則會視為整個 test 都 FAIL,但不宜寫過多個 expect 在同一個 test 裡,test 就是要找出哪個環節出問題,test 本身應該保持簡單、專一
//這樣的設計不論沒有message或message不等於2都會FAILpm.test("Valid return message", function () { let jsonData = pm.response.json(); pm.expect(jsonData).to.have.key("message"); pm.expect(jsonData.message).to.eql(2);});
Scripting in Postman | Postman Learning Center