1. 程式人生 > >利用Postman實現簡單的自動化測試

利用Postman實現簡單的自動化測試

1. 關於tests[]斷言

 對於系統整套介面的測試最好是建立系統相關的Collection,便於以後測試,測試指令碼採用的是JavaScript語法編寫,指令碼主要寫的位置在Pre-request ScriptTests兩個欄目中,Pre-request Script主要用於在請求傳送之前執行,Tests用於請求傳送之後執行,在Postman中也提供了一些簡單的斷言,比如:

// 判斷返回的狀態碼是否為200
tests["Status code is 200"] = responseCode.code === 200;

// 判斷返回的內容中是否存在指定關鍵字
tests["Body matches string"
] = responseBody.has("關鍵字"); // 判斷返回內容是否跟預期完全相等。 tests["Body is correct"] = responseBody === "預期的內容"; // responseBody為字串型別,支援轉為 Json 格式 var jsonData = JSON.parse(responseBody); tests["Your test name"] = jsonData.value === 100; // 判斷請求時長是否小於200ms ,具體時長按情況自定義 tests["Response time is less than 200ms"] = responseTime <
200;

上述test命令的語法基本是:

test["類似於函式名字"] = 一個判斷條件

函式名字可以隨緣嘛,只要見名知意就行了(比如上面判斷狀態碼是否為200就是Status code is 200),判斷條件可以是各種形式,比如數值、字串的相等可以用===、響應體中包含關鍵字可以用responseBody.has("關鍵字")函式、以及><等等,只要最後返回的是一個布林值即可,為true即表示通過,false為失敗,tests的直接賦值作用比較侷限,如果在指令碼中進行一些其他非同步操作,則需要用到pm.test了,比如:

pm.test("Status code is 200", function
() { pm.response.to.have.status(200); });

一般使用test賦值和pm.test/pm.expect已經可以滿足基本的測試需求了。也可以在測試請求拿到結果後再根據這些結果傳送新的新的請求,然後新增斷言,如:

// 將JSON響應體轉成json
let responseJSON = JSON.parse(responseBody)

// 獲取關注的第一個使用者,並請求他的使用者資訊
pm.sendRequest(responseJSON[0].url, function (err, response) {
  let responseJSON = response.json()
  pm.test('has email', function () {
    pm.expect(responseJSON.email).is.be.true // 如果使用者email不存在,斷言則會失敗
  })
});

如果我們有一些動態介面要進行測試,可以嘗試這種寫法,一級介面返回List,二級介面根據List的ID進行獲取對應資訊。

2. 關於變數globalenvironment

 Postman提供了兩種變數:一個是global,一個environment。其中global可以像下面這樣操作:

pm.globals.set("variable_key", "variable_value") // set variable
pm.globals.get("variable_key") // get variable
pm.globals.unset("variable_key") // remove variable

上述是使用指令碼的方式設定global變數,這一點在Account中很實用,使用者在登入後可以直接利用pm.globals.set("variable_key", "variable_value")的方式將cookie設定到全域性變數中,這樣後續的操作就可以利用這個cookie獲取到使用者的狀態是登入的狀態。變數設定完,可以在測試的URL中使用{{..}}雙括號的形式包裹global變數來使用。

environment變數的權重要比global變數更高一些,針對某些環境來進行設定,操作方式和上述類似(也是用雙花括號的形式包裹變數即可),在發起請求(一個或多個)時,可以勾選對應的環境來使用不同的變數,environment變數可以使用的位置如下:

  • URL
  • URL params
  • Header values
  • form-data/url-encoded values
  • Raw body content
  • Helper fields

在對大量API測試時,使用environment設定domaincontext-path是比較推薦的,比如:

// 在環境管理中配置一個domain變數,值為https://api.github.com
domain: https://api.github.com

// 使用雙括號的形式在URL中引用環境變數
{{domain}}/res1
{{domain}}/res2

具體設定環境變數時可以這麼幹:

postman.setEnvironmentVariable("variable_key","variable_value");

postman內部也提供了三種隨機數的生成方式(未測試通過):

  • {{$guid}}:新增一個V4風格GUID;
  • {{$timestamp}}:將當前的時間戳,精確到秒;
  • {{$randomInt}}:新增0和1000之間的隨機整數;

3. Run Collection

 在自動化測試過程中,通常是通過 Run Collection 的方式一次跑大量的API,Collection 建好後直接點選左上方的Runner按鈕,即可進入介面,對其中的幾個引數做一些說面:

CollectionRunner說明 上述介面的引數依據實際情況進行設定即可。

