postman 小技巧
postman 使用这么久了,但是还是有一些好用的小功能被遗忘,这次就稍微整理一下吧。对于前端而言,它最大的功能莫过于接口调试或测试,这里也提到两个命令 curl 和 httpie,有兴趣的可以去看这篇文章 👈
变量
变量可以使我们在请求或脚本中存储和重复使用其值,通过将值保存在变量中,可以在集合,环境或请求中引用,也方便管理和修改。根据作用域层级主要可以分为:
- global - 全局
- collection - 集合
- environment - 环境
三者的优先级反之,谁影响的范围最小,谁优先级最高,即本地变量 > 环境变量 > 集合变量 > 全局变量
- initial value - 当你分享该集合或环境变量时,对方拿到的值
- current value - 本地的值,不会被同步。可以点击 persist 按钮同步到 initial value
还有两种为 data 和 local,这里不做介绍
postman 存储变量时会使用字符串,所以如果是对象或数组,可以先使用
JSON.stringify()
序列化,使用的时候JSON.parse()
解析即可
设置变量
设置变量有好多种方式,可以点击到页面中相应位置进行编辑,也可以直接在需要设置的变量上右键:
还可以通过脚本来创建:
// global
pm.globals.set('key', 'value');
// collection
pm.collectionVariables.set('key', 'value');
// environment 注意是仅限于当前的环境
pm.environment.set('key', 'value');
// local - 本地变量优先级最高,可覆盖其他变量。一般只做临时覆盖其他变量来作测试
pm.variables.set('key', 'value');
// 同样也可以删除某个变量
pm.environment.unset('key');
获取变量
获取变量可以使用双大括号的插值表达式,在输入的时候默认会有联想:
定义好的变量也可以在脚本中直接使用,还有一些以 $ 开头的内置的动态变量,详细的列表可以参考这里 👈:
- {{$guid}} - A v4 style guid
- {{$timestamp}} - The current timestamp (Unix timestamp in seconds)
- {{$randomInt}} - A random integer between 0 and 1000
// global
pm.globals.get('key');
// 获取动态变量的值,需要使用 replaceIn 方法
pm.variables.replaceIn('\{\{$randomFirstName}}') // Julian
使用场景
请求前置脚本
前置脚本其实就是在 Pre-requests Script
中编写的 JS 脚本,当一个请求在发送之前,会先去执行前置脚本中的代码,因此有几个场景很适用,比如登录接口的密码,在发送前需要做加密处理,那么就可以在前置脚本中做加密处理;再比如说,有的接口的输入参数有一些随机数,每请求一次接口参数值都会发送变化,就可以在前置脚本中编写生成随机数的代码。总体来说,就是在请求接口之前对我们的请求数据进行进一步加工处理的都可以使用前置脚本这个功能。
比如下图,在请求 posts 时可以带上 id 参数,如果 id 是随机数的话,则可以在请求前先保存到变量中,然后请求的时候再从变量中去获取该值:
接口关联
有一个场景就是其中一个接口需要另一个接口的数据作为输入参数,那么这两个接口即有关联,我们需要做的就是先保存第一个接口的相关数据,然后在下一个接口中去获取该变量。比如需要根据游客 token 去获取认证 token:
// 在第一个获取游客 token 的接口的 Tests 测试中,将有效信息保存到 touristToken 集合变量中
const { info = '' } = pm.response.json()
pm.collectionVariables.set('touristToken', info)
接着我们在第二个获取认证 token 的接口的请求头中添加该参数: token: {{touristToken}},之后我们还可以将该 Tests 测试中将获取到的认证的 token 同步到全局变量中:
const { info: { member: { token = '' } = {} } = {} } = pm.response.json()
pm.globals.set('token', token)
快捷功能
新增请求的三个方法
正常情况下,我们添加一个请求需要打开一个窗口,选择请求方法,地址,以及相对应的参数,或者我们也可以复制已存在的接口然后进行修改。但是如果请求过多,难免会觉得添加起来麻烦,那么就需要用到导入功能,它可以导入相关的请求。比较常用的是如下这三种,入口都在左上角的 import
按钮,分别是:
- 从抓包工具中导入请求
- 从浏览器中导入请求
- 导入其他 postman 分享的请求数据 - 分享后可以生成一个链接,复制后直接粘贴到
Link
即可
以浏览器导入为例,直接在当前请求中右键选择 copy 出 curl 的数据包,然后粘贴到 postman 里的 Raw Text
即可:
反之,我们也可以利用 code
功能去生成对应语言的客户端代,比如 curl 或 httpie 等:
请求头信息预设
一般情况下我们做接口调试的话,很多接口请求头都差不多,为了方便添加公共参数,我们可以在 headers tab 下设置请求头预设信息,方便一次性添加预设的所有请求头,具体位置为 Presets --> Manage Presets
,在设置完预设名称保存后,则可以在 Presets 下拉框中看到所命名的选项,单击就可以快速添加请求头啦:
继承集合认证
如果需要处理登陆认证的情况,如果不用 Authorization
功能其实也能解决认证的问题,无非就是把要认证的数据按照要求在指定位置传入参数即可。即把登录后返回的 token 要在每个请求接口的 headers 中传入 。这时就需要在每个 headers 中都填写一个认证参数传入,但是这样做的话太过繁琐,如果使用认证(Authorization)功能的话,就会大大简化了我们的认证过程。
首先我们还是在预设脚本的标签中去请求登陆接口,获取到认证 token 后可以设置到集合变量中;然后切换到 Authorization
标签中设置获取 token,使其 token 在集合中有效;集合中每个请求的 Authorization
标签保持默认的 inherit auth from parent
即可。这样该集合下的所有请求都会自动获取到这个 token,也就省略了我们对每个 token 进行处理了:
// 发送 json 请求
const PostJsonRequest = {
url: 'http://test.itheima.net/api/sys/login',
method: 'POST',
header: 'Content-Type:application/json',
body: {
mode: 'raw',
raw: JSON.stringify({ 'mobile': '13110001002', 'password':'123456' })
}
// body: { // 表单数据
// mode: 'x-www-form-urlencoded',
// raw: 'username=13088888888&password=123456&verify_code=8888'
// }
};
pm.sendRequest(PostJsonRequest, function (err, res) {
console.log(err ? err : res.json());
});
快速查找和替换
有时候我们常会遇到这样一种问题,系统中有太多的用例,环境变量和系统变量的值也太多,查找其中的某个值太不方便;或者有的值想要修改,但苦于修改的地方太多,修改起来太费劲。那么,针对这样的困扰,是否有办法解决呢?答案是有的,那就是快速查询与批量替换,该功能位于左下角。搜索的内容还可以使用正则表达式,比如 ^\d{7}$
搜索出 7 位的数字等等,也可以限定搜索范围:
接口测试
编写和运行测试脚本
在 postman 中,我们可以针对接口来做自动化测试,位置即为 Tests
标签。测试的结果将会在下面的 Test Results
标签展示出来:
我们可以看到,其实输入框右边给出了很多代码片段,我们直接点击代码片段就可以直接生成相应的代码,比如点击 Response time is less than 200ms
,则会自动添加:
pm.test("Response time is less than 200ms", function () {
pm.expect(pm.response.responseTime).to.be.below(200);
});
// Response body: Contains string
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});
// Response body : JSON value check
pm.test("Your test name", function () {
var jsonData = pm.response.json(); // 获取响应数据
pm.expect(jsonData.code).to.eql(1000);
});
如果要学习更多关于编写测试脚本的知识,可以移步官网 👈
相较于请求前置脚本,这里的脚本执行时间为响应体数据返回之后,从下图就可以看到他们执行的优先级:
所以如果我们要对集合中所有请求来做统一测试的话,则可以把脚本写在集合中,这样子集合下每个请求执行的时候,都会去执行集合中的测试。我们还可以统一用 Collection Runner
来跑一次集合里的所有测试,并且可以很直观的看出哪些有问题:
newman 生成测试报告
newman 其实就是命令行的 Collection Runner
,它可以很方便地集成到你的系统服务当中。主要有下面两种使用方式:
# 1. 在 postman 中导出结果 json 文件
newman run examples/sample-collection.json
# 2. 在 postman 中获取该集合的分享链接
newman run https://www.getpostman.com/collections/631643-f695cab7-6878-eb55-7943-ad88e1ccfd65-JsLv
当然也可以当作 node 的模块引入到文件中:
const newman = require('newman');
// 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!');
});
newman 的 options 参数解析可以直接参考文档:
- -e - 可选,指定一个 URL 或者 postman 的环境变量脚本文件。如果集合中指定了环境变量,则需要添加这个参数
- -g - 可选,指定一个 URL 或者 postman的全局变量脚本文件,如果集合中指定了全局变量,则需要加这个参数
- -r - 可选,指定测试报告的类型,如果想生成对应的报告类型,需要添加这个参数,典型的有 html、json、cli,若不添加,默认为 cli
- -d - 可选,指定一个数据参数化文件,如果有参数化文件,需要添加这个选项
- –reporter-html-export - 可选,指定生成报告的路径和文件名,如果不添加该参数,默认会生成一个 newman 的文件夹,里面存放着生成的测试报告。需要安装插件 newman-reporter-html
# 其中 [] 内的参数是可选的。
newman run collect_a.json [-e environment_b.json] [-r html] [--reporter-html-export report.html]
→ Status Code Test
GET https://echo.getpostman.com/status/404 [404 Not Found, 534B, 1551ms]
1\. response code is 200
┌─────────────────────────┬──────────┬──────────┐
│ │ executed │ failed │
├─────────────────────────┼──────────┼──────────┤
│ iterations │ 1 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ requests │ 1 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ test-scripts │ 1 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ prerequest-scripts │ 0 │ 0 │
├─────────────────────────┼──────────┼──────────┤
│ assertions │ 1 │ 1 │
├─────────────────────────┴──────────┴──────────┤
│ total run duration: 1917ms │
├───────────────────────────────────────────────┤
│ total data received: 14B (approx) │
├───────────────────────────────────────────────┤
│ average response time: 1411ms │
└───────────────────────────────────────────────┘
# failure detail
1\. AssertionFai… response code is 200
at assertion:1 in test-script
inside "Status Code Test" of "Example Collection with
Failing Tests"
有个插件 newman-reporter-htmlextra 可以生成更美观的仪表盘形式的报表:
# -r 指定的测试报告类型为 htmlextra
newman run collect_a.json -r htmlextra --reporter-html-export report.html
mock 数据
创建 mock 服务
倘若后端接口若不能准时提供给前端人员,则可以通过 postman mock 来进行数据模拟。那么第一步就是创建 mock 服务,可以直接在左上角 New --> Mock Server
或者集合面板里 Mocks
,跟着步骤走,最终结果都会在 mock 标签中生成一个 mock 服务器的链接,即下图的 Mock assignments
:
创建 example
接下来模拟的时候需要用到 example
功能,详情可以参考官方文档,我们以一个请求为例:
我们直接在 example 下拉框就可以切换到已经建好的栗子上。在填写完成了 example 里的信息并保存后,我们就可以新建个请求,把请求地址改为 mock 服务器地址 + 请求路径
:
https://<mock-id>.mock.pstmn.io/<request-path>
<!-- 栗子 -->
https://3589dfde-f398-45cd-88eb-b0fa0192fc3f.mock.pstmn.io/matches
当你再次发送请求时,便会根据你的请求路径返回一个你所编写的符合条件的 mock 数据。当然我们还可以创建多个 example,只需要在 example 里改下各自的请求路径就行,然后在做 mock 请求的时候,想要数据返回哪种状态,就只要把请求路径改成对应 example 的路径即可:
If there is no exact match found, Postman will return the best matching response based on its algorithm.
另外,在 mock response 数据里,我们也可以添加一些上面讲过的动态变量:
{
"name": "\{\{$randomFullName}}",
"userName": "\{\{$randomUserName}}",
"location": "\{\{$randomCity}}",
"company": "\{\{$randomCompanyName}}",
"jobTitle": "\{\{$randomJobTitle}}",
"updatedAt": "\{\{$timestamp}}"
}
连接数据库
xmysql
这里其实不是真正意义上的直连,而是通过接口访问和修改数据库表里面的内容。这里以 mysql 为例,假设数据库 RUNOOB 有这样一张表 animation:
id | title | author | publishDate |
---|---|---|---|
1 | 罪恶王冠 | 小明 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
2 | 进击的巨人 | 小李 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
3 | 未闻花名 | 小马 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
4 | 双斩少女 | 小鹅 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
5 | 境界的彼方 | 小静 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
6 | 宝石王国 | 小包 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
7 | 刀语 | 小红 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
8 | 鬼灭之刃 | 小蓝 | Fri Jan 15 2021 00:00:00 GMT+0800 (China Standard Time) |
9 | overload | 小白 | Sat Jul 07 2018 00:00:00 GMT+0800 (China Standard Time) |
接下来我们需要借助一个工具 xmysql,通过 xmysql 连库后,xmysql 会将数据库中所有表以 REST 风格的接口形式生成,所以后续访问某张表其实就是访问的某个接口,那么对于 postman 而言,其实也就是相当于访问了某个接口而已。xmysql 命令参数介绍:
- -h - 连接数据库主机名
- -u - 连接数据库用户名
- -p - 连接数据库密码
- -d - 连接数据库名
- -r - 连接数据库输入的主机名,无这个选项默认为 localhost
- -n - 连接这个服务设置的端口,无这个选项默认为 3000
xmysql -u username -p password -d databasename
我们需要做的就是先启动本地的 mysql 服务,然后通过 xmysql 来连接并自动生成 restful apis:
# 开启本地 mysql 服务,注意这里是 macOS 的命令
# mysql.server stop 关闭服务
# mysql.server restart 重启服务
mysql.server start
# 账号登陆
mysql -u root -p
# Enter password
# ------ link start -------
# 通过 xmysql 连接
xmysql -h localhost -u root -p MyNewPass -d RUNOOB
Generating REST APIs at the speed of your thought..
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Database : RUNOOB
Number of Tables : 1
REST APIs Generated : 28
Xmysql took : 0 seconds
API's base URL : localhost:3000
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
我们可以看到通过 xmysql 连接后,暴露出 3000 端口,我们直接 http :3000
测试以下,就可以看到可以打印出所有生成的 api 列表。接下来我们可以在 postman 添加该请求,参照文档 API Overview 我们就可以对表里面的内容进行增删查改:
# GET localhost:3000/api/animation
# GET localhost:3000/api/animation?_where=(author,eq,小红)
我们可以通过 POST 请求来新增一条数据,或是通过 PUT 请求来修改,DELETE 请求来删除等等:
执行上述 POST 请求后,我们刷新下表数据,则会发现新增了一行:
id | title | author | publishDate |
---|---|---|---|
10 | 小象佩奇 | 小智 | Fri Jan 01 2021 00:00:00 GMT+0800 (China Standard Time) |
Monitor 监控
postman 的监控,和 Jenkins 中设置的定时任务差不多,用于监控接口的运行情况和性能。同样的这个功能用于集合。你可以配置多长时间运行一次,到了时间点将自动遍历集合中的每个请求。那么很明显通过这个功能,真正地帮我们实现了自动化。创建监视器的方法仍然是通过 New
或者集合面板的 Monitors
来创建。在这之后,我们便可以定期的在 postman 或者邮件中接收到监控总结:
经过一段时间,最终我们在 web 端看到的效果就是:
其他问题
Date 类型参数
有些请求参数可能涉及到 Date 日期类型,我们直接按以下这种格式写就行了:
2021/1/15 19:34:00
参考链接
1.一文带你全面解析 postman 工具的使用 By 雨滴测试