使用 postman 給 API 寫測試
Intro
上次我們簡單介紹了 使用 postman 測試 API,這次主要來寫一些測試用例以檢查請求的響應(yīng)是否符合我們的預(yù)期以及如何使用腳本測試
使用 postman 內(nèi)置的隨機(jī)變量
postman 內(nèi)置的有一些產(chǎn)生隨機(jī)值的變量,在發(fā)送請求時(shí)隨機(jī)生成,這樣我們可以在請求中隨機(jī)生成一些用戶名,郵箱,公司名稱等等,
支持的變量如下,官方文檔:https://learning.getpostman.com/docs/postman/variables-and-environments/variables-list/
- {{$randomZipCode}}
- {{$randomCity}}
- {{$randomCityPrefix}}
- {{$randomCitySuffix}}
- {{$randomStreetName}}
- {{$randomStreetAddress}}
- {{$randomStreetSuffix}}
- {{$randomStreetPrefix}}
- {{$randomSecondaryAddress}}
- {{$randomCountry}}
- {{$randomCountryCode}}
- {{$randomState}}
- {{$randomStateAbbr}}
- {{$randomLatitude}}
- {{$randomLongitude}}
- {{$randomColor}}
- {{$randomDepartment}}
- {{$randomProductName}}
- {{$randomPrice}}
- {{$randomProductAdjective}}
- {{$randomProductMaterial}}
- {{$randomProduct}}
- {{$randomCompanyName}}
- {{$randomCompanySuffix}}
- {{$randomCatchPhrase}}
- {{$randomBs}}
- {{$randomCatchPhraseAdjective}}
- {{$randomCatchPhraseDescriptor}}
- {{$randomCatchPhraseNoun}}
- {{$randomBsAdjective}}
- {{$randomBsBuzz}}
- {{$randomBsNoun}}
- {{$randomDatabaseColumn}}
- {{$randomDatabaseType}}
- {{$randomDatabaseCollation}}
- {{$randomDatabaseEngine}}
- {{$randomDatePast}}
- {{$randomDateFuture}}
- {{$randomDateBetween}}
- {{$randomDateRecent}}
- {{$randomMonth}}
- {{$randomWeekday}}
- {{$randomBankAccount}}
- {{$randomBankAccountName}}
- {{$randomCreditCardMask}}
- {{$randomCurrencyAmount}}
- {{$randomTransactionType}}
- {{$randomCurrencyCode}}
- {{$randomCurrencyName}}
- {{$randomCurrencySymbol}}
- {{$randomBitcoin}}
- {{$randomBankAccountIban}}
- {{$randomBankAccountBic}}
- {{$randomAbbreviation}}
- {{$randomAdjective}}
- {{$randomNoun}}
- {{$randomVerb}}
- {{$randomIngverb}}
- {{$randomPhrase}}
- {{$randomImage}}
- {{$randomAvatarImage}}
- {{$randomImageUrl}}
- {{$randomAbstractImage}}
- {{$randomAnimalsImage}}
- {{$randomBusinessImage}}
- {{$randomCatsImage}}
- {{$randomCityImage}}
- {{$randomFoodImage}}
- {{$randomNightlifeImage}}
- {{$randomFashionImage}}
- {{$randomPeopleImage}}
- {{$randomNatureImage}}
- {{$randomSportsImage}}
- {{$randomTechnicsImage}}
- {{$randomTransportImage}}
- {{$randomImageDataUri}}
- {{$randomEmail}}
- {{$randomExampleEmail}}
- {{$randomUserName}}
- {{$randomProtocol}}
- {{$randomUrl}}
- {{$randomDomainName}}
- {{$randomDomainSuffix}}
- {{$randomDomainWord}}
- {{$randomIP}}
- {{$randomIPV6}}
- {{$randomUserAgent}}
- {{$randomHexColor}}
- {{$randomMACAddress}}
- {{$randomPassword}}
- {{$randomLoremWord}}
- {{$randomLoremWords}}
- {{$randomLoremSentence}}
- {{$randomLoremSlug}}
- {{$randomLoremSentences}}
- {{$randomLoremParagraph}}
- {{$randomLoremParagraphs}}
- {{$randomLoremText}}
- {{$randomLoremLines}}
- {{$randomFirstName}}
- {{$randomLastName}}
- {{$randomFullName}}
- {{$randomJobTitle}}
- {{$randomNamePrefix}}
- {{$randomNameSuffix}}
- {{$randomNameTitle}}
- {{$randomJobDescriptor}}
- {{$randomJobArea}}
- {{$randomJobType}}
- {{$randomPhoneNumber}}
- {{$randomPhoneNumberFormat}}
- {{$randomPhoneFormats}}
- {{$randomArrayElement}}
- {{$randomObjectElement}}
- {{$randomUUID}}
- {{$randomBoolean}}
- {{$randomWord}}
- {{$randomWords}}
- {{$randomLocale}}
- {{$randomAlphaNumeric}}
- {{$randomFileName}}
- {{$randomCommonFileName}}
- {{$randomMimeType}}
- {{$randomCommonFileType}}
- {{$randomCommonFileExt}}
- {{$randomFileType}}
- {{$randomFileExt}}
- {{$randomDirectoryPath}}
- {{$randomFilePath}}
- {{$randomSemver}}
還是比較偏英文化,對于中文可能并不太友好,下面來演示一個(gè)使用示例:
在請求中使用上面這些變量

