1. 程式人生 > >PostMan介面測試(很全面的介面測試教程)

PostMan介面測試(很全面的介面測試教程)

## 一:理論部分 ### 1. 前言 在前後端分離開發時,後端工作人員完成系統介面開發後,需要與前端人員對接,測試除錯介面,驗證介面的正確性可用性。而這要求前端開發進度和後端進度保持基本一致,任何一方的進度跟不上,都無法及時完成功能模組的測試。 ​ 做為後端開發人員,要求獨立開發完成某個介面後,開發人員自己需要先測試通過後再提交給測試人員進行測試,否則會出現到測試人員哪裡業務流程根本就走不通,或者BUG會過多的情況等。 ​ 市場上有很多優秀的,完善的介面測試工具,比如SoapUI,Postman,JMeter、yapi等,能夠高效的幫助後端開發人員獨立進行介面測試。這裡使用Postman介面測試工具,分別介紹如何對GET請求和POST請求進行介面測試。 ### 2. Postman簡介 Postman是一個介面測試工具,在做介面測試的時候,Postman相當於一個客戶端,它可以模擬使用者發起的各類HTTP請求,將請求資料傳送至服務端,獲取對應的響應結果, 從而驗證響應中的結果資料是否和預期值相匹配;並確保開發人員能夠及時處理介面中的bug,進而保證產品上線之後的穩定性和安全性。 它主要是用來模擬各種HTTP請求的(如:get/post/delete/put..等等),Postman與瀏覽器的區別在於有的瀏覽器不能輸出Json格式,而Postman更直觀介面返回的結果。 ### 3.Postman介面圖 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104426247-1353050986.png) **各個功能區的使用如下:** l **快捷區**: 快捷區提供常用的操作入口,包括執行收藏夾的一組測試資料,匯入別人共享的收藏夾測試資料(Import from file, Import from folder, Import from link等),或新建請求、收藏夾、環境變數等。 l **側邊欄**: 包括搜尋欄, Request 請求的歷史記錄和收藏夾管理。 l **功能區**: Request 請求設定,檢視 Response 響應結果和測試結果,可以將請求儲存到收藏夾。 l **設定區**:設定和管理環境變數和全域性變數。 ## 二:工具應用 ### 1. 新建介面 #### 1.1 建立Collection集合 在剛開始一個專案時,為了後續便於組織和管理,把同屬該專案的多個 API,放在一組裡。所以要先去新建一個 Collection: New -> Collection ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104535797-666216787.png) #### 1.2 建立請求 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104543834-230447853.png) #### 1.3 設定HTTP請求 設定 HTTP 的 Method 方法和輸入 api 的地址以及請求引數或請求體 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104557290-1220359541.png) 以下為獲取微信公眾號為案例所設計的HTTP請求 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104609310-958659494.png) GET是請求方法,請求方法是HTTP請求的必要要素,常見的請求方法有GET和POST兩種。API地址一般為URL地址。如果是請求URL中的入參,會在Params列出引數名稱及引數取值,方便我們輕鬆的修改各入參的值。如有需要,還應該設定HTTP請求Headers部分。 如果是POST請求,需要將請求方法設定為POST,一般說來POST請求是有請求體的,固需要在Body部分中編寫正確的請求body內容和Content-Type的值(在Headers中進行設定) ##### 1.3.1 GET和POST的區別 l GET 使用URL 或Cookie 傳參,而POST將資料放在Body 中。 l GET的URL 在長度上會有限制,而POST沒有。 l POST比GET相對安全,因為在位址列不可見。 l 一般POST請求用來獲取資料,POST請求用來發送資料。 **對於上面的區別,其實第一點POST也可以將資料放在URL裡,GET請求其實也沒有長度限制,POST請求看起來是隱式的,但是可以通過抓包拿到引數。** #### 1.4 傳送HTTP請求 點選上圖中藍色Send圖示即可傳送請求,驗證請求結果是否正確。下圖是對應的響應結果,包含Body和Headers兩個部分,Body即響應體正文,Headers即為響應頭資訊,響應頭不包含響應狀態碼和狀態資訊部分。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104701022-1044304827.png) 響應體包含三種檢視模式,分別為:Pretty預設模式、Raw原始資料格式,Preview預覽模式(此模式針對HTML頁面效果很好)。 #### 1.5 關聯技術 關鍵技術是將前一個請求的響應結果儲存到變數中,再將此變數在後續請求中進行引用。 ##### 1.5.1 儲存前一個請求的響應資料 因為Tests模組是後置模式,可對響應進行處理。我們可以通過賦值方式把響應結果儲存到變數中,參考程式碼如下: ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104719437-308552256.png) ##### 1.5.2 對後一個請求進行引數化 因前面將access_token的值儲存到了環境變數中,所以在該請求中,只需要進行引數引用即可。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104752241-1011181615.png) ##### 1.5.3 關聯的高階操作 利用Send a request實現前置步驟,例如:客服發訊息模組,前置步驟是獲取access_token,我們可在Pre-request Script前置步驟中傳送請求,將該請求的結果儲存到環境變數accesstoken中,然後在主請求中引用該環境變數即可。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104807619-243748909.png) ##### 1.5.4 附:前置步驟中傳送POST請求 POST請求相比GET請求要複雜一點,因為其需要加入請求Header和請求Body,以下是Pre-request Script在傳送POST請求的案例: * 構造一個登入請求 ```javascript const loginRequest = { url: 'http://115.28.108.130:5000/api/user/login/', method: "POST", body: { mode: 'urlencoded', // 模式為表單url編碼模式 urlencoded: 'name=張三&password=123456' } }; ``` * 傳送請求 ```javascript pm.sendRequest(loginRequest, function (err, res) { console.log(err ? err : res.text()); }); ``` 傳送JSON格式請求與傳送POST請求類似,以下采用了raw模式傳送請求體。 * 構造一個註冊請求 ```javascript const regRequest = { url: 'http://115.28.108.130:5000/api/user/reg/', method: 'POST', header: 'Content-Type: application/json', //注意要在Header中宣告內容使用的型別 body: { mode: 'raw', // 使用raw(原始)格式 raw: JSON.stringify({ name: '小小', password: '123456' }) //要將JSON物件轉為文字傳送 } }; ``` * 傳送請求 ```javascript pm.sendRequest(regRequest, function (err, res) { console.log(err ? err : res.json()); // 響應為JSON格式可以使用res.json()獲取到JSON物件 }); ``` 因為HTTP請求都支援raw格式,我們只要能夠獲取請求的raw格式,便可採用raw模式傳送任意型別的請求體了。 ### 2.介面資料用例 #### 2.1 資料用例設計 Postman支援的是csv檔案作為資料用例,資料用例包含三大部分,分別為:用例標題(title),入參(grant_type,appid,secret),期望結果(expected) | **title** | **grant_type** | **appid** | **secret** | **expected** | | -------------- | ----------------- | ------------------ | -------------------------------- | ------------ | | 正確的用例 | client_credential | wx508a5cacbbfc1141 | fa4fc7f17ddead12d7cdcd994e7d2543 | 7200 | | grant_type錯誤 | client_credentia | wx508a5cacbbfc1141 | fa4fc7f17ddead12d7cdcd994e7d2543 | 40002 | | appid錯誤 | client_credential | wx508a5cacbbfc114 | fa4fc7f17ddead12d7cdcd994e7d2543 | 40013 | | secret錯誤h | client_credential | wx508a5cacbbfc1141 | fa4fc7f17ddead12d7cdcd994e7d254 | 40001 | 我們可以根據黑盒用例設計方法如等價類、邊界值、判定表、正交實驗法對入參進行用例設計,得到各種不同的測試場景(取值組合) #### 2.2 資料用例引數化 前面我們在csv檔案中編寫好了資料用例,且保證第一行為引數的名稱。將請求中入參值依次進行替換,在Postman中引數的編寫規格為兩個花括號,如:{{appid}} ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104830826-1694615954.png) #### 2.3 設定迭代器 要讀取所有的測試用例,需要設定迭代器讓其迴圈讀取那些測試資料。Postman中設定迭代器需在Run中完成,請看【4.Runner執行測試】 ### 3.結果檢查(斷言) Postman的斷言功能在Test模組中,比如要測試返回結果是否含有某一字串,就需要在Test中編寫相應的程式碼,Test中的程式碼使用的是JavaScript語法。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104843664-452299200.png) #### 3.1 Postman自帶Tests函式 Postman提供了參考程式碼供我們選擇即可,主要斷言程式碼有如下幾種: \# 斷言狀態碼是否為200,在斷言中此種斷言價值不高 ```javascript pm.test("Status code is 200", function () { pm.response.to.have.status(200); }); ``` \# 斷言響應文字中是否包含某個資料串,常用 ``` javascript pm.test("Body matches string", function () { pm.expect(pm.response.text()).to.include("string_you_want_to_search"); }); ``` \# 使用JsonPath斷言 ```javascript pm.test("Your test name", function () { var jsonData = pm.response.json(); pm.expect(jsonData.value).to.eql(100); }); ``` \# 檢查響應正文中是否包含某個子串 ``` javascript pm.test("Body is correct", function () { pm.response.to.have.body("response_body_string"); }); ``` \# 響應資訊包含列表中其中某一個 ```javascript pm.test("Successful POST request", function () { pm.expect(pm.response.code).to.be.oneOf([201,202]); }); ``` \# 將xml響應轉為json ```javascript var jsonObject = xml2Json(responseBody); ``` #### 3.2 手工tests函式 也可以使用斷言並賦值的形式,相對而言,以下方式會更為簡潔實用。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104906873-1008787771.png) 常見的斷言程式碼有: \# 檢查response的body中是否包含字串 ```javascript tests["Body matches string"] = responseBody.has("string_you_want_to_search"); ``` \# 檢查JSON節點的值和節點元素的個數為5 ```javascript var data = JSON.parse(responseBody).city; //把JSON字串轉化為物件 tests["Your test name"] = data.value===100; tests["program's lenght"] = data.programs.length===5; ``` \# 驗證Response time是否小於某個值 ```javascript tests["Response time is less than 200ms"] = responseTime < 200; ``` #### 3.3 tests高階操作 我們可以引用資料用例csv文件中的預期結果進行斷言。 ```javascript var jsonData = JSON.parse(responseBody) ; # data.expected 為csv資料檔案中的預期結 tests["測試結果通過"] = jsonData.expires_in===data.expected ; ``` 在tests還可以使用判斷語句進行斷言,如下: ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427104924703-1231663608.png) 在Postman中斷言的操作非常靈活,需要同學們多進行練習。 ```javascript pm.test("預期結果包含:長沙,實際結果為:"+result, function () { if(JSON.parse(responseBody).city==="長沙"){ pm.expect(pm.response.text()).to.include("千里"); pm.expect(pm.response.text()).to.include("長沙"); }else if(JSON.parse(responseBody).city==="Changsha"){ pm.expect(pm.response.text()).to.include("千里"); pm.expect(pm.response.text()).to.include("Changsha"); }else if(JSON.parse(responseBody).city==="長沙"){ pm.expect(pm.response.text()).to.include("千里"); pm.expect(pm.response.text()).to.include("長沙"); } }); ``` ### 4.Runner執行測試 #### 4.1 設定迭代器 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105315770-383070439.png) #### 4.2 檢視執行結果 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105325462-1331927071.png) ## 三:其他事項 ### 1.儲存介面配置 待整個介面都除錯完畢後,記得點選 Save 去儲存介面資訊: ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105019191-782729724.png) 去儲存當前 API 介面,然後需要填寫相關的介面資訊: l Request Name: 請求的名字 我一般習慣用儲存為 介面的最後的欄位名,比如 l Request Description: 介面的描述 最好寫上該介面的要實現的基本功能和相關注意事項 支援 Markdown 語法 Select a collection or folder to save: 選擇要儲存到哪個分組(或資料夾) 往往儲存到某個 API 介面到所屬的該專案名的分組 ### 2. Postman的引數 #### 2.1 自動解析多個引數Param 比如,對於一個 GET 的請求的 url 是: `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx508a5cacbbfc1141&secret=fa4fc7f17ddead12d7cdcd994e7d2543` 對應著其實是?key=value形式中包含多個 Http 的 GET 的 query string=query parameters Postman 可以自動幫我們解析出對應引數: ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105036649-11325508.png) #### 2.2 臨時禁用引數 在不刪除某引數的情況下,如果想要暫時不傳引數,可以方便的通過不勾選的方式去實現 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105044712-1306494929.png) #### 2.3 批量編輯多個引數 如果想要批量的編輯引數,可以點選右上角的Bulk Edit,去實現批量編輯。 ### 3. Postman傳送POST請求詳講 POST 請求不能像GET一樣直接在瀏覽器輸入就可以請求,需要藉助工具來完成。 #### 3.1.1 傳送key-value 的請求: 以login 介面為例,在Body 中選取**"form-data"** 格式,輸入所需的key-value, 選取對應的環境變數。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105104041-1268949398.png) #### 3.1.2 傳送json格式的請求: 以add user 介面為例,在Body 中選取**"raw"** 格式,根據介面文件輸入json 資料, 有需要應用環境變數的選取環境變數。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105113788-2022830149.png) #### 3.1.3 傳送檔案的請求 以file upload 介面為例,在Body 中選取**"form-data"** 格式,在key 裡輸入"file",在右邊的下拉里選取型別為"File",點選"Choose Files" 就可以上傳本地檔案了。 ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105125256-2121388460.png) ### 4. 環境變數設定 #### 4.1 設定環境變數的意義 在測試 API 期間,往往存在多種環境,對應 IP 地址(或域名也不同)。比如: Dev:http://192.168.1.21/oa/index.jsp l 用於開發期間的線上的 Development 的測試環境 LocalTest:http://192.168.1.42/oa/index.jsp l 用於開發期間配合後臺開發人員的本地區域網內的本地環境,用於聯合除錯 API 介面 Product:http://www.example.com/oa/index.jsp l 用於開發完成釋出到生產環境 在測試API期間,往往需要修改API地址,這樣效率會比較低且更換後的地址沒法儲存。 #### 4.2 環境變數設定 在Postman的設定區有Environment 和 Global Variable,用於解決這個問題,實現不同環境的管理: ![](https://img2020.cnblogs.com/blog/465934/202004/465934-20200427105146287-238101285.png) 很明顯,就可以用來實現不用手動修改 url 中的伺服器地址,從而動態的實現,支援不同伺服器環境: l Production 生產環境 l Development 開發環境 l Local 本地區域網環境 *環境變數可以使用在以下地方*: l URL l URL params l Header values l form-data/url-encoded values l Raw body content **注意:在你要使用的變數名上附上****雙花括號****,一個請求只能應用一個環境變數。** #### 4.3 使用程式碼設定環境變數 我們可以在Pre-request Script和Test模組中進行環境變數設定。 --1.設定環境變數 ```javascript postman.setEnvironmentVariable("key", "value"); ``` --2.獲取環境變數 ```javascript pm.environment.get("variable_key"); ``` #### 4.4 全域性變數 全域性變數(Global Variable)顧名思義是針對於所有指令碼和所有環境將生效的變數,它的作用域大於環境變數。設定全域性變數的方法與環境變數相似: --1.設定全域性變數 ```javascript pm.globals.set("variable_key", "variable_value"); ``` --2.獲取全域性變數 ```javascript pm.globals.get("variable_ke