postman变量和脚本功能介绍

news2024/11/24 8:46:12

1、基本概念——global、collection、environment

在postman中,为了更好的管理各类变量、测试环境以及脚本等,创建了一些概念,包括:globals、collection、environment。其实在postman中,最上层还有一个Workspaces的概念,不过大多数情况我们都使用一个workspace,这里就不多介绍了。

1.1)请求组(collection):

可以将多个请求保存到一个请求组(Collections)中, 好处是: 增加额外Collection变量作用域, 增加公共的PreRequest和Test脚本, 批量执行Collection下的请求, 定义Collection内请求的顺序。

上图中可以看到,左上角“+”可以创建新的collection;点击collection的右侧“。。。”可以Edit现有collection,以及Run、Add folder等功能。

说明Collection下还可以建文件夹,对请求进一步划分,比如:用户模块、订单模块。

1.2)环境(environment):

通常一个系统具备多个环境,比如:测试、线上。

如上图,点击左上角“+”可以新建一个environment;鼠标指向现有environment,点击右侧“。。。”可以进行编辑。值得提醒的是,当运行时,需要在右上角选中我们想要的环境。

变量有两个value(不光是环境变量,其他变量也是一样的),二者的区别:

  • INITAL_VALUE:初始值是在定义变量的元素(集合、环境或全局变量)中设置的值。此值将同步到 Postman 的服务器,并在您共享该元素时与您的团队共享
  • CURRENT_VALUE:这些是本地值,不会同步到 Postman 的服务器。如果您更改当前值,它将不会保留在原始共享集合、环境或全局变量中。

1.3)golbal:

细心的朋友已经发现,在environment中,左上角出现了Golbals:

2、变量

变量,在postman中最常见的一个功能,包括设置、读取、作用域等。

2.1)变量作用域:

postman中变量有多个作用域, 越往内的作用域优先级越高(global < collection < environment < …), 举例来说, 如果global作用域和Environment作用域里都有一个变量叫username, 那么最终使用的是Environment作用域里的变量值。

 

 不同作用域变量设置方法:

2.2)定义、使用变量

从上面图可以看到,在UI界面上可以管理globals变量,后面也会降到使用API方式设置、读取globes变量(会同步出现在UI界面上);同样的,对于environment变量也是一样的。(如上面1.2和1.3)

1)通过界面定义变量:

选中某个值,然后点击弹出的菜单点击"Set as new variable":

 

然后这只变量名、和作用域:

 

2)管理Collections变量:

选择某个Collection后,点击右侧的“。。。”,然后选择Edit,在右侧界面上会显示Variables。

3)使用变量:

在不同作用域定义好变量后, 然后在某个请求中引用该变量, 从而做到变量复用和统一管理。

 使用"{{变量名}}"来引用变量。

2.3)在脚本中操作变量

// 不同作用域设置变量
pm.globals.set("username", "golbals_name");
pm.globals.set("username1", "golbals_name1");
pm.collectionVariables.set("username", "collection_name");
pm.environment.set("username", "environment_name");
pm.variables.set("username", "variable_username"); //临时覆盖, 优先级最高, 请求结束后失效

// 获取变量值
console.log(pm.globals.get("username")); //从globals作用域中查询变量
console.log(pm.collectionVariables.get("username"));
console.log(pm.environment.get("username"));
var k = pm.variables.get("username1"); //依次从各个作用域查找
console.log("username:" + k);


// 判断
pm.variables.has("username");
pm.environment.has("username");
pm.globals.has("username");

// 清理
pm.environment.unset("username");

2.4)data作用域的变量

在UI界面上,选择Collection的Run,在界面中可以选择一个文件

 

然后准备一个文件,内容如下:(必须是json或者csv格式)

[{
  "path": "post",
  "value": "1"
}, {
  "path": "post",
  "value": "2"
}, {
  "path": "post",
  "value": "3"
}, {
  "path": "post",
  "value": "4"
}]

另外,在脚本里访问data文件可以使用如下AIP:

pm.iterationData.get("value");

3、脚本

postman API文档:Home - Postman Documentation

3.1)脚本相关概念:

1)脚本执行顺序:

执行每个请求时会依次执行如下脚本:

  1. Collection级别的pre-request脚本
  2. Folder级别的pre-request脚本
  3. Request级别的pre-prequest脚本
  4. Request级别的test脚本
  5. Folder级别的test脚本
  6. Collection级别的test脚本

 

2)在界面上输入脚本信息: 

