Postman高效实践(下)

简介: 四、脚本Postman基于Node.js开发了一个强大的运行脚本平台,可以在请求和集合运行前后添加更多的动态操作,你可以使用它来编写测试用例、构建请求,你可以在下面两个事件执行的时候添加JavaScript代码:在请求发送到服务器之前,可以在 Pre-request Script 标签页添加前置脚本在响应到达之后,可以在 Tests 标签页上添加测试脚本


四、脚本



Postman基于Node.js开发了一个强大的运行脚本平台,可以在请求和集合运行前后添加更多的动态操作,你可以使用它来编写测试用例、构建请求,你可以在下面两个事件执行的时候添加JavaScript代码:

  • 在请求发送到服务器之前,可以在 Pre-request Script 标签页添加前置脚本
  • 在响应到达之后,可以在 Tests 标签页上添加测试脚本

微信图片8888.jpg

你不仅可以在每个请求中添加脚本,还可以在文件夹、集合中添加脚本,脚本的执行顺序如下:

微信图片7777.png

在脚本中使用 console.log('...') 等打印日志的代码时,会在Postman的控制台输出,可以点击左下角的控制台(Ctrl+Alt+C)图标打开:微信图片6666.jpg

Postman的脚本执行原理是Postman基于Node.js开发,并自带一个沙箱环境来运行JavaScript脚本


1. 前置脚本


前置脚本在发送请求之前执行,可以用来定义参数构建请求,比如在发送的请求中添加一个时间请求头:

  • 在请求的 Pre-request Script 标签中编写下面代码:
pm.globals.set("timestampHeader", new Date());

在请求头 Headers 标签添加timestamp请求头,并使用{{timestampHeader}}来使用变量

微信图片4444.png

不管是全局变量还是环境变量,还是集合的变量,都可以在URL、表单、请求体等输入框通过 {{var}} 来使用变量。


2. 测试脚本


使用JavaScript语言来为每个请求编写测试。

微信图片3333.jpg

在Postman发送请求之后,可以访问响应对象 pm.response,例如:

// pm.response.to.have
pm.test("response is ok", function () {
    pm.response.to.have.status(200);
});
// pm.expect()
pm.test("environment to be production", function () {
    pm.expect(pm.environment.get("env")).to.equal("production");
});
// response 断言
pm.test("response should be okay to process", function () {
    pm.response.to.not.be.error;
    pm.response.to.have.jsonBody("");
    pm.response.to.not.have.jsonBody("error");
});
// pm.response.to.be*
pm.test("response must be valid and have a body", function () {
    pm.response.to.be.ok;
    pm.response.to.be.withBody;
    pm.response.to.be.json;
});

在编写脚本的时候虽然你只需要记住很少的一些代码,Postman在编辑栏也提供了常用的代码片段,来帮助你更快的编写脚本。微信图片2222.png

在响应的 Tests 标签栏可以看到所有测试的结果。

微信图片1111.png

在编辑集合或者文件夹的时候可以添加脚本。当你运行一个集合或文件夹时,里面包含多个请求,可以使用脚本来控制请求的工作流:


设置当前请求执行完的下一个请求

 postman.setNextRequest("request_name");


设置当前请求执行完后停止请求

postman.setNextRequest(null);

使用 postman.setNextRequest() 注意的点:

  1. 指定后续请求的名称或ID,然后使用 Runner 来执行
  2. 它可以在前置脚本和测试脚本中使用,如果指定了多个,只有最后一个有效
  3. 如果没有postman.setNextRequest()Runner将按顺序执行后续请求


3. 测试示例


下面是常用的测试脚本:

设置环境变量

pm.environment.set("variable_key", "variable_value");

设置嵌套对象环境变量

var array = [1, 2, 3, 4];
pm.environment.set("array", JSON.stringify(array, null, 2));
var obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
pm.environment.set("obj", JSON.stringify(obj));

获取环境变量

pm.environment.get("variable_key");

获取嵌套对象环境变量

var array = JSON.parse(pm.environment.get("array"));
var obj = JSON.parse(pm.environment.get("obj"));


清除环境变量

pm.environment.unset("variable_key");

