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.com
schema格式的约束文件,值得推荐的地方就是对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"]
}
开放Apihellosean1025.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
检查5XXpm.response.to.be.error
检查4XX或5XXpm.response.to.be.ok
状态码必须为200pm.response.to.be.accepted
状态码必须为202pm.response.to.be.badRequest
状态码必须为400pm.response.to.be.unauthorized
状态码必须为401pm.response.to.be.forbidden
状态码403pm.response.to.be.notFound
检查响应的状态码为404pm.response.to.be.rateLimited
检查响应状态码是否为429
json格式校验并显示错误_使用postman做自动化接口校验相关推荐
- excel切片器显示错误_带切片器的Excel弹出选择器工具
excel切片器显示错误 Slicers make it easy to select from a list of items, but they take up valuable space on ...
- jsr303jsp页面怎么显示错误信息_springmvc使用JSR-303进行数据校验实例
项目中,通常使用较多的是前端的校验,比如页面中js校验以及form表单使用bootstrap校验.然而对于安全要求较高点建议在服务端进行校验. 服务端校验: 控制层controller:校验页面请求的 ...
- excel切片器显示错误_使用切片器在Excel中设置过滤条件
excel切片器显示错误 In most cases, it's best if you keep people away from your data in Excel. It's too easy ...
- hive 非正确json格式字段造成查询错误
1. 问题 hive查询报错: Diagnostic Messages for this Task: [2020-04-02 05:32:04,360] {bash_operator.py:110} ...
- app开发历程————Android程序解析服务器端的JSON格式数据,显示在界面上
上一篇文章写的是服务器端利用Servlet 返回JSON字符串,本文主要是利用android客户端访问服务器端链接,解析JSON格式数据,放到相应的位置上. 首先,android程序的布局文件main ...
- json schema如何约束为小数_如何使用jsonschema进行接口响应断言
一,JSONSchema的概念 JSONSchema是一种用来描述JSON数据的一种JSON数据结构.JSON Schema也有版本,目前的版本有 Draft 7,Draft 6,Draft 4 和D ...
- c语言实现http服务器_基于postman实现http接口测试过程解析_服务器其它
这篇文章主要介绍了基于postman实现http接口测试过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 无意中发现了一个巨牛的人工智能教程, ...
- php使mysql显示错误_如何针对依赖用户输入的长查询在PHP中显示MySQL错误?
在PHP中,我试图执行一个长的MySQL查询,该查询取决于用户输入.但是,我的查询失败,并显示以下消息, "Query Failed". 实际上,每当查询失败时,我都会打印此消息, ...
- 使用pygal.maps.world库读取JSON格式文件,显示世界人口地图图示
import json import pygal.maps.world #引入世界地图 from pygal_maps_world.i18n import COUNTRIES #引入世界个国家def ...
最新文章
- 使用C++实现Socket编程传输协议文件(包括大文件)
- 当你看到曾经自己的代码时...
- JZOJ 5400. 【NOIP2017提高A组模拟10.7】Repulsed
- HTTP状态码415 springboot项目
- 如何连接Linux上的服务器 网络编程,Linux 网络编程 一
- aspxgridview的取值
- asp.net core 系列 10 配置configuration (上)
- SIFT算法论文:译文、详解
- 小企业主代理记账基础知识
- yasm,nasm的关系
- python中plot函数参数_Python的 plot函数和绘图参数设置
- 相信我,这些web前端技术会让你虎躯一震
- 汽车内饰胶市场现状及未来发展趋势
- day06三级缓存 二次采样
- gcc 编译参数 -fPIC 的详解和一些问题
- 本机php环境搭建教程:windows环境下wampserver的配置教程——超级详细
- python多个strip_python 中strip方法
- 第二节 数据CRUD操作与连接查询和子查询(包含练习)
- MySQL数据库——MySQL创建视图(CREATE VIEW)
- 小组取什么名字好_好消息!这座天桥今年年底完工!取什么名字,等你出主意...
热门文章
- 分享到系统面板_win7电脑没有nvidia控制面板怎么办【解决方法】
- bom_clear.php,thinkphp清除BOM方法
- VRP网络操作系统简介
- 详细介绍 Qt Creator 快捷捷应用
- linux centos7.2 nodeJs全局安装
- [react] 举例说明如何在React创建一个事件
- 重学java基础第二十三课:java基础 注释
- Taro+react开发(45)taro中组件生命周期
- react学习(42)----react中的jsx表达对象
- 前端学习(3037):vue+element今日头条管理-把数据放到本地存储