最常见的就是request级别的脚本,可以在Scripts页签下输入,如下:

可以看到,脚本分两个:pre-request和post-reponse,分别对应请求前处理和请求后处理。

在Collection级别上也可以创建脚本,如下:

同样,如果在Collection下有folder,那么folder上也可以创建scripts。 

3.2)常用脚本代码

1)操作变量:

// 设置全局变量
pm.globals.set('variable_key', 'variable_value');
var variable_key = pm.globals.get('variable_key');// 获取全局变量
pm.globals.unset('variable_key');// unset 全局变量

// 设置环境变量
pm.environment.set('variable_key', 'variable_value');
var variable_key = pm.environment.get('variable_key');// 获取环境变量
pm.environment.unset('variable_key');// unset 环境变量

// 设置临时变量
pm.variables.set('variable_key', 'variable_value');
var variable_key = pm.variables.get('variable_key');// 获取临时变量
pm.variables.unset('variable_key');// unset 临时变量

// 将对象或数组(非字符串)写入环境变量
var array = [1, 2, 3, 4];
pm.environment.set('array', JSON.stringify(array));
var obj = { a: [1, 2, 3, 4], b: { c: 'val' } };
pm.environment.set('obj', JSON.stringify(obj));
// 转换回来
try {
  var array = JSON.parse(pm.environment.get('array'));
  var obj = JSON.parse(pm.environment.get('obj'));
} catch (e) {
  // 处理异常
}

2)前置读取/修改接口信息:

// ================= URL ===================
// 获取 url 对象
var urlObject = pm.request.url;

// 获取完整接口请求 URL,包含 query 参数
var url = urlObj.toString();

// 获取协议(http 或 https)
var protocol = urlObj.protocol;

// 获取 端口
var port = urlObj.port;

// ================= Header ===================
// 获取 Header 参数对象
var headers = pm.request.headers;

// 获取 key 为 field1 的 header 参数的值
var field1 = headers.get('field1');

// 已键值对象方式获取所有 query 参数
var headersObject = headers.toObject();

// 遍历整个 query
headers.each(item => {
    console.log(item.key); // 输出参数名
    console.log(item.value); // 输出参数值
});

// 增加 header 参数
headers.add({
    key: 'field1',
    value: 'value1',
});

// 修改 query 参数(如不存在则新增)
headers.upsert({
    key: 'field2',
    value: 'value2',
});

// ================= Query ===================
// 获取 Query 参数对象
var queryParams = pm.request.url.query;

// 获取 key 为 field1 的 query 参数的值
var field1 = queryParams.get('field1');

// 已键值对象方式获取所有 query 参数
var quertParamsObject = queryParams.toObject();

// 遍历整个 query
queryParams.each(item => {
    console.log(item.key); // 输出参数名
    console.log(item.value); // 输出参数值
});

// 增加 query 参数
queryParams.add({
    key: 'field1',
    value: 'value1',
});

// 修改 query 参数(如不存在则新增)
queryParams.upsert({
    key: 'field2',
    value: 'value2',
});

// ================= Body ===================
// Body 参数来自pm.request.body,pm.request.body 是一个RequestBody 实例。
// Body 参数在只能读取,不能直接修改。如需修改 Body 里的数据,请在 Body 里引用变量,然后在脚本里设置变量的值,以达到修改的目的。

// --------------------- body 类型为 form-data ------------------
// 当 body 类型为 form-data 时,从 pm.request.body.formdata 获取请求参数
var formData = pm.request.body.formdata;

// 获取 key 为 field1 的 form-data 参数的值
var field1 = formData.get('field1');
console.log(field1); // 控制台打印 field1

// 已键值对象方式获取所有 formdata 参数
var formdataObject = formData.toObject();
console.log(formdataObject); // 控制台打印 formdataObject

// 遍历整个 form-data 数据
formData.each(item => {
    console.log(item.key); // 控制台打印参数名
    console.log(item.value); // 控制台打印参数值
});

// --------------------- body 类型为 x-www-form-urlencode ------------------
// 当 body 类型为 x-www-form-urlencode** 时,从 pm.request.body.urlencoded 获取请求参数
var formData = pm.request.body.urlencoded;

// 获取 key 为 field1 的 form-data 参数的值
var field1 = formData.get('field1');

// 已键值对象方式获取所有 formdata 参数
var formdataObject = formData.toObject();

// 遍历整个 form 数据
formData.each(item => {
    console.log(item.key); // 控制台打印参数名
    console.log(item.value); // 控制台打印参数值
});

