使用Postman做API自動化測試
06-15
Postman API 自動化測試:
高級點的用法可以使用 Postman 生成各個語言的腳本,還可以抓包,認證,傳輸文件。
僅僅做到這些還不能夠滿足一個系統的開發,或者說過於瑣碎,你仍需要頻繁地在開發環境,測試環境,生產環境中來回切換。單一的請求也不夠,你需要維護系統所有 API 的請求,並且每個請求還帶有不同的 querystring 和 body。
對應一個請求,可以添加認證信息。也可以設置代理,進行抓包。詳見 capturing http requests。
4、Example對應一個請求不同的參數以及響應,用於Mock Server 以及文檔。postman 可以根據 Collection 的結構生成文檔與Mock Server。不過都是付費功能,免費版有次數限制。二、文檔postman 自動生成文檔有助於團隊協作,解決了手動寫文檔,以及更新不及時的重大bug。對於 GET 請求,Postman 上可以添加對該欄位的描述,生成文檔。對於 POST 以及 PUT 請求,如果 Content-Type 是 form-data 或者 x-www-form-urlencoded可以添加描述生成文檔。不過如今傳遞 json 更方便靈活,所以 application/json 也會有很多,而且 json 又是不能添加註釋的。如果需要對 json 添加文檔說明的話,可以添加冗餘欄位 _{key}.comment 標明注釋{"id": 128,"_id.comment": "id",
"page": 10,"_page.comment": "頁數""pageSize": 15,"_pageSize.comment": "每頁條數"}不過這樣冗餘欄位過多,更好的解決方案是在測試中對請求進行 json 校驗,同時充當了一部分文檔的功能。畢竟 json-schema 就是用來描述數據使數據更加可讀。以上說到請求,對於響應的文檔,可以 json-schema 校驗或者每個欄位的描述,以及更多的測試用例代表更多的細節。三、Mock當伺服器端還沒有寫好 API 時,客戶端可以根據 Examples 來生成 Mock Server。
建議客戶端端自己做 Mock,與項目集成在一起,納入版本控制,方便靈活。強烈推薦 json-server,簡單好用。四、測試
測試可以使用 pm.expect 進行 BDD 測試,風格和 chai 很像,如果熟悉 chai 就很容易上手。
postman 內置了一些第三方庫,如果你更喜歡 chai ,可以直接使用,也可以使用 pm.expect底層使用 chai 實現,與 chai BDD API 一致。
postman 也有一些 http 相關的測試 API,如 status code,header, body,並且也提供了一些 snippets。
// 響應成功
pm.test(Status code is 200, () => {
pm.response.to.have.status(200)
// 響應成功 chai.expect
pm.test(Status code is 200, () => {
chai.expect(pm.response).to.have.property(code, 200)
})
// 校驗響應數據
const jsonData = pm.response.json()
chai.expect(jsonData.page).to.eql(100)
})
五、Json Schemajson-schema 可以用來描述 json 信息,使 json 更加易讀,同時也可以用來校驗 json 的合法性。主流語言都有實現 json-schema 的庫。建議對所有 GET 響應進行 json-schema 校驗,一來校驗數據,二來也可以作為文檔使用,使用 tv4 校驗 jsonpm.test("User info", () => {const jsonData = pm.response.json()
const schema = {
title: UserInfo,discription: 用戶信息,type: object,required: [age, email, name],properties: {age: {description: 年齡,type: number,mininum: 0,},
email: {description: 郵箱,type: string },name: {description: 姓名,type: string }}}
pm.expect(tv4.validate(jsonData, schema)).to.eql(true)})同樣對於請求也可以添加 json 校驗,不過更複雜一些,因為 postman 沒有直接給出獲取全部請求參數的api,需要自己解析和計算// 獲取 application/json 中的數據const json = JSON.stringify(pm.request.body.raw)// 獲取 GET query string 的數據const qs = pm.request.url.query.toObject()如果 postman 可以根據請求參數的 json-schema 自動生成數據就好了...參考:http://json-schema.orgtv4 Documentaionchai bdd - APIpostman sandbox api reference六、測試請求參數一個請求帶有若干參數,如 GET 的 querystring(search) 以及 POST 的 body,不同的參數會有不同的響應。假設一個請求不同參數返回的 json schema 完全不同,則可以寫成兩個 Request 分開測試。如果返回的 json schema 相同,只是值不同,則需要考慮傳遞了哪些參數,參數是多少。一個經典的場景,根據 filter 來篩選符合條件的列表。拿用戶列表舉例,偽代碼如下const url = /api/usersconst query = {name: san,age: 12,sex: MALE}// 注意query數據需要校驗,防止 SQL 注入const sql = `select * from users where name = ${query.name} and age = ${query.age} and sex = ${query.sex}`一個思路是根據請求的參數進行測試,一段重要的 snipet 是在 postman 中獲取 querystring,query 是一種 PropertyList 的數據,定義在 postman-collection - PropertyList。如下const name = pm.request.url.query.get(name)const age = pm.request.url.query.get(age)if (name) {pm.test(Items should match the name, () => {const jsonData = pm.response.json()expect(_.uniq(jsonData.rows.map(row => row.name))).to.eql([name])})}// 冗餘代碼有些多,postman不知道支不支持自建 snipetsif (age) {pm.test(Items should match the age, () => {const jsonData = pm.response.json()expect(_.uniq(jsonData.rows.map(row => row.age))).to.eql([age])})}當然以上 filter 只包含了最簡單的場景,其中只涉及到了相等測試。但是有不等以及包含關係呢。const query = {name: san,age: 12,sex: MALE}const sql = `select * from users where name like ${query.name} and age < ${query.age} and sex = ${query.sex}`這種請求參數依賴於前後端的協商交流,當然對測試或者一個不知情的開發來說很不友好的。當然對於後端也是不友好的,因為需要對你傳入的每個 query 來進行處理,而且以後每添加一個篩選欄位,都需要手動改一下。可以由前端自行決定需要篩選的數據,比如使用類似於 mongo 的檢索語法。graphql 是相當酷的,值得嘗試一下const query = {name: {$like: san },age: {$lt: 12 },sex: MALE}不過這對於測試的開發能力要求也比較高了,測試人員需要解析參數並且測試介面。七、測試多次請求當對一個函數進行單元測試時,需要大量的輸入以及期望輸出,在postman中,可以使用 data 來模擬多次輸入data 是一種變數,只能在Runner 中使用,有必要對每個 Folder 建立相關的data file,並且加入版本控制。…………………………using csv and json files in thepostman collection runner……………………………………http://blog.getpostman.com/2014/10/28/using-csv-and-json-files-in-the-postman-collection-runner/八、集成測試單個API測試通過後,需要把所有請求集成在一起進行測試。這時候出現了兩個問題1.如何確保API依賴2.API之間如何傳遞數據請求在 Collection 的順序就是他們的發起請求的順序,如果需要強制更改順序,可以使用 setNextRuest()在 postman 中有三種作用域的數據,data,environment,global。在請求中用 {{}} 佔位符替代。environment 可以用來更改 HOST,避免在 url 中頻繁手動切換本地環境,開發環境和生產環境。另外也可以用來傳遞數據。一個常見的場景是項目使用 token 來保存登錄信息,每次請求都需要攜帶token。可以在登錄的測試代碼中設置 token 的環境變數const url = http://{{HOST}}/api/loginpm.test(There is a token, () => {const jsonData = pm.response.json()pm.expect(jsonData.token).to.a(string)pm.environment.set(token, jsonData.token)})const urlNext = http://{{HOST}}/api/profile?token={{token}}九、測試Collection確保依賴後,可以對 Collection 新建一個 Runner,並且引入一個 data 文件來測試所有的請求。對局部的 Folder 也可以使用 Runner 以及 data 進行測試。最新版本的 postman 已經可以支持,為每個 Postman 新建變數以及 Test所有的請求都會有一些共同測試,比如測試介面是否響應成功以及以上提到的測試 filterpm.test(Response is right, () => {// status code: 2XXpm.response.to.be.success})pm.test(Filter is matching, () => {// ...})十、持續集成當可以測試 Collection 後,需要對測試加入版本控制,與項目集成在一起,保留測試記錄,以便準時定位 bug。可以與 postman 的官方工具 newman 集成在一起,但是有一點不方便的是,持續集成僅僅可以保存記錄,並不能還原記錄。newman run https://api.getpostman.com/collections/{{collection_uid}}?apikey={{postman-api-key-here}} --environment https://api.getpostman.com/environments/{{environment_uid}}?apikey={{postman-api-key-here}}十一、對比UI自動化測試按照我的理解,UI 自動化測試目的是用來測試流程是否通暢,比如登陸,註冊,退出,如果用例沒通過則截屏。但是前端需求的不斷變化,加上現在各種前端框架,導致 selector 不是特別容易獲取到且流程容易更改。而API 自動化測試用來測試數據是否正確。而且大部分問題是出在數據問題上,所以 API 自動化測試性價比比較高一些。十二、總結1.如何編寫測試用例postman 底層使用 [chai.js](http://chaijs.com/api/bdd/) 的 bdd 語法作為斷言庫,另外加了一些特有的語法。2.如何debug點擊菜單欄 View -> Show Devtools (Show Postman Console) 可以查看響應,檢查輸出,不過不能打斷點。對於系統的單個請求,可以使用 Proxy 監聽請求進行調試。3.如何使用js第三方庫對請求就行預處理以及後處理比如:發送請求時,伺服器端要求時間為 timestmap(unix) 的格式,但介面調試時可讀性過弱,是否可以使用 moment 轉化時間。收到響應時,也需要 moment 對時間進行解析,獲得更好的展現形式。或者使用 lodash 一些函數進行數據的處理。可以在 Tests 和 Pre-request Script 中編寫腳本對請求以及響應做一些處理。但是不能對數據格式化,比如日期。建議前後端交流日期時使用 ISO 格式的字元串,前後端都容易解析,並且可讀性強。4.如何管理請求依賴比如:兩個API需要有依賴關係,比如當創建完一個用戶後(註冊),獲取他的個人信息。獲取個人信息就需要依賴創建用戶這個API。使用 Environment Variables 可以管理依賴5.如何設置統一的請求參數比如:大部分介面都需要統一的 token 參數。目前好像沒什麼辦法6.如何集成到伺服器端項目中如果系統後續版本沒有通過API測試,則保留測試記錄是很重要的,版本控制可以得知該時間段內的代碼變更。以git為例,需要每次提交後運行測試,並保留測試結果。可以使用 npm 包 newman 來集成到項目中※自動化測試
※自動化測試丨如何滿足自動化測試需求?
※你們測試用例越來越多,刪不刪?
※單元測試之旅:預見優秀之①——優秀基因
※DevOps入門教程——Jenkins持續集成篇