關於介面的執行順序

 預設情況下,介面是按照我們編寫的順序執行的,即介面在前面的就先執行,在後面就後執行,如果想手動指定介面的執行順序,可以在介面的Tests一欄中使用setNextRequest函式指定下一個要執行的介面,如:

# 當前介面執行完畢後就會繼續執行Request2介面,而不管位置上在它下一個的介面
postman.setNextRequest("Request2");

4. 變數解析

 在通過postman中在RequestBody中放List,遇到JSON解析問題,原來是要往裡面塞一個List<Long> feedbackIds,後來在postman中直接這麼放的:

{
	"feedbackIds":[
		1194812025388864,
		1195607949901632
	]
}

然後出現下面的解析異常:

"exepct '[', but {, pos 1, json : {\n\t\"feedbackIds\":[\n\t\t1194812025388864,\n\t\t1195607949901632\n\t]\n}"

在JSON解析的時候,後端是要的一個List,而前端傳過來的確實一個物件(這一塊感覺說不太清楚,應該都有這種感覺),最終直接通過最簡單的方式傳入得以解決(傳入[xx, xx, ..]的形式),直接將傳入的資料改寫為:

[
  1194812025388864,
  1195607949901632
]

 很多情況下,API返會給前端的資料都是封裝成下面的JSON格式:

{
  "code": string,
  "message": string,
  "data": T
}

在此時斷言responseBody中的具體JSON內容時,比如返回的內容為:

{
    "code": "invitee.not.reach",
    "message": "The Invitee not reach."
}

那在斷言的時候先轉JSON再取其中的內容進行判斷:

// 轉成json
var jsonData = JSON.parse(responseBody);
// 取json中具體需要斷言的key做判斷
tests["check qualification"] = jsonData.message === "The Invitee not reach."

除此外,postman還可以斷言 response 的頭部資訊,如:

// 斷言響應頭中是否有Content-Type
tests["Content-Type is present"] = responseHeaders.hasOwnProperty("Content-Type");


// 獲取Content-Type的值
var ct = postman.getResponseHeader("Content-Type");
// 判斷Content-Type的型別是否相符
tests["Content-Type is image/gif;charset=UTF-8"] = postman.getResponseHeader("Content-Type") === "image/gif;charset=UTF-8";

// 判斷Cookie的值,cookie一般都是很多cookie一起,中間以分號間隔
var cookied = postman.getResponseHeader("set-cookie");
// 將多個cookie字串切割為一個個單個的cookie
cookies = cookied.split(";");
// 將該介面寫入的cookie中的最後一個設定為postman全域性環境變數,從而影響後面介面的測試
postman.setEnvironmentVariable("Cookie",cookies[0]);

// 如果知道了cookie的名字,想直接取這個cookie的值
var cuk_yk = postman.getResponseCookie("cuk_yk").value;

注意

上述流程中在獲取整個cookie時使用的是postman.getResponseHeader("set-cookie")這個函式,如果這個介面在後臺邏輯內部有設定cookie的行為,第一次使用postman測試該介面時postman.getResponseHeader("set-cookie")函式可以獲取到設定的cookie的頭欄位set-cookie,但是一旦這個執行過該介面後cookie被寫進去了,沒有清cookie執行第二次的時候,postman發現該cookie存在就不會去設定對應的cookie,介面響應體中也不會出現set-cookie頭欄位,所以最終獲取的cookiednull,從而也導致cookied.split(";")函數出現TypeError: Cannot read property 'split' of undefined,因為獲取的cookied變數為null,沒法呼叫該函式,很多人會使用(cookied || "").split(";")方式處理來避免這個錯誤,其中(cookied || "")其實類似於三目運算的過程,如果cookied不為null結果就為cookied,否則結果為一個空串。

5. 具體操作

 這裡只記錄我遇到的一些不太注意的東西,常規操作自行百度,有下面一些:

關於環境變數

 在建立環境時,我以為只有在Run Collection時才能使用,然後為了在測試單個介面時,在每個介面的Pre-requestScript中都用指令碼寫了domain和context-path:

pm.environment.set("domain","http://www.xxxx.com");
pm.environment.set("contextpath","/api");

但實際根本不需要,在配置好環境變數後,在下圖的紅色框中選用即可:

環境變數

關於除錯或postman輸出、列印

 postman在寫測試指令碼的時候也是可以進行簡單列印除錯的,只是之前沒有用過,但不是常規意義上打端點進行debug,而是利用console.log()函式將變數進行輸出,關鍵是輸出你最起碼有個類似於控制檯的地兒啊,這玩意找了大半天,調出postman控制檯的操作流程如下:頂部選單欄View–> Show Postman Console,或者直接快捷鍵Ctrl+Alt+C,這樣在指令碼使用console.log()就可以將需要檢視的變數顯示出來了。