// --------------------- body 类型为 JSON ------------------
try {
    var jsonData = JSON.parse(pm.request.body.raw);
    console.log(jsonData); // 控制台打印参整个 json 数据
} catch (e) {
    console.log(e);
}

// --------------------- body 类型为 raw ------------------
var raw = pm.request.body.raw;
console.log(raw); // 控制台打印参整个 raw 数据

3)常用后置脚本:

pm.test("响应状态码为200", function () {
  pm.response.to.have.status(200);
  pm.expect(pm.response.code).to.eql(200);
});

// GET https://gank.io/api/v2/banners
pm.test("成功响应且有数据", function() {
	pm.expect(pm.response.code).to.eql(200);

    const respJson = pm.response.json();
    pm.expect(respJson.data).to.length.gt(0);
})

// GET https://gank.io/api/v2/data/category/GanHuo/type/iOS/page/1/count/10
pm.test("分页数据满页", function() {
    const respJson = pm.response.json();
    pm.expect(respJson.data.length).to.eq(10);
    pm.expect(respJson.data).to.have.lengthOf(10);
})

// 在脚本中发送请求
pm.sendRequest("https://gank.io/api/v2/banners", function(err, resp) {
    console.log(resp.json())
})

// 响应数据转换
// json
const responseJson = pm.response.json();
// xml
const responseJson = xml2Json(pm.response.text());
// csv
const parse = require('csv-parse/lib/sync');
const responseJson = parse(pm.response.text());
// html https://cheerio.js.org
const $ = cheerio.load(pm.response.text());
console.log($.html());
console.log($(".header"));
// 纯文本
pm.expect(pm.response.text()).to.include("customer_id");
pm.response.to.have.body("whole-body-text");

// 将 jsonData.token 的值写入环境变量
pm.environment.set('token', jsonData.token);

4)常用断言:

// response assertions 示例
pm.test('返回结果没有错误', 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('返回结果没有错', function() {
  // assert that the status code is 200
  pm.response.to.be.ok; // info, success, redirection, clientError,  serverError, are other variants
  // assert that the response has a valid JSON body
  pm.response.to.be.withBody;
  pm.response.to.be.json; // this assertion also checks if a body  exists, so the above check is not needed
});

// -----------  状态码  -------------
pm.test('Status code is 200', function() {
  pm.response.to.have.status(200);
});
// 检查 HTTP 状态码名称是否包含某个字符串
pm.test('Status code name has string', function() {
  pm.response.to.have.status('Created');
});
// 是否正确的 POST 请求状态码
pm.test('Successful POST request', function() {
  pm.expect(pm.response.code).to.be.oneOf([201, 202]);
});

// --------- 请求头  ---------
pm.expect(pm.response.headers.get('Content-Type')).to.eql('application/json');
pm.test('Content-Type header is present', function() {
  pm.response.to.have.header('Content-Type');
});

// ---------  cookie  ---------
pm.expect(pm.cookies.has('JSESSIONID')).to.be.true;
pm.expect(pm.cookies.get('isLoggedIn')).to.eql('1');

// ---------  响应时间 ms  ---------
pm.test('Response time is less than 200ms', function() {
  pm.expect(pm.response.responseTime).to.be.below(200);
});

// ---------------  请求体验证  -----------------
const jsonData = pm.response.json();
pm.expect(jsonData.name).to.eql("Jane");
// 响应值等于某个预先定义的变量值
pm.expect(jsonData.name).to.eql(pm.environment.get("name"));

// 检查 response body 是否包含某个字符串
pm.test('Body matches string', function() {
  pm.expect(pm.response.text()).to.include('string_you_want_to_search');
});

// 检查 response body 是否包含等于字符串
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);
});

// 断言数据类型
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(jsonData.errors).to.be.empty;
pm.expect(jsonData.errors).to.be.an('array').that.is.empty;
pm.expect(jsonData.areas).to.include("goods");
const contactSettings = jsonData.settings.find(m => m.type === "contact");
pm.expect(contactSettings).to.be.an("object", "找不到联系方式配置信息");
pm.expect(contactSettings.detail).to.have.members(["email", "sms"]);

// 对象
pm.expect({a: 1, b: 2}).to.have.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd');
pm.expect({a: 1}).to.have.property('a');
pm.expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b');
pm.expect({a: 1, b: 2}).to.deep.include({a:1});	// 包含部分属性
// 集合
pm.expect({"a": 1, "b": 123}.a).to.be.oneOf([1, 123]);