監(jiān)控發(fā)送的 HTTP 請求

從上圖中可以看到,我們使用到的隨機(jī)變量在發(fā)送請求的時(shí)候是已經(jīng)替換成具體的值的了
編寫測試用例
Scripts 介紹
postman 有一套基于 nodejs 的運(yùn)行時(shí),我們可以寫一些 scripts 來在請求發(fā)送之前做一些日志等,在得到響應(yīng)之后測試響應(yīng)是否與預(yù)期一致
postman 的 script 主要分成兩類,一類是 Pre-Request Scripts,在發(fā)送請求之前執(zhí)行,一類是 Tests,個(gè)人感覺可能叫 Post-Response Scripts 更好一些,因?yàn)槲覀儾粌H僅可以寫測試,也可以記錄日志,也可以設(shè)置變量等
上次我們說過了 postman 的測試推薦使用 Collection ,Collection 下可以分目錄也可以直接就是 request,目錄里也可以有具體的 api request,還可以有子目錄
Collection/Folder/Request 都可以定義自己的 Pre-Request Scripts 和 Tests,這些 Scripts 執(zhí)行順序如下:

上一級的測試作用于子級所有的請求,也就是說我們可以在 Collection 的 Test Scripts 中定義一個(gè)測試用例,這會對這個(gè) Collection 下的所有請求都有效,都會驗(yàn)證這個(gè)測試是否有效
如果想要實(shí)現(xiàn)測試用例的復(fù)用可以將類似的請求放在一個(gè)目錄下針對目錄寫測試用例,這樣這個(gè)目錄下的請求都會有這個(gè)測試用例
如果只是想針對某一個(gè)請求的測試,可以針對 request 來寫,只在對應(yīng) request 的 Test Scripts 中定義即可
Scripts 常用語法
Postman Console
postman 是基于 nodejs 的,你可以直接使用 console.log 來記錄一些日志,通過 postman console 來查看,在左上角的菜單 View 下有一個(gè) Show Postman Console

我們在請求的 Pre-Scripts 里輸出一條日志,然后發(fā)送請求

這里的 pm.variables.set("phone","") 是設(shè)置 phone 這一參數(shù)為空字符串,由下圖可以看出,phone 這一變量在發(fā)送請求的時(shí)候會被替換成空字符串

查看 postman console

可以看到我們在上面輸出的日志已經(jīng)輸出到 postman console 了
變量設(shè)置
postman 支持的變量分幾個(gè)層級,
- global
- environment
- collection
- data(數(shù)據(jù)文件中的變量值)
- local

變量優(yōu)化級:
上面的類型優(yōu)先級從低到高,“就近原則”

