Postman是一款非常流行的支持HTTP/HTTPS协议的接口调试与测试工具,其功能非常强大,易用。
1 基础知识
1.1 下载与安装
Postman的安装步骤,本例以Windows为例,如下所示:
- 1、访问官网,下载Postman,官网地址如下所示:
- 2、进入到主页面后,下载适合自己的操作系统的版本,如下所示:
直接下载Postman的地址:Download Postman | Get Started for Free
-
3、双击下载之后的安装包,进入安装界面,按安装向导完成即可。
-
4、点击桌面快捷方式,注册、登录或者直接使用即可,跳过登录直接使用如下所示:
这里推荐注册,在注册并登录后,Postman会将相应的数据上传至远程服务器,后面在其他地方登录后,可以自动同步之前的数据。
1.2 界面导航说明
初次使用Postman可能对界面上一些菜单、导航不太熟悉,可查看下图的说明。
1.3 第一个示例
Postman发送请求非常简章,我们以最简单的GET请求为例,操作步骤如下所示:
- 1.打开Postman,点击左边Collections,再点击右边的+,新建一个Collections;
- 2.在上一步新建的Collection上右键选择Rename输入新名字,按Enter键即可。
- 3、在Postman填写好相应的内容,点击Send即可:
请求方法:选择GET
请求地址中输入:http://httpbin.org/get
Params中输入参数zq和lyl
以下输入如下图所示:
2 基础功能
2.1 常见HTTP接口类型
在HTTP中常见的接口主要有以下几种类型
- 带查询参数的接口
- 表单类型的接口
2.1.1 带查询参数的接口
带查询参数的接口通常为GET方法,在URL地址中通过?进行分隔,多个参数使用&进行连接,常见表现形式为param=value。示例如下所示:
http://httpbin.org/get?zq=diana&lyl=surpass
以上为GET方法请求的完整URL地址,可拆分为如下所示:
- URL地址:http://httpbin.org/get
- 参数有两个:zq和lyl,其对应的值分别为diana和surpass
2.1.2 表单类型的接口
表单类型的接口通常为POST方法,常见的提交数据方式有以下几种方式:
- application/x-www-form-urlencoded
- multipart/form-data
- application/json
- text/xml
2.1.2.1 application/x-www-form-urlencoded
这是最常见的POST提交数据的方式。在POST提交数据中Content-Type被指定为application/x-www-form-urlencoded,提交的数据按照 key1=value1&key2=value2 的方式进行编码,其中key和value都会进行URL转码
2.1.2.2 multipart/form-data
这是另外一个常见的POST提交数据的方式。一般这种方式用于上传文件
2.1.2.3 application/json
application/json这是目前用得最多的数据提交方式,做为请求时,用来告诉服务器数据是序列化化的JSON数据。
2.1.2.4 text/xml
text/xml是一种使用HTTP作为传输协议,XML作为编码方式的远程调用规范,它的使用也很广泛,能很好的支持已有的 XML-RPC 服务。不过,XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便
2.1.3 Postman实现示例
2.1.3.1 带查询参数的接口
可参考前面的第一个示例,结果如下所示:
2.1.3.2 application/x-www-form-urlencoded
操作步骤如下所示:
- 1.新建一个请求
- 2.请求方法为POST
- 3.输入请求地址:
http://httpbin.org/post
- 4.切换至Body,编码类型选择x-www-form-urlencoded
- 5.填写相应的参数
username:diana
password:surpass
code:loveyou
- 6.点击Send
2.1.3.3 multipart/form-data
multipart/form-data一般常用于上传文件,比如更新用户头像、License授权等,操作步骤如下所示:
- 1.新建一个请求
- 2.请求方法为POST
- 3.输入请求地址:
http://httpbin.org/post
- 4.切换至Body,编码类型选择form-data
- 5.在key中填入参数file,移动鼠标至其他地方
- 6、再次移动鼠标至参数file后面,设置参数类型为File
- 7.在value点击Select Files
- 8.点击Send
上传文件中的key(该示例为file)需要根据实际接口地址进行替换,该例仅为演示
2.1.3.4 application/json
这是接口最常见一种的数据类型,操作步骤如下所示:
- 1.新建一个请求
- 2.请求方法为POST
- 3.输入请求地址:
http://httpbin.org/post
- 4.切换至Headers,输入Conten-Type
- 5.切换至Body,编码类型选择raw,输入以下数据
{
"username": "diana",
"password": "surpass",
"code": "loveyou"
}
- 6.点击Send
2.1.3.5 text/xml
- 1.新建一个请求
- 2.请求方法为POST
- 3.输入请求地址:
http://httpbin.org/post
- 4.切换至Headers,输入Conten-Type
- 5.切换至Body,编码类型选择raw,输入以下数据
<?xml version="1.0" encoding="UTF-8" ?>
<userinfo>
<username>diana</username>
<password>surpass</password>
<code>loveyo</code>
</userinfo>
- 6.点击Send
2.2 接口响应数据解析
响应数据是在发送请求后经过服务器处理后返回的结果,通过由三部分组成,分别是状态行、响应头、响应体。在Postman的展示如下所示:
在Postman中的响应数据中,对接口测试的主要参考如下所示:
- Body和Status是重点,可以用来验证响应数据和响应状态码
- Test Result用来我们编写的断言执行结果
- Time和Size可用作性能测试的简单判断条件
Body的显示主题,常用的是Pretty、Raw、Preview
- Pretty:直译是美化,如果选中该标签,则意味着返回的数据Postman会自动进行格式化处理,使数据看起来更加美观。若返回的数据是json格式,则格式化为json再进行展示
- Raw:即返回的数据,不做任何美化处理,直接显示最原始的数据。
- Priview:直译为预览,一般常用于返回为HTML的响应中,可以直接显示为网页形式,示例如下所示:
2.3 接口管理
2.3.1 接口管理功能
当我们对一个或多个系统中的接口用例进行维护时,需要进行分类管理,方便后期维护或批量做回归测试。在Postman提供该功能为Collections,通过Collections可以实现以下功能:
- 用例分类管理
- 批量回归测试用例
假设一个系统按模块划分有以下几个模块和接口,如下所示:
--用户模块
|--用户新增接口
|--用户删除接口
|--用户修改密码接口
|--用户查询接口
--订单模块
|--订单管理
|--订单查询接口
|--订单删除接口
|--订单跟踪
|--订单物流信息查询
我们按以上结构进行创建Collections,操作步骤如下所示:
- 1.点击左边Collection选项卡,再点击+,如下所示:
- 2.在创建的Collections右键,在弹出的菜单中选择Rename,输入新的名称CollectionSample即可
- 3.创建子模块,在CollectionSample右键,在弹出的菜单中选择Add Folder,再次在刚新创建的子模块中右键,在弹出的菜单中选择Rename,输入新的名称用户模块即可,如下所示:
- 4.创建请求,在子模块用户模块右键,在弹出的菜单中选择Add Request,再次在刚新创建的请求右键,在弹出的菜单中选择Rename,输入新的名称用户模块即可,如下所示:
- 5.重复上面步骤,依次创建各模块和相应的接口请求,最终效果如下所示:
2.3.2 批量执行接口
有一些时间,想单独执行系统中某一模块的全部接口用例,该如何操作呢?Postman提供了批量执行接口用例的功能,对应于Run,操作步骤如下所示:
- 1.选中一个需要批量执行的Collections,在菜单中选择Run,如下所示:
- 2.在弹出的窗口中勾选需要运行的接口用例,并设置对应的参数,点击Run CollectionSample即可
Iterations:代表需要执行的次数
Delay:在执行完一个接口后的休眠时间
Data:从文件中读取并替换参数化变量
- 3.在等待运行完成,可以查看相应的结果
All Tests:所有运行的测试接口用例
Passed:断言通过的接口用例
Failed:断言失败的接口用例
2.3.3 日志调试
在接口测试时,会因为代码有问题导致报错,这时则可以利用Postman的日志调试功能实现快速定位问题。
在Postman中编写日志打印的语句是使用JavaScript,可以在Pre-request Script和Tests中编写。
在Postman中默认Console是隐藏的可以通过以下两种方式开启
- 菜单栏View->Show Postman Console
- 点击左下角的Console
搜索日志:输入URL或日志关键字即可搜索出对应的请求和日志记录
日志级别:可以按日志级别进行快速查询,日志级别有:All logs、Log、Info、Warning、Error
查看原始日志:提供格式化后的请求日志和原生日志,可以进行切换
Show timestamps:是否显示时间戳
Hides network:隐藏接口请求,仅显示日志
2.3.4 断言
如果没有断言,就需要人工去判断返回的结果是否正确,而有了断言之后,就为接口自动化提供一个基础条件,相应Postman也提供对应的断言功能,在Postman中的断言有以下几个特点:
- 断言编写位置:Tests选项卡
- 断言编写语言:JavaScript
- 断言执行顺序:在响应数据返回后执行
- 断言结果查看:Test Results
JavaScript如果不会怎么办?Postman非常贴心的提供了一些常用的内置断言,从右侧点击对应的断言,就可以在左边Tests标签中生成断言代码片断。
常用断言代码,按响应又可以分为状态码、响应头、响应体
- 断言状态码:Status code: code is 200
pm.test("Status code is 200", function () {
// 响应的状态码为200
pm.response.to.have.status(200);
});
- 断言状态消息:Status code:code name has string
pm.test("Status code name has string", function () {
// 响应的状态消息包含的字符OK
pm.response.to.have.status("OK");
});
- 成功的POST请求状态码:Successful POST request
pm.test("Successful POST request", function () {
pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]);
});
- 断言响应头中包含:Response headers:Content-Type header check
pm.test("Content-Type is present", function () {
//断言响应头存在Content-Type
pm.response.to.have.header("Content-Type");
});
- 断言响应体中包含字符串:Response body:Contains string
pm.test("Body matches string", function () {
// 响应数据中包含字符串loveyou
pm.expect(pm.response.text()).to.include("loveyou");
});
- 断言响应体等于字符串:Response body : is equal to a string
pm.test("Body is correct", function () {
// 响应数据等于字符串loveyou
pm.response.to.have.body("loveyou");
});
- 断言响应体(json)中某个键名对应的值:Response body : JSON value check
响应的数据如下所示:
{
"args": {},
"data": "",
"files": {},
"form": {
"code": "loveyou",
"password": "surpass",
"username": "diana"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Cache-Control": "no-cache",
"Content-Length": "392",
"Content-Type": "multipart/form-data; boundary=--------------------------885313293587233892669712",
"Host": "httpbin.org",
"Postman-Token": "9d61a0e9-d938-4263-90fb-b2acb696e700",
"User-Agent": "PostmanRuntime/7.28.4",
"X-Amzn-Trace-Id": "Root=1-6159c71c-65ecce4342403def289304d9"
},
"json": null,
"origin": "183.192.232.183",
"url": "http://httpbin.org/post"
}
断言代码如下所示:
pm.test("Your test name", function () {
// 获取响应Json数据
var jsonData = pm.response.json();
// 获取jsonData键名为form的子键名为username的值为diana,然后再与期望的值进行对比
pm.expect(jsonData.form.username).to.eql("diana");
});
- 响应时间:Response time is less than 1000ms
pm.test("Response time is less than 1000ms", function () {
pm.expect(pm.response.responseTime).to.be.below(1000);
});
一般用于简单的性能测试参考指标
2.3.5 变量
变量可以脚本中存储和重复使用,通过设置变量,可以在集合、环境或请求中引用。在Postman中常用的变量有以下全局变量、环境变量、集合变量。
- 全局变量:一旦申明,则全局有效,即在Postman中的任何集合中都可以使用该变量,作用域最大
- 环境变量:要申明环境变量,先要创建环境,然后在该环境中创建变量。如果要想使用环境变量,必须先导入这个环境,这样才可以使用这个环境下的变量了。环境可以创建多个,每个环境下又可以有多个变量。
- 集合变量:集合变量是针对集合的,即申明的变量只能用于某个集合,使用范围也仅限于该集合之内。
以上三种变量的范围从大到小依次为全局变量 > 集合变量 > 环境变量,如果要想使用变量,则需要进行两步操作定义变量 、访问变量
2.3.5.1 定义变量
定义全局变量和环境变量,点击Postman右上角眼睛图标,在弹出的界面就可以根据需要定义全局变量和环境变量。
- 定义全局变量
操作步骤如下所示:
1.点击Postman右上角眼睛图标
2.在弹出的界面中,点击Globals后面的Add
3.在上面第2步弹出的界面填写全局变量名称及其相应的值,最后点击Save,保存全局变量
以上操作步骤如下所示:
- 定义环境变量
操作步骤如下所示:
1.在Postman左侧点击Environments,再点击左上角+
2.在弹出的界面中输入环境名称,并添加对应的环境变量
3.点击Save,保存环境变量
以上操作步骤如下所示:
- 查看全局变量和环境变量
操作步骤如下所示:
1.在右侧点击下拉列表列表,选择其中一个环境
2.点击Postman右上角眼睛图标,即可查看对应环境变量和全局变量
以上操作步骤如下所示:
- 定义集合变量
操作步骤如下所示:
1.在Postman左侧点击Collections,选择任意一个Collection
2.在弹出的右侧中,选择Variable选项卡
3.填写相应的集合变量信息即可
以上操作步骤如下所示:
- 代码定义变量
除了以上三种方式定义变量,也可以在Tests和Pre-requests Script中进行定义
定义全局变量:pm.globals.set("变量名",变量值)
定义环境变量:pm.environment.set("变量名",变量值)
定义集合变量:pm.collectionVariables.set("变量名",变量值)
示例如下所示:
- 其他定义变量
定义变量除了以上几种方式,还有另外一种方式。这种方式定义变量在不同的位置,编写也有所不同,通过可以在URL、Params、Authorization、Headers和Body中定义,其操作步骤如下所示:
1.在URL、Params、Authorization、Headers和Body创建一个空的变量名
2.在以上位置把要创建变量的值右键选择Set:环境|全局
3.选择其中一个变量名即可
以上操作步骤如下所示:
2.3.5.2 获取变量
在定义好变量就可以获取并使用变量了。在不同的位置获取变量,编写的规则也不尽相同,需要注意一下:
- 如果是在请求参数中获取变量(URL、Params、Authorization、Headers和Body),无论是全局变量、环境变量,还是集合变量,获取的方式都是如下的规则:
{{变量名}}
- 如果变量位于Tests和Pre-requests Script,则获取不同类型的变量,编写的代码有所区别,如下所示:
获取全局变量:pm.globals.get("变量名")
获取环境变量:pm.environment.get("变量名")
获取集合变量:pm.collectionVariables.get("变量名")
以上示例如下所示:
变量的使用地方非常多,如接口关联等,请求前置脚本中会使用到变量等。
2.3.6 前置脚本
前置脚本其实就是在Pre-requests Script中编写的JavaScript脚本。
2.3.6.1 执行顺序
在请求发送之前,会先执行Pre-requests Script中的代码
2.3.6.2 使用场景
一般常用在发送请求前,需要对接口数据做进一步处理。如调用一个接口前,需要获取到使用的cookie等。
前置脚本主要用于在发送请求之前,需要对发送的接口数据做进一步处理都可以使用前置脚本功能
2.3.6.2 实战示例
我们以一个登录接口为示例,该接口基本信息如下所示:
- 请求的登录接口地址,有一个参数是需要获取当前系统时间
- 接口地址:http://httpbin.org/post
- 接口参数如下所示:
实现步骤如下所示:
- 1.在前置脚本中编写获取系统时间戳的代码,如下所示:
var timestamp=Date.parse(new Date())/1000
- 2.将该值保存为环境变量,如下所示:
pm.environment.set("timestamp",timestamp)
- 3、获取变量的值并传递给参数timestamp
以下详细操作结果如下所示:
2.4 接口关联
2.4.1 接口关联定义
在日常测试过程,经常会碰到这种情况。接口A返回的数据需要做为接口B的请求参数(即接口A的输出参数做为接口B的输入参数),我们称这种情况为 接口关联
2.4.2 接口关联实现思路
我们抛开Postman来整理下通用思路,如下所示:
- 1、获取上一个接口的返回数据
- 2、将返回的数据保存一个变量
- 3、在下一个接口发送请求前,获取变量的值
在Postman中如何实现呢?我们可以参考通用思路整理成以下的方式:
- 1、发送请求并获取到上一个接口的返回数据
- 2、将返回的数据保存为全局或环境变量
- 3、在下一个接口发送请求前,获取全局或环境变量的值
2.4.3 接口关联实践示例
示例相应的接口说明如下所示:
- 1.接口A实现登录示例,其返回数据中会有一个参数timestamp参数
- 2.接口B实现发送请求前,需要获取接口A返回数据中的timestamp值,做为本身的请求参数
接口A的返回数据如下所示:
{
"args": {},
"data": "",
"files": {},
"form": {
"password": "surpass",
"timestamp": "1633851549",
"username": "diana"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Cache-Control": "no-cache",
"Content-Length": "52",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"Postman-Token": "0247d754-25a1-4775-9673-348ce30678a1",
"User-Agent": "PostmanRuntime/7.28.4",
"X-Amzn-Trace-Id": "Root=1-6162989d-329af5e75ae151953220e30d"
},
"json": null,
"origin": "183.192.236.236",
"url": "http://httpbin.org/post"
}
最终实现步骤如下所示:
- 1.获取接口A的返回数据并保存为环境变量
- 2、在接口B中获取环境/全局变量的值
2.5 返回数据获取
在做接口测试,返回数据比较多的一般为JSON格式,可能存在多层嵌套,所以对返回的JSON进行取值也不全一样,我们来看看在Postman里面如何获取,在Postman中获取JSON数据的格式通常如下所示:
-
单层结构: .key
-
多层嵌套:.key.key
-
多层嵌套带数组:.key[index]
-
请求数据如下所示:
{
"personInfo": [
{
"nickName": "Surpass",
"realName": "lyl"
},
{
"nickName": "Diana",
"realName": "zq"
}
],
"location": "sh"
}
- 接口返回数据如下所示:
{
"args": {},
"data": "{\r\n \"personInfo\":[\r\n {\"nickName\":\"Surpass\",\"realName\":\"lyl\"},\r\n {\"nickName\":\"Diana\",\"realName\":\"zq\"}\r\n ],\r\n \"location\":\"sh\"\r\n}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Cache-Control": "no-cache",
"Content-Length": "149",
"Content-Type": "application/json",
"Host": "httpbin.org",
"Postman-Token": "6bbae7e9-3ef5-4f52-8737-fc4dcd80cf8f",
"User-Agent": "PostmanRuntime/7.28.4",
"X-Amzn-Trace-Id": "Root=1-6162a8bf-0e14645445d34fe042ea136b"
},
"json": {
"location": "sh",
"personInfo": [
{
"nickName": "Surpass",
"realName": "lyl"
},
{
"nickName": "Diana",
"realName": "zq"
}
]
},
"origin": "183.192.236.236",
"url": "http://httpbin.org/post"
}
1.单层结构
获取返回数据中origin值,代码如下所示:
// 1.获取请求返回的数据
var returnJsonData=pm.response.json()
console.log("Retuen json data is:",returnJsonData)
// 2.获取对应变量的值
var returnDataValue=returnJsonData.origin
console.log("Retuen json data value is:",returnDataValue)
2.多层嵌套
获取返回数据中json中location值,代码如下所示:
// 1.获取请求返回的数据
var returnJsonData=pm.response.json()
console.log("Retuen json data is:",returnJsonData)
// 2.获取对应变量的值
var returnDataValue=returnJsonData.json.location
console.log("Retuen json data value is:",returnDataValue)
3.多层嵌套带数组
获取返回数据中json中personInfo第二个值,代码如下所示:
// 1.获取请求返回的数据
var returnJsonData=pm.response.json()
console.log("Retuen json data is:",returnJsonData)
// 2.获取对应变量的值
var returnDataValue=returnJsonData.json.personInfo[1]
console.log("Retuen json data value is:",returnDataValue)