// 字符串
pm.expect('').to.be.empty;

5)脚本里发送请求:

pm.sendRequest('https://postman-echo.com/get', (error, response) => {
  if (error) {
    console.log(error);
  } else {
    console.log(response);
    pm.environment.set('variable_key', 'new_value');
  }
});

// 完整的 request 参数示例
const echoPostRequest = {
  url: 'https://postman-echo.com/post',
  method: 'POST',
  header: {
    headername1: 'value1',
    headername2: 'value2',
  },
  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');
  });
});

在Runner中运行collection下的请求时, 可以通过postman.setNextRequest(请求名) 或者 postman.setNextRequest(请求id)来指定下一个请求, 这样可以构建起一个调用工作流, 比如先请求数据列表接口, 然后从响应中获取数据id, 再请求数据详情接口. 

原文:postman | Tonny's Blog

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么汽车电源正在用 48V 取代 12V

欧姆定律也有利于 48 伏电源 假设您需要为汽车的起动电机供电。可能存在以下静态和动态特征&#xff1a; 电源电压&#xff1a;12V 额定电流&#xff1a;40A 额定功率&#xff1a;480W 标称平均阻抗&#xff1a;0.3Ω 浪涌电流&#xff1a;150A 浪涌功率&#xff1a;1,8…

【webrtc】 RTP 中的 MID(Media Stream Identifier)

RTP 中的 MID(Media Stream Identifier) RID及其与MID的区别 cname与mid的对比【webrtc】CNAME 是rtprtcp中的Canonical Name(规范化名称) 同样都是RTP头部扩展: 基于mediasoup的最新的代码,学习,发现mid在创建RtpSendStream时是必须传递的参数: 例如 D:\XTRANS\soup\…

酷炫的鼠标移入效果(附源码!!)

预览效果 源码(htmljs部分) <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>…

PHP和Python脚本的性能监测方案

目录 1. 说明 2. PHP脚本性能监测方案 2.1 安装xdebug 2.2 配置xdebug.ini 2.3 命令行与VS Code中使用 - 命令行 - VS Code 2.4 QCacheGrind 浏览 3. Python脚本性能监测方案 3.1 命令行 4. 工具 5.参考 1. 说明 获取我们的脚本程序运行时的指标&#xff0c;对分析…

【人工智能】10分钟解读-深入浅出大语言模型(LLM)——从ChatGPT到未来AI的演进

文章目录 一、前言二、GPT模型的发展历程2.1 自然语言处理的局限2.2 机器学习的崛起2.3 深度学习的兴起2.3.1 神经网络的训练2.3.2 神经网络面临的挑战 2.4 Transformer的革命性突破2.4.1 Transformer的核心组成2.4.2 Transformer的优势 2.5 GPT模型的诞生与发展2.5.1 GPT的核心…

hive中windows子句的使用

概述 1&#xff0c;windows子句是对窗口的结果做更细粒度的划分 2、windows子句中有两种方式 rows &#xff1a;按照相邻的几行进行开窗 range&#xff1a;按照某个值的范围进行开窗 使用方式 (rows | range) between (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING…

GPT4的下一代Orion已经降速了?

嘿&#xff0c;大家好&#xff0c;我是小索奇&#xff01;说起AI&#xff0c;相信不少人都和我一样&#xff0c;总感觉这玩意儿发展得就像装了火箭&#xff0c;快得让人眼花缭乱。咱们从GPT-3到GPT-4&#xff0c;一路哇哦着过来&#xff0c;天天惊叹它越来越聪明&#xff0c;越…

【LinuxC编程】06 - 守护进程,线程

进程组和会话 概念和特性 进程组&#xff0c;也称之为作业。BSD于1980年前后向Unix中增加的一个新特性。代表一个或多个进程的集合。每个进程都属于一个进程组。在waitpid函数和kill函数的参数中都曾使用到。操作系统设计的进程组的概念&#xff0c;是为了简化对多个进程的管…

探索 Python 图像处理的瑞士军刀:Pillow 库

文章目录 探索 Python 图像处理的瑞士军刀&#xff1a;Pillow 库第一部分&#xff1a;背景介绍第二部分&#xff1a;Pillow库是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;简单的库函数使用方法第五部分&#xff1a;结合场景使用库第…

【数据结构 | C++】字符串关键字的散列映射