设置全局变量

pm.globals.set("variable_key", "variable_value");

获取全局变量

pm.globals.get("variable_key");

清除全局变量

pm.globals.unset("variable_key");

获取变量:从环境变量和全局变量中搜索

pm.variables.get("variable_key");

检验响应体中是否包含字符串

pm.test("Body matches string", function () {
    pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});

检验响应体中是否等于字符串

pm.test("Body is correct", function () {
    pm.response.to.have.body("response_body_string");
});

检验响应的JSON的值

pm.test("Your test name", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(100);
});

检验是否存在Content-Type

pm.test("Content-Type is present", function () {
    pm.response.to.have.header("Content-Type");
});

检验响应时间是否小于200毫秒

pm.test("Response time is less than 200ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(200);
});

检验状态码是否为200

pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

检验状态码名称包含字符串

pm.test("Status code name has string", function () {
    pm.response.to.have.status("Created");
});
检验状态码是否在某个范围内

验状态码是否在某个范围内

pm.test("Successful POST request", function () {
    pm.expect(pm.response.code).to.be.oneOf([201, 202]);
});

使用TinyValidator校验JSON数据

var schema = {
    "items": {
        "type": "boolean"
    }
};
var data1 = [true, false];
var data2 = [true, 123];
pm.test('Schema is valid', function () {
    pm.expect(tv4.validate(data1, schema)).to.be.true;
    pm.expect(tv4.validate(data2, schema)).to.be.true;
});

JSON校验

var Ajv = require('ajv'),
    ajv = new Ajv({ logger: console }),
    schema = {
        "properties": {
            "alpha": {
                "type": "boolean"
            }
        }
    };
pm.test('Schema is valid', function () {
    pm.expect(ajv.validate(schema, { alpha: true })).to.be.true;
    pm.expect(ajv.validate(schema, { alpha: 123 })).to.be.false;
});

base64解码

var intermediate,
    base64Content,
    rawContent = base64Content.slice('data:application/octet-stream;base64,'.length);
intermediate = CryptoJS.enc.Base64.parse(base64content);
pm.test('Contents are valid', function () {
    pm.expect(CryptoJS.enc.Utf8.stringify(intermediate)).to.be.true;
});

发送异步请求:该函数可以用于前置脚本和测试脚本中

pm.sendRequest("https://postman-echo.com/get", function (err, response) {
    console.log(response.json());
});

XML转换成JSON对象

var jsonObject = xml2Json(responseBody);


4. 脚本API

Postman脚本提供了简单实用的API用于测试和工作流。


4.1 require

require(moduleName:String):function → *

require函数可以导入Postman沙箱内置的模块库,包含下列内置库:

  • ajv → v6.6.2
  • atob → v2.1.2
  • btoa → v1.2.1
  • chai → v4.2.0
  • cheerio → v0.22.0
  • crypto-js → v3.1.9-1
  • csv-parse/lib/sync → v1.2.4
  • lodash → v4.17.11 (when used with require, the inbuilt _ object is for v3.10.1)
  • moment → v2.22.2 (sans locales)
  • postman-collection → v3.4.0
  • tv4 → v1.3.0
  • uuid → (the module loaded is a shim for original module)
  • xml2js → v0.4.19

一些NodeJS的模块也可以使用:

  • path
  • assert
  • buffer
  • util
  • url
  • punycode
  • querystring
  • string_decoder
  • stream
  • timers
  • events

使用函数导入模块赋值给变量,例如:

var atob = require('atob'),
    _ = require('lodash'),
    arrayOfStrings,
    base64Strings;
arrayOfStrings = ['string1', 'string2'];
base64Strings = _.map(arrayOfStrings, atob);
console.log(base64Strings);

4.2 pm

pm:Object

pm对象封装了有关脚本执行的所有信息,可以用来获取请求、响应信息,也可以获取和设置环境环境变量和全局变量。

pm.info:Object

pm.info对象包含了脚本执行时的信息,比如请求名称,请求ID和迭代次数都保存在这对象中。

  • pm.info.eventName:String:执行脚本名称,前置脚本:prerequest,测试脚本:test
  • pm.info.iteration:NumberRunner执行时的当前迭代计数
  • pm.info.iterationCount:Number:迭代执行时的迭代总数
  • pm.info.requestName:String
  • pm.info.requestId:String

