postman使用进阶

一、说明

分享目的

  • 开发需要测试
  • 测试不测接口
  • 有的同事只会简单的发请求,对脚本相关不熟悉或者没用过
  • 其他工具类: go cli 暂时用不着,而且一看就会,感觉浪费时间
  • 当前阶段可用,提升效率

二、基础(跳过)

新建请求 新建集合 新建目录 导入文件 ...

三、进阶

概述

Postman 有一个基于 Node.js 的强大运行时,可以向请求和集合添加动态行为。 因此可以在编写 API 测试、构建中包含动态参数的请求、在请求之间传递数据等。 代码在流程中的两个事件期间执行:

  1. 在将请求发送到服务器之前,作为 Pre-request Script 选项卡下的 pre-request 脚本。
  2. 收到响应后,作为测试选项卡下的测试脚本。

脚本的执行顺序:

  1. 与请求关联的预请求脚本将在发送请求之前执行。
  2. 与请求关联的测试脚本将在请求发送后执行。

图解执行过程:

优先级说明

文字描述(重点)

pre-request script - > request -> response -> tests collections > folders > requests

过程示例

脚本示例

场景描述 Pre-request script: 登录(拿token)-获取用户信息(拿用量)->比对用量数据判断是否可以继续上传

Pre-request:
let endpoint=pm.globals.get("rec_dev")

// 登录
{
let login_url=endpoint+"/authentications"

// body 参数
let user_info={
    "password":"xxx",
    "email":"xxx@qq.com",
    "type":1,
    "brand_id":"xx",
    "app_id":"xx",
    "language":"zh"
}

// 请求参数
let login_request = {
  url: login_url,
  method: 'POST',
  header:'Content-Type:application/json',
  body: {
    mode: 'raw',
    raw: JSON.stringify(user_info)
  }
};

// 发送请求
pm.sendRequest(login_request, function (err, response) {
    if (err){
        console.log(response.json());
    }else{
        let param_resp=response.json();
        if (param_resp.status==200){
        // 重点 统一覆盖为最新token
            pm.request.headers.add({
                key: 'Authorization', 
                value: 'Bearer '+param_resp.data.api_token})
        }else{
            console.log(param_resp.message);
        }
    }
});
}

Request&Response:
Request:{{rec_dev}}/users/41638056
Response:
{
    "status": 200,
    "message": "success",
    "data": {
        "user_info": {
            "user_id": 41638056,
            "telephone": "",
            "nickname": "1369499226",
            "email": "1369499226@qq.com",
            "avatar_url": "",
            "region": "CN"
        },
        "member_info": {
            "type": 1,
            "license_type": "",
            "expired_at": 1661910465,
            "vip_type": 1
        },
        "quota": {
            "storage": {
                "limit": 53687091200,
                "used": 11743911
            },
            "traffic": {
                "limit": 0,
                "used": 0
            },
            "quantity": {
                "limit": 10000,
                "used": 2
            }
        },
        "extra": "Windows ApowerRec"
    }
}

Tests

pm.test('是否可继续上传',function(){

    // 断言响应码
    pm.expect(pm.response.code).to.eq(200);

    // 获取响应数据
    let resp = pm.response.json()

    // 断言业务逻辑
    pm.expect(resp.status).to.eq(200)
    let resp_data = resp.data;
    pm.expect(resp_data.quota.storage.limit).to.lt(resp_data.quota.storage.used)
})

TestResult

常用脚本

断言

pm.test('断言',function(){

    // 语法
    // pm.expect(elem).to.method(val);

    // 判断是否存在
    pm.response.to.have.header("Content-Type");//bolean

    // 请求头
    pm.expect(pm.response.headers.get('Content-Type')).to.eql('application/json')

    // 状态码
    // pm.expect(pm.response.code).to.eq(200);
    pm.expect(pm.response.code).to.oneOf([200,201]);

    // cookie
    pm.expect(pm.cookies.has('JSESSIONID')).to.be.false;

    // 响应时间
    pm.expect(pm.response.responseTime).to.be.below(2000);

    // 获取响应数据
    let resp = pm.response.json()

    // 类型
    // pm.expect(jsonData).to.be.an("object");
    // pm.expect(jsonData.name).to.be.a("string");
    // pm.expect(jsonData.age).to.be.a("number");
    // pm.expect(jsonData.hobbies).to.be.an("array");
    // pm.expect(jsonData.website).to.be.undefined;
    // pm.expect(jsonData.email).to.be.null;

    // 响应体
    pm.expect(resp.status).to.eq(200)

    // 业务数据
    // pm.expect(resp.usage).to.eql(pm.environment.get("usage"));

    // 数组
    let temp_array= ['names','goods']
    pm.expect(temp_array).to.be.empty;
    pm.expect(temp_array).to.include("goods");

    // 对象
    let temp_obj = {name: "zhang", age: 22}
    pm.expect(temp_obj).to.have.all.keys('name', 'age');
    pm.expect(temp_obj).to.have.any.keys('name', 'age');
    pm.expect(temp_obj).to.not.have.any.keys('gender', 'country');
    pm.expect(temp_obj).to.have.property('name');

    // 包含
    let temp_name = 'zhaoliu'
    pm.expect(temp_name).to.be.oneOf(["zhangsan", "lisi", "wangwu"]);

    // 环境
    pm.expect(pm.environment.name).to.eql("Prod");
})