字符串关键字的散列映射 给定一系列由大写英文字母组成的字符串关键字和素数P&#xff0c;用移位法定义的散列函数H(Key)将关键字Key中的最后3个字符映射为整数&#xff0c;每个字符占5位&#xff1b;再用除留余数法将整数映射到长度为P的散列表中。 例如将字符串AZDEG插入长…

游戏引擎学习第五天

这节貌似没讲什么 视频参考:https://www.bilibili.com/video/BV1Gmm2Y5EwE/ uint8 *A somewhere in memory; uint8 *B somewhere in memory;//BEFORE WE GOT TO HERE int Y *B; // whatever was actually there before the 5 *A 5; int X *B; // 5 //Obviously! Y and …

Linux——基础指令2 + 权限

目录 1.zip/unzip 2.tar 3.bc 4.uname –r 5.重要的几个热键 6.扩展命令 7.shell命令以及运行原理 8.Linux权限的理解 关于权限的三个问题&#xff1a; 1.目录权限 2.缺省权限 3.粘滞位 1.zip/unzip 打包、压缩&#xff1a;使用特定的算法&#xff0c;文件进行合…

摄像机视频分析软件下载LiteAIServer视频智能分析软件抖动检测的技术实现

在现代社会中&#xff0c;视频监控系统扮演着至关重要的角色&#xff0c;其可靠性和有效性在很大程度上取决于视频质量。然而&#xff0c;由于多种因素&#xff0c;如摄像机安装不当、外部环境振动或视频信号传输的不稳定&#xff0c;视频画面常常出现抖动问题&#xff0c;这不…

Pandas | 数据分析时将特定列转换为数字类型 float64 或 int64的方法

类型转换 传统方法astype使用value_counts统计通过apply替换并使用astype转换 pd.to_numericx对连续变量进行转化⭐参数&#xff1a;返回值&#xff1a;示例代码&#xff1a; isnull不会检查空字符串 数据准备 有一组数据信息如下&#xff0c;其中主要将TotalCharges、MonthlyC…

Fish Agent V0.13B:Fish Audio的语音处理新突破,AI语音助手的未来已来!

近日&#xff0c;Fish Audio公司发布了一款全新的语音处理模型——Fish Agent V0.13B&#xff0c;这款模型以其高效、精确的语音生成和处理能力&#xff0c;尤其是在模拟或克隆不同声音方面的表现&#xff0c;引起了广泛关注。这不仅意味着我们在拥有一个声音自然、反应迅速的A…

稀疏视角CBCT重建的几何感知衰减学习|文献速递-基于深度学习的病灶分割与数据超分辨率

Title 题目 Geometry-Aware Attenuation Learning forSparse-View CBCT Reconstruction 稀疏视角CBCT重建的几何感知衰减学习 01 文献速递介绍 稀疏视角锥形束计算机断层扫描&#xff08;CBCT&#xff09;重建的几何感知学习方法 锥形束计算机断层扫描&#xff08;CBCT&a…

Docker入门系列——Docker-Compose

Docker Compose 是 Docker 官方编排工具&#xff0c;用于定义和运行多容器 Docker 应用程序。它是一个轻量级的工具&#xff0c;用于快速配置和启动应用程序的不同服务。 Docker Compose 是什么 Docker Compose 最初是由 Docker 公司开发&#xff0c;并于 2014 年 6 月首次发布…

[运维][Nginx]Nginx学习(1/5)--Nginx基础

Nginx简介 背景介绍 Nginx一个具有高性能的【HTTP】和【反向代理】的【WEB服务器】&#xff0c;同时也是一个【POP3/SMTP/IMAP代理服务器】&#xff0c;是由伊戈尔赛索耶夫(俄罗斯人)使用C语言编写的&#xff0c;Nginx的第一个版本是2004年10月4号发布的0.1.0版本。另外值得一…

GIN:逼近WL-test的GNN架构

Introduction 在 图卷积网络GCN 中我们已经知道图神经网络在结点分类等任务上的作用&#xff0c;但GIN&#xff08;图同构神经网络&#xff09;给出了一个对于图嵌入&#xff08;graph embedding&#xff09;更强的公式。 GIN&#xff0c;图同构神经网络&#xff0c;致力于解…

ReactPress与WordPress:一场内容管理系统的较量

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress WordPress官网&#xff1a;https://wordpress.org/ ReactPress与WordPress&#xff1a;一场内容管理系统的较量 在当今数字化时代&#xff0c;内容管理系统&#xff08;CMS&#xff09;已成为…