// Variables
// This function searches for the variable across globals and the active environment.
var value = pm.variables.get("variable_key"); // 這個(gè)方法會從上面所有的來源尋找對應(yīng)的變量,就近原則,優(yōu)先從最靠近自己的地方找
// Globals
// Set a global variable,設(shè)置一個(gè)全局變量
pm.globals.set("variable_key", "variable_value");
// Get a global variable,從全局變量中獲取某個(gè)變量的值
pm.globals.get("variable_key");
// Clear a global variable,取消設(shè)置全局變量,移除變量
pm.globals.unset("variable_key");
// Environments
// Setting an environment variable, 設(shè)置一個(gè)環(huán)境變量(注,這是postman 中的 <Environment> 環(huán)境變量,不同于系統(tǒng)環(huán)境變量)
pm.environment.set("variable_key", "variable_value");
// 你也可以序列化一個(gè)對象或數(shù)組放在變量中
// Setting a nested object as an environment variable
// var array = [1, 2, 3, 4];
// pm.environment.set("array", JSON.stringify(array, null, 2));
// var obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
// pm.environment.set("obj", JSON.stringify(obj));
// Getting an environment variable,從環(huán)境中獲取某個(gè)變量
var value = pm.environment.get("variable_key");
// If the value is a stringified JSON:
// These statements should be wrapped in a try-catch block if the data is coming from an unknown source.
var array = JSON.parse(pm.environment.get("array"));
var obj = JSON.parse(pm.environment.get("obj"));
// // Clear an environment variable, 從環(huán)境中移除某一個(gè)變量
// pm.environment.unset("variable_key");
// Collection
// Setting an collection variable,設(shè)置一個(gè) collection 變量
pm.collectionVariables.set("variable_key", "variableValue");
// Get a collection variable,從 collection 中獲取一個(gè)變量
var val = pm.collectionVariables.get("variable_key");
// Clear a collection variable,從 collection 中移除一個(gè)變量
pm.collectionVariables.unset("variable_key");
// local
pm.variables.set("variable_key", "variable_value");
pm.variables.get("variable_key");
使用變量,如 username => {{username}},使用兩層大括號來表示變量引用,比如上面的測試中的 phone
測試用例
postman 的測試用例也是分層級的,上面已經(jīng)做了簡單的介紹,postman 是基于 nodejs 的所以,在nodejs 里可以用的語法大多也都支持,比如 JSON.parse,這里主要介紹幾種常用的方法:
// 檢查 response 的 statusCode 是 200
pm.test("response is ok", function () {
pm.response.to.have.status(200);
});
// 檢查響應(yīng)是 200,并且有 body,body 是一個(gè) json
pm.test("response must be valid and has a json body", function () {
// assert that the status code is 200
pm.response.to.be.ok; // info, success, redirection, clientError, serverError, are other variants
// assert that the response has a valid JSON body
pm.response.to.be.withBody;
pm.response.to.be.json; // this assertion also checks if a body exists, so the above check is not needed
});
// 定義一個(gè)超時(shí)時(shí)間,檢查響應(yīng)時(shí)間是否超時(shí)
let responseTimeout = parseInt(pm.variables.get("responseTimeout"));
if(responseTimeout > 0){
pm.test(`Response time is less than ${responseTimeout}ms`, function () {
pm.expect(pm.response.responseTime).to.be.below(responseTimeout);
});
}
// Convert XML body to a JSON object,使用postman 內(nèi)置的 xml2Json 將 xml 轉(zhuǎn)換為 json 對象
var jsonObject = xml2Json(responseBody);
//Check for a JSON value
// 檢查 json 對象中某一個(gè)值是否符合預(yù)期
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
// 檢查數(shù)組是否為空
pm.test("Check if array is empty", function () {
expect([]).to.be.empty;
});
// 檢查字符串是否為空
pm.test("Check if string is empty", function () {
pm.expect('').to.be.empty;
});
運(yùn)行測試:


測試結(jié)果會顯示出多個(gè)測試通過,多少失敗的,哪些 assertion 失敗,你也可以看到具體的響應(yīng)信息
使用命令行測試
postman 提供了一個(gè) npm 包 newman,我們可以直接命令行運(yùn)行測試,也可以在自己的程序里集成 npm 包,在程序里運(yùn)行
npm install -g newman
使用導(dǎo)出 Collection, 導(dǎo)出之后是一個(gè) json 文件
newman run testCollection.json // 運(yùn)行 testCollection 測試
newman run testCollection.json -d testData.json // -d 指定數(shù)據(jù)文件
newman run testCollection.json -d testData.json -r json // -d 指定數(shù)據(jù)文件,-r 指定 report 類型,默認(rèn)是 `cli` 直接在命令行中輸出測試結(jié)果
newman run testCollection.json -r cli,json // -d 指定數(shù)據(jù)文件,-r 指定 report 類型,默認(rèn)是 `cli` 直接在命令行中輸出測試結(jié)果,可以指定多個(gè) reporter,json 會將運(yùn)行結(jié)果保存到 json 文件中
// collection 路徑不僅支持本地路徑,也支持 url
newman run https://www.getpostman.com/collections/631643-f695cab7-6878-eb55-7943-ad88e1ccfd65-JsLv
示例:

在自己的程序中使用 newman 運(yùn)行測試
const newman = require('newman'); // require newman in your project
// call newman.run to pass `options` object and wait for callback
newman.run({
collection: require('./sample-collection.json'),
reporters: 'cli'
}, function (err) {
if (err) { throw err; }
console.log('collection run complete!');
});
更多用法參考官方文檔:https://github.com/postmanlabs/newman#using-newman-cli