pm.sendRequest:Function

pm.sendRequest函数可以用来发送HTTP/HTTPS的异步请求,异步请求,只是在后台处理一些繁重的复杂的逻辑,或是发送多个请求,而不要等待阻塞下一个请求,你可以使用回调函数来处理返回结果。该函数可以用于前置脚本和测试脚本中。

// 普通URL
pm.sendRequest('https://postman-echo.com/get', function (err, res) {
    if (err) {
        console.log(err);
    } else {
        pm.environment.set("variable_key", "new_value");
    }
});
// 构建SDK请求
const echoPostRequest = {
    url: 'https://postman-echo.com/post',
    method: 'POST',
    header: 'headername1:value1',
    body: {
        mode: 'raw',
        raw: JSON.stringify({ key: 'this is json' })
    }
};
pm.sendRequest(echoPostRequest, function (err, res) {
    console.log(err ? err : res.json());
});
// 包含测试
pm.sendRequest('https://postman-echo.com/get', function (err, res) {
    if (err) { console.log(err); }
    pm.test('response should be okay to process', function () {
        pm.expect(err).to.equal(null);
        pm.expect(res).to.have.property('code', 200);
        pm.expect(res).to.have.property('status', 'OK');
    });
});

参考:

  • Request JSON
  • Response Structure

pm.globals:VariableScope

  • pm.globals.has(variableName:String):function → Boolean
  • pm.globals.get(variableName:String):function → *
  • pm.globals.set(variableName:String, variableValue:String):function
  • pm.globals.unset(variableName:String):function
  • pm.globals.clear():function
  • pm.globals.toObject():function → Object

pm.environment:VariableScope

  • .pm.environment.has(variableName:String):function → Boolean
  • pm.environment.get(variableName:String):function → *
  • pm.environment.set(variableName:String, variableValue:String):function
  • pm.environment.unset(variableName:String):function
  • pm.environment.clear():function
  • pm.environment.toObject():function → Object

pm.variables:VariableScope

在Postman中,所有的变量定义都是有优先级的,在当前迭代请求中定义的变量优先于在环境中定义的变量,而环境变量优先于全局变量。优先级:Iteration Data > Environment >Global,在环境中或全局定义的变量都可以通过下面函数获取到。

  • pm.variables.get(variableName:String):function → *

pm.request:Request

pm.request对象包含请求信息,例如:

  • pm.request.url:Url
  • pm.request.headers:HeaderList


4.3 测试脚本


pm.response:Response

pm.response对象包含响应信息,例如:

  • pm.response.code:Number
  • pm.response.reason():Function → String
  • pm.response.headers:HeaderList
  • pm.response.responseTime:Number
  • pm.response.text():Function → String
  • pm.response.json():Function → Object

pm.iterationData:VariableScope

pm.iterationData对象在使用Runner运行集合或文件夹时通过数据文件导入的数据。

  • pm.iterationData.get(variableName:String):function → *
  • pm.iterationData.toObject():function → Object

pm.cookies:CookieList

cookies对象可以获取到Cookies信息,例如:

  • pm.cookies.has(cookieName:String):Function → Boolean
    检查在当前的请求域名中是否存在特定的Cookie
  • pm.cookies.get(cookieName:String):Function → String
    获取特定Cookie的值
  • pm.cookies.toObject:Function → Object
    以对象形式获取 Cookies的值

pm.test(testName:String, specFunction:Function):Function

你可以使用该函数来编写测试点,来检验响应是否符合预期:

pm.test("response should be okay to process", function () {
    pm.response.to.not.be.error;
    pm.response.to.have.jsonBody('');
    pm.response.to.not.have.jsonBody('error');
});

pm.expect(assertion:*):Function → Assertion

pm.expect是一个通用断言函数,使用ChaiJS expect BDD library标准,这个库可以让测试代码更具可读性。

pm.test('environment to be production', function () {
    pm.expect(pm.environment.get('env')).to.equal('production');
});