异步请求

pm.test('异步请求',function(){

    let test_url = "https://localhost:8081/rec-login"

    pm.sendRequest(test_url, function (err, response) {
        console.log(response.json());
    });

})

数据解析 pm.test('解析数据',function(){

// json
let resp_json = pm.response.json();

// text
let resp_text = pm.response.text();

// xml
let resp_xml =  xml2Json(pm.response.text());

})

动态变量

  • postman内置大量动态变量,依赖faker-js库。 常用动态变量:

  • $guid :v4-guid

  • $timestamp:Unix时间戳,单位:秒

  • $randomInt:0到1000之间的随机整数

  • $randomUUID:随机的 36 个字符的 UUID

  • $randomColor:随机的颜色

  • $randomPassword:随机 15 个字符的字母数字密码

  • $randomFirstName:随机的名字

  • $randomLastName:随机的姓氏

  • $randomPhoneNumber:随机的 10 位电话号码

  • $randomAvatarImage:随机头像图片

    • 示例:

内置对象:(pm->postman) 概述:

  • 提供对请求和响应数据以及变量的访问。
  • 作用范围:全局可用。 变量:
  • 环境变量:pm.environment.method
  • 集合变量: pm.collectionVariables.method
  • 全局变量: pm.globals.method
  • 数据变量: pm.iterationData.method
  • method备注:
    • has
    • get
    • set 请求:
  • 对象获取: pm.request
  • 常用方法:
    • pm.request.url
    • pm.request.headers
    • pm.request.method
    • pm.request.body
    • pm.request.headers.add
    • pm.request.headers.remove 响应:
  • 对象获取:pm.response
  • 常用方法:
    • pm.response.code
    • pm.response.status
    • pm.response.headers
    • pm.response.responseTime
    • pm.response.responseSize
    • pm.response.text()
    • pm.response.json()

四、起飞

读取外部文件

  • 目前支持json、csv
  • 操作流程:
    • 选择文件 -> 指定参数 -> run
  • 图解:
    • 选择集合

    • 外部文件(json示例,可选csv)

    • 引入文件

    • 请求中使用外部变量

    • 效果

生成报告

安装环境

  • node.js[env]: 下载 (验证 newman -v )

  • newman[pkg mgr]:npm install -g newman (验证 newman -v)

  • newman-reporter-html[plugin]: npm install -g newman-reporter-html(验证npm list -g --depth 0) 操作示例

  • 导出集合

  • 使用脚本生成报告 newman run .\个人测试.postman_collection.json -r html

  • 当前文件夹下打开文件即可

  • 效果展示

集合协作

概述:

  • 像git管理代码一样管理源码。 操作流程:

  • 创建集合分支:

  • 合并变更

  • pull源码

  • 查看记录

  • 查看日志

接口文档

  • 生成在线文档 图解

    • 创建入口

    • 选择集合

  • markdown编写

  • 效果展示

  • 发布效果 (测试链接)

Mock

概述:

  • 模拟真实响应数据。 场景:

    1. 无法控制第三方系统某接口的返回,返回的数据不满足要求 比如:支付中最常用的刷卡支付,有可能直接支付成功,也有可能返回支付中,此逻辑受平台方风控逻辑校验,对我们来说完全是黑盒子
    2. 某依赖系统还未开发完成,就需要对被测系统进行测试 前端开发比较依赖后端开发提供的接口,然后根据接口返回值设计各类场景页面。当服务端开发人员未及时提供接口时可能会影响到前端开发及整个项目的进度,特别是在敏捷开发中,对于上下游开发顺序更加依赖
    3. 有些系统不支持重复请求,如支付功能
    4. 系统功能有访问频次限制,获取敏感信息的接口访问频次不可高于xx等 操作流程
  • 保存正常响应数据 -> 新建MockServer -> 拿到Mock Url -> 使用MockUrl建立请求 图解

  • 保存reponse

  • 新建MockServer

  • 拿到MockUrl

  • 请求示例

五、后记

其他个人已知功能 监控

  • 要花钱,但有免费额度。 连接数据库
  • 个人暂无应用场景,有需要的话,大家可自行摸索。

打 赏