postman入门到精通
一、postman下载安装与更换主题
1、下载与安装
下载地址:https://www.postman.com/downloads/
下载适合自己的版本
下载后图标
2、更换主题(Themes)
打开后页面:
更换主题:选择自己喜欢的明色或者暗色系
二、页面详解
1、顶部工具栏
- 搜索
- 同步数据(Sync)
- 【invite】邀请加入团队
- 抓取API请求
- 【Sign In】登录
- 【Runner】运行用例
2、左侧栏
- 【New】新建
- 【import】导入
- 【Collections】集合:用来管理用例
3、中部栏
3.1 请求部分页签介绍
接口来源于聚合数据,点击此处查看
- 请求方式
- 接口地址
- send: 发送请求
- Params:get请求传参
注:Bulk Edit 批量编辑
- Authorization:认证鉴权
- Headers:请求头 注:如使用post请求方式,请求头(Headers)要加入content-type参数
- Body:post请求传参
1、none:没有参数
2、form-data:传文件和键值对
注:Content-Type与请求参数的格式之间的关联
当选择某一参数方式后,postman会自动帮我们设置对应的Content-Type,不需要自行设置,而如果是使用jmeter还是需要自行设置Content-Type。
所以,当选择form-data的参数方式后,postman会自动的帮我们设置了Content-Type:multipart/form-data
3、x-www-form-urlencoded :传键值对
当选择x-www-form-urlencoded的参数方式后,postman会自动的帮我们设置了Content-Type:application/x-www-form-urlencoded
4、raw:可以上传任意格式的文本,可以上传text、json、xml等
当我们选择了text时,postman同样帮我们自动设置了Content-Type:text/plain,可自行查看Headers
当我们选择了JSON时,postman同样帮我们自动设置了Content-Type:application/json,可自行查看Headers
当我们选择了XML时,postman同样帮我们自动设置了Content-Type:text/xml,可自行查看Headers
5、binary:只可以上传二进制数据,通常用来上传文件,一次只能上传一个文件
6、GraphQL:发送GraphQL查询
- Scripts
Pre-request :预请求脚本
Post-response:请求后置脚本/请求后的脚本处理/断言
- Setting:设置
- Cookies:Postman的cookie的管理器
3.2 响应部分页签介绍
Body:响应的数据(Pretty:json格式,Raw:文本格式,Preview:网页格式)
Cookies:缓存
Headers:响应头
Test Results:断言的结果
Status:200返回码
OK:返回信息
Time:响应时间 588ms(毫秒)
Size:2.7KB
三、管理用例
四、设置环境变量和全局变量
全局变量:就是在所有接口请求里面都可以访问的变量
环境变量:就是全局变量。(开发环境,测试环境,线上环境)
1、添加环境变量
例如:
开发环境:ip:略
测试环境:ip:略
生产环境:ip:http://apis.juhe.cn/fapig/football/query
引用方式为:{{变量名}}
在运行时:选择相应的环境变量
2、添加全局变量
步骤同环境变量,不再赘述
五、发送请求
1、发送一个get请求
接口文档:
根据接口文档,我们可以看到,请求方式为get或post,这里使用get方法,填写url并把参数填写到Params中,点击Send后成功发送请求
2、发送一个post请求
接口文档:
六、接口关联
场景:下一个接口的参数是使用的上一个接口的返回值
接口示例:用的是聚合数据的接口,可自行申请
脚本输入位置
1、JSON提取器(响应body中提取)
//javascript脚本,var定义变量// 将响应body里的内容解析为一个json对象(字典),存到变量res中var res=pm.response.json();//提取响应body中的date值存到全局变量date中
pm.globals.set("date", res.result.matchs[0].date);
执行后,可以看到全局变量中存上了变量date和它的值
获取全局变量:{{变量名}},如其它接口把date作为入参只需要:{{date}}
接口示例:
2、正则表达式提取器(响应body中提取)
var dateone = pm.response.text().match(newRegExp('"date":"(.*?)"'));
console.log(dateone[1]);
pm.globals.set("dateone", dateone[1]);
执行后,也可以看到全局变量中存上了变量dateone和它的值
3、从响应头中去提取
响应头示例:
// 获取响应头中参数Etag的值var Etag=pm.response.headers.get("Etag")// 在控制台输出
console.log(Etag)
控制台可以看到,成功获取Etag的值
4、从响应Cookie中去提取
响应Cookie示例
//响应Cookie中提取var aliyungf_tc=pm.cookies.get("aliyungf_tc")// 在控制台输出
console.log(aliyungf_tc)
控制台可以看到,成功获取aliyungf_tc的值
七、postman动态参数
接口测试中常常会出现接口的参数不能写死,必须使用随机数来实现。
1、内置动态参数
{{$timestamp}} 时间戳
{{$randomInt}} 随机的0-1000的整数
{{$guid}} 随机的很长的字符串
2、自定义动态参数
//自定义的时间戳var times = Date.now();
pm.globals.set("times",times);//让接口请求停留3秒(3秒灌水机制),time.sleep(3)constsleep=(milliseconds)=>{const start = Date.now();while(Date.now()<= start + milliseconds){}};sleep(3000);
八、postman断言
八种断言方式
1、断言返回码为200 用于状态断言
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
示例:
2、断言返回的结果中包含一个指定的字符串 用于业务断言
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});
3、检查返回结果的json字符串的值 用于业务断言
pm.test("Your test name", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
4、断言返回的结果等于一个字符串 用于业务断言
pm.test("Body is correct", function () {
pm.response.to.have.body("response_body_string");
});
5、断言响应头中包含有指定的响应头
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");
});
6、断言请求接口的时间小于200ms 用于性能断言
pm.test("Response time is less than 200ms", function () {
pm.expect(pm.response.responseTime).to.be.below(200);
});
7、断言一个post请求的返回的状态码是否在指定的范围中
pm.test("Successful POST request", function () {
pm.expect(pm.response.code).to.be.oneOf([201, 202]);
});
8、断言返回的状态码信息中包含指定的字符串
pm.test("Status code name has string", function () {
pm.response.to.have.status("Created");
});
每个接口写2个断言,一个状态断言一个业务断言
特别注意:
1.postman内置的动态参数无法做断言。所以必须使用自定义的动态参数。
2.在tests里面不能使用{{}}的方法取全局变量,必须使用以下方式:
pm.globals.get(“times1”)
globals[‘times1’]
globals.times1
九、Postman+newman+jenkins实现自动生成报告并持续集成
1、安装
1.1、安装Node.js
下载地址:https://nodejs.org/en/ 双击安装
验证:打开cmd,输入node
1.2、.安装npm
打开cmd输入:npm install --location=global --production windows-build-tools
验证: 打开cmd,输入npm -v
1.3、.安装newman
打开cmd输入:npm install --location=global newman
验证:打开cmd,输入newman -v
2、导出postman的测试用例,环境变量,全局变量
newman run “e:\yongli.json” -e “e:\huanjing.json” -g “e:\quanju.json” -r
cli,html,json,junit --reporter-html-export “e:\report.html”
-e 环境变量
-g 全局变量
-r cli,html,json,junit --reporter-html-export 测试报告输出的路径
3、和jenkins持续集成
1.构建:执行window批处理命令
2.构建后:Publish HTML Report
十、接口鉴权(鉴定是否有访问接口的权限)
1、cookie,session,token鉴权
1.1、cookie鉴权
cookie它是服务器产生的,保存在浏览器,主要是因为http协议无连接,无状态。
cookie通过键值对的方式来保存记录。
原理:第1次访问服务器的时候,那么服务器就会产生cookie并且在响应头的set-cookie里面发送给浏览器,浏览器保存,在第2-N次请求时会带上cookie信息。
cookie一般包括信息:name,value,domain,path,expries,size。
会话级cookie和持久化cookie
缓存并不等于cookie。
1.2、session鉴权
session它是服务器产生的,保存在服务器的内存。它可以通过cookie来传参sessionid。
原理:当你登录的时候,那么服务器会生成session,它通过cookie把sessionid传给客户端,然后在后面所有的请求里面都会自动的带上sessionid。然后和服务器的内存中的ssioniid对比以判断是否是同一个客户端。保存在服务器的内存里面的ssession的失效时间为30分钟。
在apache-tomcat-8.5.43\conf\web.xml文件里面的session-timeout可以修改默认的失效的时间。
sessionid可以隐藏域,也可以url或者是cookie传递。
1.3、token鉴权
token是服务器的产生的,保存在服务器的文件或数据库(硬盘),一般情况下接口测试通过一个专门的获取token的接口或者是登录接口来获取token,获取后每次请求其他接口都必须带上token鉴权。
面试题:cookie,session,token的相同点和不同点?
相同点:
都是在服务器产生的,都是用于鉴权。只是保存在不同的地方。
不同点:
cookie保存在客户端,所以不安全,一般情况下用cookie保存一些非重要的数据,而通过session去保存一些重要的数
据,session是保存在服务器的内存当中,而token是独立的鉴权,它和sesion和cookie无关。
2、Postman的鉴权方式。
bearer token鉴权:就是发送一个鉴权码(令牌)。
basic Auth鉴权:通过用户名和密码实现鉴权。
十一、接口Mock Sersver
mock测试就是测试过程中,对于一些不容易创建或者是不容易获取的比较复杂的对象,用一个模拟的对象去代替。
mock一把是为了解决单元之间的耦合依赖关系。(桩服务)
比如:工作中前后端分离,前端已经开发好了,但是后端的接口没有开发好。
项目之间的对接。(开发电子商务,支付宝支付。)
postman中使用mock sever
创建mock
创建成功后,环境变量中增加了查询奖品的变量
同时,请求中也新增了查询奖品的接口
十二、接口的加解密
接口加密:接口测试当中把传输的数据加密成密文(0101011101100)再传输。
接口解密:获取密文后把密文还原成原始数据。
1.目前市面上的加密方式
对称式加密(私钥加密):DES,AES,Base64
非对称式加密(双钥加密):RSA(公钥《公开》和私钥《保密》)
只加密不解密:MD5,SHA1,SHA3…(常用)
http://www.bejson.com
Postman实现解密接口(可遇不可求,除非自定义。)
十三、、接口签名sign(接口鉴权的一种)
BATJ,金融项目,银行项目等。
1.什么是接口签名?
接口签名就是使用appid,appsecret,nonce(流水号),timestamp,以及其它的各种参数按照一定的规则(ASCII排序)组成用来识别你的账号有没有访问api接口的权限的字符串,组成之后再进行加密,这个经过加密之后的字符串就是sign签名。
appid和appsecret在线下针对不同的接口调用方提供的。
流水号nonce,订单号一般是一串10位以上的随机一组数字或者随机的一组字符串。数字+字符串(guid)。
timestamp时间戳,一般10分钟之内有效。
2、为什么要做接口签名?(大大提高接口的安全性)
(1)防止接口鉴权码泄漏,接口被伪装攻击,(签名,只需要提供签名不需要鉴权码)
(2) 防止接口数据被篡改,(原理:签名针对的是所有的请求数据,只要有一个数字别改动了,那么sign就变了。就会请
求失败。)
(3)防止接口被重复提交,nonce是唯一的。并且只有10分钟之内有效。
3、接口签名的规则有很多,每个公司都不一样,但是大同小异(90%以上相似)。
举例:
(1)获取到所有的参数包括params和body,把所有的参数的key按照ascii码升序排列。
{a:2,c:1,b:3}改成{a:2,b:3,c:1,}
(2)把参数按照key=value的方式组合,多个参数用&分开。
a=2&b=3&c=1
(3)用申请到的appid和appsecret拼接到参数的最前面
appid=123&appsecret=456&a=2&b=3&c=1
(4)把订单号和时间戳拼接到参数的最后面
appid=123&appsecret=456&a=2&b=3&c=1&nonce=12121313×tamp=235235235
(5)把上述字符串通过MD5加密。加密之后大写。形成sign
sign=WEO987979798DDFGF767FDG
(6)然后把sign放到url或者请求头(一般用这种)或请求体里面发送给服务器做鉴权
//接口签名//1.获取到asppid和appsecretvar appid ="test";var appsecret ="123";
console.log(appid);
console.log(appsecret);//2.获得nonce流水号var nonce =getnonce(1000000000,9999999999);
console.log(nonce);//3.获得时间戳var timestamp =newDate().getTime();
console.log("timestamp="+timestamp)//4.获取到params里面的参数var params_args = pm.request.url.query.members;
console.log("params_args="+params_args);//5.获取到body里面的参数(JSON.parse加载成对象,JSON.stringify加载成字符串)var body_args = request.data;
console.log("body_args="+JSON.stringify(body_args));//6.把params和body的参数组合成一个变量for(var i=0;i<params_args.length;i++){
body_args[params_args[i].key]= params_args[i].value;}
console.log("body_args2="+JSON.stringify(body_args));//7.把组合的数据按照key升序
body_args =objectsort(body_args)
console.log("body_args3="+JSON.stringify(body_args));//8.把字典格式的参数转换成key=value&key=value的格式var new_string ="";for(var key in body_args){
new_string += key +"="+ body_args[key]+"&";}
console.log("new_string="+JSON.stringify(new_string));//9.在字符串的前面加上aooid和appsecret,在字符串的后面加nonce,timestamp.
new_string ="appid="+appid+"&"+"appsecret="+appsecret+"&"+new_string+"nonce="+nonce+"&"+"timestamp="+timestamp;
console.log(new_string);//10.对上述字符做MD5加密后并大写形成sign签名,然后把sign保存为全局变量var sign = CryptoJS.MD5(new_string).toString().toUpperCase();
console.log("sign="+sign);
pm.globals.set("sign",sign);//------------------------------------------------------//获得任意长度的随机数字functiongetnonce(min,max){return Math.floor(Math.random()*(max - min +1))+ min;}//把对象的key升序排序函数(此方法固定)functionobjectsort(obj){var new_key = Object.keys(obj).sort();
console.log(new_key);var arr ={};for(var i=0;i<new_key.length;i++){
arr[new_key[i]]= obj[new_key[i]];}return arr;}
版权归原作者 zhoukeguai 所有, 如有侵权,请联系我们删除。