4.4 响应断言

  • pm.response.to.have.status(code:Number)
  • pm.response.to.have.status(reason:String)
  • pm.response.to.have.header(key:String)
  • pm.response.to.have.header(key:String, optionalValue:String)
  • pm.response.to.have.body()
  • pm.response.to.have.body(optionalValue:String)
  • pm.response.to.have.body(optionalValue:RegExp)
  • pm.response.to.have.jsonBody()
  • pm.response.to.have.jsonBody(optionalExpectEqual:Object)
  • pm.response.to.have.jsonBody(optionalExpectPath:String)
  • pm.response.to.have.jsonBody(optionalExpectPath:String, optionalValue:*)
  • pm.response.to.have.jsonSchema(schema:Object)
  • pm.response.to.have.jsonSchema(schema:Object, ajvOptions:Object)

pm.response.to.be.*

  • pm.response.to.be.info:检验1XX状态码
  • pm.response.to.be.success:检验2XX状态码
  • pm.response.to.be.redirection:检验3XX状态码
  • pm.response.to.be.clientError:检验4XX状态码
  • pm.response.to.be.serverError:检验5XX状态码
  • pm.response.to.be.error:检验4XX状态码或5XX状态码
  • pm.response.to.be.ok:检验状态码是否为200
  • pm.response.to.be.accepted:检验状态码是否为202
  • pm.response.to.be.badRequest:检验状态码是否为400
  • pm.response.to.be.unauthorized:检验状态码是否为401
  • pm.response.to.be.forbidden:检验状态码是否为403
  • pm.response.to.be.notFound:检验状态码是否为404
  • pm.response.to.be.rateLimited:检验状态码是否为429


五、变量



Postman支持设置各种不同作用域的变量,可以在脚本中引用这些变量,也可以在请求的URL、参数、请求体等地方使用{{var_name}}来调用,Postman可以在集合中设置变量,可以创建环境抽象来设置变量,也可以设置作用域最大的全局变量。简而言之,使用变量可以:

  • 管理一些特殊的值,方便修改
  • 根据不同的环境对同一变量设置不同的值
  • 解析响应中的值,以及更灵活地构建一个请求

所有变量的值都只能是字符串类型,如果有复杂的对象类型,可以使用JSON字符串来设置。例如:

varstr=JSON.stringify(object);

varobj=JSON.parse(str);


1. 变量


1.1 变量作用域

Postman中有5种作用域:

  • Global:全局变量
  • Collection:集合变量
  • Environment:环境变量
  • Data:导入数据的变量
  • Local/Tempoary:本地变量/临时变量

不同作用域有着不同的优先级,作用域的大小如下图所示,如果在两个作用域中有同名变量,取优先级大的作用域中的值,作用域越大,优先级越低。

微信图片28.png


1.2 在请求中使用变量

使用{{variableName}}在构建请求时的任务地方插入变量的值,比如接口的域名、参数、请求头等地方。例如:

微信图片27.jpg


1.3 在脚本中使用变量


在脚本中通过代码获取在各个作用域中设置的变量:

  • 使用pm.environment.get()pm.environment.set()来获取和设置环境变量
  • 使用pm.globals.get()pm.globals.set()来获取和设置全局变量
  • 使用pm.variables.get()可以从任何作用域中搜索值,使用pm.variables.set()来设置变量


1.4 定义集合变量

在新建和编辑集合的时候,可以在Variables标签页里定义集合变量。


1.5 导入数据文件的变量

在使用 Runner 运行集合的时候,你可以导入CSV或者JSON数据文件,然后使用这些数据发送HTTP请求,这些数据的会根据字段名称导入为变量。这些变量在请求中一样可以使用{{variableName}}来插入,在脚本中可以使用pm.iterationData.get("username")来获取,例如:

微信图片26.jpg

1.6 内置变量

Postman提供了几个内置变量来加强请求,你可以在请求的URL、请求头或请求体等地方通过{{...}}来使用,这些变量包括:

  • {{$guid}}:生成字符串UUID
  • {{$timestamp}}:生成当前时间的时间戳
  • {{$randomInt}}:生成0到1000的随机整数

