logo
menu
post-banner

2024.3.26

SHARE ON |

fb
fb
fb

What is API testing

以現代主流的網頁架構多半是前後端分離式,透過 API 的方式互相溝通,API 測試主要著重在不透過使用者介面,直接測試背後的商業邏輯是否設計正確,同時也可以測試伺服器內各項子服務是否運作正常,溝通順暢,且通常 API 都有嚴謹的定義,因此適合透過自動化的方式進行。

Tool - Postman

Overview

postman 主要的功能是可以送出 http request 來模擬前端呼叫後端 API,並在送出 request 前後經過 script 處理,送出 request 前的 pre-request script 主要用來設定測試案例資料或設定測試用的變數,test script 則用來接收 response 並比較 response 和預期的結果是否一致

每次 request 送出時會依照以下的順序執行 script

https://assets.postman.com/postman-docs/execOrder.jpg

Sending Request

整個基本的 request 長的像這樣

Untitled

最上面設定的 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 Structure

Untitled

所謂的 collection 就是把多個 API 集合起來就可以稱做 collection,以現在的存放架構來說我們有一個關於 backend API 的 collection,下有各個不同功能分區的資料夾(/accout,/user,/animal...),各功能下單一支 API 各有自己的資料夾,每個 request 就是一個 testcase,request 下還可以放置單純做紀錄的 example

那 collection 跟 folder 有什麼區別呢?感覺都是把 API 集合起來而已?

collectionfolder
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

講解 environment 是因為 postman 提供非常多不同 scope 的 variable,以 AInimal 的情境其實可以不用用到 environment 功能,因為測試的環境只有一個

在現實公司的情境下,測試通常會經過三個環境:內網測試環境、外網測試環境、正式環境,這三個環境下的 API request 都是相同的,但可能會有些許環境變數的不同就可以放在這裡,例如 base URL 在測試環境可能是/devel/animial/...,正式環境下是/animial...,這時就可以透過快速切換環境來帶入指定的環境變數

Using variables

postman 的 variable scope 如下

scopemethod
pm.globalspm.globals.set("variable_key", "variable_value");
pm.collectionVariablespm.collectionVariables.set("variable_key", "variable_value");
pm.environmentpm.environment.set("variable_key", "variable_value");
pm.variablespm.variables.set("variable_key", "variable_value");

越上層可視範圍越大,但取用優先順序也越低,例如 local 和 global 下都有相同 key = email 的 variable,如果寫{{email}}會優先取用 local 下 email 的值

Example:use environment variable for API URL

因為每支 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")

Untitled

Example:use variable in body

可以在 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)

Writing test

postman 整合 javascript 中的 Chai assertion library 進行測試,細節的語法可以參考官方文件(放在下方的 reference),附上幾個簡單的範例說明

情境:當註冊 email 已經重複


//測試回傳的狀態是否為200
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
//測試回傳是否帶有名為message的key
pm.test("Return message", function () {
let jsonData = pm.response.json();
pm.expect(jsonData).to.have.key("message");
});
//測試JSON body裡message的value是否為2
pm.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 顯示測試的結果

Untitled

(註:此處為了示範 FAIL,故意 expect 會有一個 messag 的 key)


一個 test 裡面也可以有複數個 expect,當其中一個 expect 吐出 assertion error 則會視為整個 test 都 FAIL,但不宜寫過多個 expect 在同一個 test 裡,test 就是要找出哪個環節出問題,test 本身應該保持簡單、專一


//這樣的設計不論沒有message或message不等於2都會FAIL
pm.test("Valid return message", function () {
let jsonData = pm.response.json();
pm.expect(jsonData).to.have.key("message");
pm.expect(jsonData.message).to.eql(2);
});

Reference

Scripting in Postman | Postman Learning Center

Using variables | Postman Learning Center

Postman 之 API 測試使用全指南

Assertion Styles

AINIMAL人工社群智慧養成

找到與你最契合的人