json格式校验并显示错误_使用postman做自动化接口校验
要想實現接口的自動化測試,需要以下幾個步驟:
自動登錄
首先點擊postman左上角的new按鈕,創建一個collection,在pre-request-scripts標簽下,給整個collection創建一個公用規則
編寫登錄腳本
pre-request-scripts在請求發送前執行的腳本,在整個集合期間只會執行一次;
在集合變量(參考上圖)中添加對應的用戶名和密碼
//獲取集合 const { host, username, password } = pm.collectionVariables.toObject();使用pm.sendRequest方法發送一個ajax請求,將請求成功的結果的token值存到環境變量中。
const data = res.json(); pm.environment.set("token", data.data["X-Access-Token"]);完整代碼如下:
const {// host,yapiToken,yapiHost,variable_key,token,catid,CooperationPlatformId } = pm.variables.toObject();const { host, username, password } = pm.collectionVariables.toObject(); const echoPostRequest = {url: `${host}/api/login`,method: 'POST',header: 'Content-Type: application/json;charset=UTF-8',body: {mode: 'raw',raw: JSON.stringify({ username, password})} }; //使用pm.sendRequest方法發送一個ajax請求, if(!token){pm.sendRequest(echoPostRequest, function (err, res) {console.log(err ? err : res.json());const data = res.json();pm.environment.set("token", data.data["X-Access-Token"]); }); }yapi,去哪網出的開源的可視化接口管理平臺,推薦部署到公司服務器,也可以直接使用官方的。
YApi-高效、易用、功能強大的可視化接口管理平臺?yapi.demo.qunar.comschema格式的約束文件,值得推薦的地方就是對mockjs語法支持的很好。
{"type": "object","title": "empty object","properties": {"data": {"type": "object","properties": {"name": {"type": "string","mock": {"mock": "@string"}}},"required": ["name"]},"code": {"type": "string","mock": {"mock": "@natural"}},"msg": {"type": "string","mock": {"mock": "@string"}}},"required": ["data","code","msg"] }開放Api?hellosean1025.github.io獲取接口的schema文件
yapi的開發api很方便的獲取接口相關的信息。
//生成分類下接口列表的map對象 const genCatInterfaceListMap = function (catid) {return new Promise(function (resolve, reject) {const url = `${yapiHost}/api/interface/list_cat?token=${yapiToken}&catid=${catid}&limit=100`;pm.sendRequest(url, function(err, res){if(err){console.log("err: ", err)}else{var data = res.json();var list = data.data.list;var catInterfaceListMap = list.reduce((acc, item) => {var key = item.path.slice(1).split("/").join("_");acc[key] = item._id;return acc;}, {})resolve(catInterfaceListMap);}})}); };獲取指定分類下的接口列表,并存到集合變量中。
genCatInterfaceListMap(catid).then((newMap) => {let catInterfaceListMap = pm.collectionVariables.get("catInterfaceListMap") || {};pm.collectionVariables.set("catInterfaceListMap", Object.assign({}, catInterfaceListMap, newMap)); });genCatInterfaceListMap(CooperationPlatformId).then((newMap) => {let catInterfaceListMap = pm.collectionVariables.get("catInterfaceListMap") || {};pm.collectionVariables.set("catInterfaceListMap", Object.assign({}, catInterfaceListMap, newMap)); })關鍵環節來了從yapi獲取接口的schema,并驗證格式
//驗證數據格式測試用例。 pm.test("數據格式正確", () => {var valid = validate(pm.response.json());if(!valid){console.log("validate.errors", validate)validate.errors.forEach(function(item){console.log(item.dataPath, ":", item.message);})}pm.expect(valid).to.be.true })使用avj來做校驗;
var Ajv = require('ajv'); var ajv = new Ajv(); // options can be passed, e.g. {allErrors: true} var validate = ajv.compile(schema); var valid = validate(data); if (!valid) console.log(validate.errors);完整代碼
在collection的Tests tab下,編寫下面代碼
//從yapi 服務上獲取到了對應的schema,檢驗接口返回值是否匹配schema var Ajv = require("ajv"); var ajv = new Ajv({logger: console, allErrors: true}); const { path } = pm.request.url; const yapiToken = pm.variables.get("yapiToken") const pathKey = path.slice(-3).join("_"); const catid293 = pm.variables.get("catid293"); const interfaceId = catid293[pathKey];console.log("path:Test", pathKey, catid293, interfaceId); const url = `http://yapi.ops.tst-weiboyi.com/api/interface/get?token=${yapiToken}&id=${interfaceId}`;//從yapi接口中獲取當前接口的schema pm.sendRequest(url, function(err, res){if(err){console.log("err: ", err)}else{var data = res.json();var schema = JSON.parse(data.data.res_body);delete schema["$schema"];var validate = ajv.compile(schema);pm.test("數據格式正確", () => {var valid = validate(pm.response.json());if(!valid){console.log("validate.errors", validate)validate.errors.forEach(function(item){console.log(item.dataPath, ":", item.message);})}pm.expect(valid).to.be.true}) } })輸出錯誤信息
還有其他方法和參數,默認validate.errors雖然是個數組,但里面默認只包含了第一條錯誤。具體能否輸出所有不匹配字段,還待研究?
補充:
//allErrors 默認為false,只能顯示一條信息 var ajv = new Ajv({logger: console, allErrors: true}); 編寫測試入門-帶有示例?documenter.getpostman.com使用變量作為請求參數
(function(){const data = pm.response.json();const list = data.data.list;//獲取滿足指定操作條件的idconst okIds = list.filter(item => item.type == 1).map(item => item.id);const passIds = list.filter(item => item.type == 2).map(item => item.id);const [ okId ] = okIds;const [ passId ] = passIdspm.collectionVariables.set("customId", okId);pm.collectionVariables.set("passId", passId); })()可以在下個請求中使用上個請求存儲的變量
{"type":"2", "remark":"1111", "id": {{okId}} }在body里面獲取變量注意事項
pm.collectionVariables.set("ids", [1,2,3]); //在body里面需要這樣寫 {"ids":{{ids}} }自動化批量測試
查看格式報錯
在postman的控制臺,可以顯示所有格式錯誤的log
其他的集合測試用例
在編輯集合的彈窗里面,Tests標簽下,可以編寫公共測試用例,集合下的每個請求都會執行
pm.test("Status code is 200", function () {pm.response.to.have.status(200); });pm.test('狀態碼為1000', () => {var d = pm.response.json();pm.expect(d.code).to.equal("1000") })pm.test("Response time is less than 200ms", function () {pm.expect(pm.response.responseTime).to.be.below(200); });//清除全局變量 pm.globals.unset("variable_key");pm.test("Content-Type is present", function () {pm.response.to.have.header("Content-Type"); });編寫單個請求的測試用例
在每個請求的Tests標簽下,可以編寫腳本,這個是請求成功后執行的代碼
//獲取變量 const aId = pm.collectionVariables.get("accountId");console.log("aId", aId) //編寫測試用例 pm.test(`上架成功, id: ${aId}`, () => {//將返回值轉換為json對象var d = pm.response.json();//驗證返回值的code值是否是1000pm.expect(d.code).to.equal("1000") })相關文檔
pm.expect語法相關文檔 chaijs BDD(想弄明白,就仔細看一遍這個文檔)
BDD
The BDD styles are expect and should. Both use the same chainable language to construct assertions, but they differ in the way an assertion is initially constructed. Check out the Style Guide for a comparison.
API Reference
Language Chains
The following are provided as chainable getters to improve the readability of your assertions.Chains
- to
- be
- been
- is
- that
- which
- and
- has
- have
- with
- at
- of
- same
- but
- does
- still
.not
Negates all assertions that follow in the chain.
expect(function () {}).to.not.throw(); expect({a: 1}).to.not.have.property('b'); expect([1, 2]).to.be.an('array').that.does.not.include(3);以下是文檔相關內容,postman-sanbox-api-reference;(pm對象的相關屬性)
在postman的沙箱內有幾個作用域
優先順序是Iteration Data<Environment<Collection<Global。四個作用域分別對應下面四個變量。
pm.variables,在 pre-request scripts中pm.variables.set("path", "/api/xxx"),在Test中可以通過pm.variables.get("path")獲取到
pm.variables
pm.variables: 閱讀有關VariableScope的更多信息
在Postman中,所有變量都符合特定的層次結構。當前迭代中定義的所有變量優先于當前環境中定義的變量,當前環境中的變量將覆蓋全局范圍中定義的變量。優先順序是Iteration Data< Environment< Collection< Global。
- pm.variables.has(variableName:String):function → Boolean:檢查當前作用域中是否存在局部變量。
- pm.variables.get(variableName:String):function → *:獲取具有指定名稱的局部變量的值。
- pm.variables.toObject():function → Object:返回包含本地范圍內所有變量的對象。
- pm.variables.set(variableName:String, variableValue:String"):function → void:使用給定值設置局部變量。
還可通過pm.environment環境范圍和pm.globals全局范圍訪問在各個范圍中定義的變量。
pm.environment
pm.environment: 閱讀有關VariableScope的更多信息
- pm.environment.name:String:包含當前環境的名稱。
- pm.environment.has(variableName:String):function → Boolean:檢查環境是否具有具有給定名稱的變量。
- pm.environment.get(variableName:String):function → *:獲取具有給定名稱的環境變量。
- pm.environment.set(variableName:String, variableValue:String):function:使用給定的名稱和值設置環境變量。
- pm.environment.unset(variableName:String):function:刪除具有指定名稱的環境變量。
- pm.environment.clear():function:清除所有當前環境變量。
- pm.environment.toObject():function → Object:以單個對象的形式返回所有環境變量。
pm.collectionVariables
pm.collectionVariables: 閱讀有關VariableScope的更多信息
- pm.collectionVariables.has(variableName:String):function → Boolean:檢查是否存在具有給定名稱的集合變量。
- pm.collectionVariables.get(variableName:String):function → *:返回具有給定名稱的collection變量的值。
- pm.collectionVariables.set(variableName:String, variableValue:String):function:設置具有給定值的集合變量。
- pm.collectionVariables.unset(variableName:String):function:清除指定的集合變量。
- pm.collectionVariables.clear():function:清除所有集合變量。
- pm.collectionVariables.toObject():function → Object:以對象的形式返回變量及其值的列表。
pm.globals
pm.globals: 閱讀有關VariableScope的更多信息
- pm.globals.has(variableName:String):function → Boolean:檢查是否存在具有給定名稱的全局變量。
- pm.globals.get(variableName:String):function → *:返回具有給定名稱的全局變量的值。
- pm.globals.set(variableName:String, variableValue:String):function:設置具有給定值的全局變量。
- pm.globals.unset(variableName:String):function:清除指定的全局變量。
- pm.globals.clear():function:清除所有全局變量。
- pm.globals.toObject():function → Object:以對象的形式返回變量及其值的列表。
pm.request
pm.request: 閱讀有關VariableScope的更多信息
request內部的對象pm表示正在為此腳本運行的請求。對于請求前腳本,這是將要發送的請求,在測試腳本中時,這是已發送請求的表示。
request 包含以以下結構存儲的信息:
- pm.request.url:Url:包含發出請求的URL。
- pm.request.headers:HeaderList:包含當前請求的標頭列表。
- pm.request.headers.add(headerName:String):function:為當前請求添加具有指定名稱的標頭。
- pm.request.headers.delete(headerName:String):function:刪除具有當前請求的指定名稱的標頭。
- pm.request.headers.upsert({ key: headerName:String, value: headerValue:String}):function):插入給定當前請求的標題列表的標題名稱和標題值(如果標題不存在,否則將已存在的標題更新為新值)。
pm.response
pm.response: 閱讀有關響應的更多信息
在測試腳本中,該pm.response對象包含與收到的響應有關的所有信息。
響應詳細信息以以下格式存儲:
- pm.response.code:Number
- pm.response.reason():Function → String
- pm.response.headers:HeaderList
- pm.response.responseTime:Number
- pm.response.text():Function → String
- pm.response.json():Function → Object
pm.iterationData
pm.iterationData: 閱讀有關VariableScope的更多信息
該iterationData對象包含在收集運行期間提供的數據文件中的數據。
- pm.iterationData.get(variableName:String):function → *:從迭代數據中返回具有指定名稱的變量。
- pm.iterationData.toObject():function → Object:將迭代數據作為對象返回。
- pm.iterationData.addLayer(list: VariableList):function → void:將變量列表添加到迭代數據。
- pm.iterationData.clear():function → void:清除所有數據。
- pm.iterationData.has(variableName: string):function → boolean:檢查迭代數據中是否存在具有指定名稱的變量。
- pm.iterationData.set(key: string, value: any, type: string):function → void:設置變量,為其指定值和類型。
- pm.iterationData.syncVariablesFrom(object: {[key: string]: VariableDefinition}, track?: boolean, prune?: boolean):function → Object | Undefined:從具有指定名稱的對象獲取變量。
- pm.iterationData.syncVariablesTo(object?: {[key: string]: VariableDefinition}):function → Object:將變量保存到具有指定名稱的對象。
- pm.iterationData.toJSON():function → *:將迭代數據對象轉換為JSON格式。
- pm.iterationData.unset(key: string):function → void:取消分配給指定變量的值。
- pm.iterationData.variables():function → Object:從erationData對象返回所有變量。
- static pm.iterationData.isVariableScope(object: any):function → boolean:檢查特定變量是否在范圍內。
pm.cookies
pm.cookies: 閱讀有關CookieList的更多信息
該cookies對象包含與請求域相關聯的cookie列表。
- pm.cookies.has(cookieName:String):Function → Boolean
檢查請求的域是否存在特定的cookie(以其名稱尋址)。 - pm.cookies.get(cookieName:String):Function → String
獲取特定cookie的值。 - pm.cookies.toObject:Function → Object
以對象的形式獲取所有cookie及其值的副本。返回的cookie是為請求的域和路徑定義的cookie。
pm.cookies.jar
- pm.cookies.jar():Function → Object
訪問Cookie罐對象。 - jar.set(URL:String, cookie name:String, cookie value:String, callback(error, cookie)):Function → Object
使用Cookie名稱和值設置Cookie。也可以通過在此函數中將cookie值與cookie名稱相關聯來直接設置cookie。 - jar.set(URL:String, { name:String, value:String, httpOnly:Bool }, callback(error, cookie)):Function → Object
使用PostmanCookie或其兼容對象設置cookie。 - jar.get(URL:String, token:String, callback (error, value)):Function → Object
從Cookie罐獲取Cookie。 - jar.getAll(URL:String, callback (error, cookies)):Function → Object
從cookie罐中獲取所有cookie。 - jar.unset(URL:String, token:String, callback(error)):Function → Object
取消設置Cookie。 - jar.clear(URL:String, callback (error)):Function → Object
清除餅干罐中的所有餅干。
pm.test
pm.test(testName:String, specFunction:Function):Function
您可以使用此功能在Pre-request Script或Tests沙箱中編寫測試規范。在此函數中編寫測試可以使您準確地命名測試,并且即使該函數內部存在錯誤,該函數也可以確保腳本的其余部分不會被阻塞。
在下面的示例測試中,我們正在檢查關于響應的所有內容對我們來說都是有效的。
pm.test("response should be okay to process", function () {pm.response.to.not.be.error;pm.response.to.have.jsonBody('');pm.response.to.not.have.jsonBody('error');});done可以將 可選的回調添加到中pm.test,以測試異步功能。
pm.test('async test', function (done) {setTimeout(() => {pm.expect(pm.response.code).to.equal(200);done();}, 1500);});- pm.test.index():Function → Number
從特定位置獲取總數測試。
期望值
pm.expect(assertion:*):Function → Assertion
pm.expect是一個通用的斷言函數。這是ChaiJS期望的BDD庫的基礎。使用該庫,可以很容易地編寫語法易讀的測試。
此功能對于處理來自response或的數據斷言很有用variables。有關使用的斷言測試示例pm.expect,請查看斷言庫示例
測試腳本中可用的響應聲明API
- pm.response.to.have.status(code:Number)
- pm.response.to.have.status(reason:String)
- pm.response.to.have.header(key:String)
- pm.response.to.have.header(key:String, optionalValue:String)
- pm.response.to.have.body()
- pm.response.to.have.body(optionalValue:String)
- pm.response.to.have.body(optionalValue:RegExp)
- pm.response.to.have.jsonBody()
- pm.response.to.have.jsonBody(optionalExpectEqual:Object)
- pm.response.to.have.jsonBody(optionalExpectPath:String)
- pm.response.to.have.jsonBody(optionalExpectPath:String, optionalValue:*)
- pm.response.to.have.jsonSchema(schema:Object)
- pm.response.to.have.jsonSchema(schema:Object, ajvOptions:Object)
pm.to.be. *
通過pm.response.to.be對象內部的屬性,您可以輕松地聲明一組預定義規則。
- pm.response.to.be.info
檢查1XX狀態碼 - pm.response.to.be.success
檢查2XX狀態碼 - pm.response.to.be.redirection
檢查3XX狀態碼 - pm.response.to.be.clientError
檢查4XX狀態碼 - pm.response.to.be.serverError
檢查5XX - pm.response.to.be.error
檢查4XX或5XX - pm.response.to.be.ok
狀態碼必須為200 - pm.response.to.be.accepted
狀態碼必須為202 - pm.response.to.be.badRequest
狀態碼必須為400 - pm.response.to.be.unauthorized
狀態碼必須為401 - pm.response.to.be.forbidden
狀態碼403 - pm.response.to.be.notFound
檢查響應的狀態碼為404 - pm.response.to.be.rateLimited
檢查響應狀態碼是否為429
總結
以上是生活随笔為你收集整理的json格式校验并显示错误_使用postman做自动化接口校验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最佳75个安全工具介绍及其下载地址
- 下一篇: 机器学习算法总结--K近邻