#Api Tests# Postman + Newman 最佳实践

#Api Tests# Postman + Newman 最佳实践

本篇博客将讨论 Postman + Newman 的最佳实践,从以下五个方面来展开:

  • 初始化
  • 测试单个接口
  • 测试逻辑功能
  • 接口文档
  • 接口模拟

目录 Table of Contents


背景

程序写完之后,需要对单个接口和逻辑功能来进行测试,Postman (UI) 和 Newman (CLI) 是很易用且强大的工具。当然它们也拥有提供接口文档和进行接口模拟的功能,虽使用方便但略显粗糙。本博客将着重讨论测试部分,其它功能只做简单介绍,对于概念则不会过多地解释,主要讨论其功能与流程。

初始化

Global

公共变量

Environment

环境变量

Dynamic

内置变量

尽可能地抽取变量,既方便调试时修改数据,又方便自动测试的集成。

测试单个接口

请求内容

Request

  • Method:请求方法
  • Path:请求路径
  • Headers:请求头部
  • Params:请求参数
  • Body:请求主体

测试内容

Pre-request Script

  • Pre-request Script:测试前脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /* 发起请求:用户登录 */
    var ip = pm.environment.get("ip");
    var port = pm.environment.get("port");
    var username = pm.environment.get("username");
    var password = pm.environment.get("password");
    var body = {
    "username": username,
    "password": password
    };

    const postRequest = {
    url: "http://" + ip + ":" + port + "/login", // 请求路径
    method: 'POST', // 请求方法
    header: ['Content-Type:application/json'], // 请求头部
    body: { // 请求主体
    mode: "raw", // 格式
    raw: JSON.stringify(body) // 内容
    }
    };
    pm.sendRequest(postRequest, (err, response) => {
    if (err) {
    console.log(err);
    } else {
    console.log(response.json());
    }
    });

Tests

  • Tests:测试后断言

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /* 判断状态码正常:200 */
    pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
    });

    /* 发起请求:用户登录 */
    var ip = pm.environment.get("ip");
    var port = pm.environment.get("port");

    const postRequest = {
    url: "http://" + ip + ":" + port + "/logout",
    method: 'POST'
    };
    pm.sendRequest(postRequest, (err, response) => {
    if (err) {
    console.log(err);
    } else {
    console.log(response.json());
    }
    });

    /* 设置相关的变量:更新密码 */
    var body = JSON.parse(pm.request.body.raw);
    pm.environment.set("password", body["password"]);

测试逻辑功能

用例组织

  • 流程跳转:优点是非常灵活,缺点是有点复杂

    1
    postman.setNextRequest("接口名称");
  • 目录集合:优点是比较直观,缺点是存在冗余

    功能接口组成逻辑单元

用例设计

创建服务接口

  • Pre-request Script

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 生成随机的必填字段
    function rand (n, m) {
    var num = Math.floor(Math.random() * (m - n + 1) + n)
    return num
    }

    var tcp_port = rand(8001, 8999);
    pm.environment.set("tcp_port", tcp_port);

    var tcp_service_name = "test_tcp_service_" + rand(1, 100).toString();
    pm.environment.set("tcp_service_name", tcp_service_name);
  • Tests

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 状态判断
    pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
    });

    // 错误判断
    pm.test("Body not matches string", function () {
    pm.expect(pm.response.text()).not.to.include("user not login");
    });

    // 回写标识
    var body = pm.response.json();
    pm.environment.set("service_id", body["data"]["info"]["id"]);

查询服务详情接口

  • 对 Tests 进行状态判断和错误判断

修改服务接口

  • Body

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
    "black_list": "",
    "client_ip_flow_limit": 0,
    "forbid_list": "",
    "ip_list": "127.0.0.1:2333",
    "open_auth": 0,
    "port": {{tcp_port}},
    "round_type": 0,
    "service_desc": "updated", // 特殊字串
    "service_host_flow_limit": 0,
    "service_name": "{{tcp_service_name}}",
    "weight_list": "50",
    "white_host_name": "",
    "white_list": ""
    }
  • Tests

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 状态判断
    pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
    });

    // 错误判断
    pm.test("Body not matches string", function () {
    pm.expect(pm.response.text()).not.to.include("user not login");
    });

    // 子串判断:特殊字串
    pm.test("Body matches string", function () {
    pm.expect(pm.response.text()).to.include("updated");
    });

删除服务接口

  • 对 Tests 进行状态判断和错误判断

查询服务列表接口

  • Params

    1
    2
    3
    keyword:{{service_name}} // 模糊搜索
    //page_index:2
    //page_size:2
  • Tests

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 状态判断
    pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
    });

    // 错误判断
    pm.test("Body not matches string", function () {
    pm.expect(pm.response.text()).not.to.include("user not login");
    });

    // 数量判断:特殊数值
    pm.test("Service not found", function () {
    pm.expect(pm.response.json().data.total).to.eql(0);
    });

运行测试

  • Postman:界面化操作

    进行参数设置

    Postman 运行结果

  • Newman:命令行操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # file path: test/postman/*.json

    # npm install -g newman
    # npm install -g newman-reporter-html or npm install -g newman-reporter-htmlextra

    # Initiate a Postman Collection run from a given URL or path
    newman run test/postman/giotto-gateway.postman_collection.json \
    # Define the number of iterations to run
    -n 1 \
    # Specify the extent of delay between requests (milliseconds) (default: 0)
    --delay-request 0 \
    # Specify a URL or path to a Postman Environment
    -e test/postman/giotto-gateway_env_local.postman_environment.json \
    # Specify a URL or path to a file containing Postman Globals
    -g test/postman/giotto-gateway.postman_globals.json \
    # Specify the reporters to use for this run (default: ["cli"])
    -r htmlextra \
    # Export test report as html (default: newman/*.html)
    --reporter-html-export giotto-gateway.newman_report.html

    Newman 运行结果

接口文档

Publish Docs

已支持的功能

  1. 在线接口文档
  2. 目录和接口的描述
  3. 请求示例:根据环境进行填充
  4. 响应示例:Save response as example
  5. 生成多种语言的请求代码等

不支持的功能

  1. 离线接口文档
  2. 请求参数描述
  3. 响应参数描述

接口模拟

修改响应示例路径

替换 mock_url 地址

测试接口模拟效果

返回预期响应示例

附录


Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×