2. 环境和全局变量

当测试API的时候,你可能需要在本地环境、开发环境、测试环境或者生产环境使用不同的变量设置,使用环境变量可以很容易的实现这一功能。


2.1 创建环境和全局变量

点击界面右上方的 Manage Environments 图标来管理环境变量和全局变量。

微信图片25.png

2.2 选择环境

点击界面右上方的下拉列表框可以选择环境,选择不同的环境激活不同的变量组。

微信图片24.jpg


2.3 查看环境和全局变量

微信图片23.jpg


3. 作用域和优先级

下图描述了Postman中变量的工作方式:

微信图片22.png



变量使用示例:假设我们创建了三个集合C1、C2和C3,还创建了三个环境Dev、Staging和Prod,在三个环境中都存在一个URL变量,在不同的环境有不同的值。每个集合中有一个定义超时的变量,集合C1中的是10,C2中的是20,C3中的是30。定义一个全局变量重试次数为3,如下图所示。


微信图片21.png


现在,选择不同的环境就可以使用不同的URL,每个集合下的超时时间是不一样的,但与哪个环境无关,全局变量不管在哪个环境,哪个集合下都是一样的。





目录
相关文章
|
XML JSON 前端开发
Postman高效实践(上)
Postman是一款优秀的HTTP接口测试软件,它最初是谷歌浏览器的插件,后来独立成PC软件,支持多平台(macOS / Windows / Linux)安装。测试对于开发人员开发高质量的应用不可或缺,对于后端开发,除了必要的单元测试之外,也应对HTTP接口层进行相应的测试,对于前端开发,除了对接口进行检验外,也可以Mock接口服务,达到与后端并行开发的目的。
459 0
Postman高效实践(上)
|
4月前
阿萨聊测试:如何用Postman查看HTTP消息相关内容?
阿萨聊测试:如何用Postman查看HTTP消息相关内容?
阿萨聊测试:如何用Postman查看HTTP消息相关内容?
|
4月前
|
JSON 数据格式 开发者
Postman模仿GET/POST请求进行接口的本地测试
接口是软件开发中常用的概念,是软件生产过程中比较核心的任务。对于接口开发者,调试接口是一件较为繁琐的事情,很多时候需要线上线下来回切换。在这里,我就跟大家介绍一个只需要在本地就可以调试接口的方法。
67 0
|
5月前
|
JavaScript 前端开发 测试技术
Postman 加密接口测试 | 使用Rsa、Aes对参数加密
Postman 加密接口测试 | 使用Rsa、Aes对参数加密
241 0
|
5月前
|
JSON 测试技术 API
『Postman入门万字长文』| 从工具简介、环境部署、脚本应用、Collections使用到接口自动化测试详细过程
『Postman入门万字长文』| 从工具简介、环境部署、脚本应用、Collections使用到接口自动化测试详细过程
80 3
|
4月前
|
JSON API 开发工具
如何使用Postman 设计和测试一个API?
如何使用Postman 设计和测试一个API?
如何使用Postman 设计和测试一个API?
|
2月前
|
JSON 测试技术 API
Postman Newman 实现 API 自动化测试的快速指南
Newman 是一款专为 Postman 打造的命令行工具,旨在通过自动运行 Postman 集合和环境,实现 API 测试的自动化。它使得开发者无需打开 Postman 图形界面,即可直接在命令行中执行测试用例。
|
3月前
|
JSON JavaScript 前端开发
提升 API 测试效率:Postman Tests 详解
Postman 不仅是一个强大的 API 开发工具,它还提供了创建自动化测试脚本的能力,这些脚本可以用于检验API请求得到的响应是否符合预期。这些测试脚本被称为 “Tests”,支持使用 JavaScript 编程语言进行编写,并且 Postman 提供了一系列的断言库来帮助你检查包括但不限于状态码、响应内容以及响应时间在内的响应数据。
|
3月前
Postman 测试上传与下载
Postman 测试上传与下载
42 0
|
4月前
|
API 数据安全/隐私保护
如何使用Postman 测试Https 网站?
如何使用Postman 测试Https 网站?
112 0