
直接用 Postman 发单个请求是大多数接口调试场景里的日常操作。可一旦变成需要验证 50 个用户的订单状态、给 30 个不同参数的商品详情接口做回归、或者把一批线上数据拿回来重新造数鼠标点到手酸不说还特别容易漏掉中间某一条。这时候真正要用的是 Postman 的批量发送请求能力。这篇文章主要围绕 Postman 批量发送请求的最佳实践来写从数据准备、Collection Runner 参数配置、脚本断言到和 Newman 结合做持续集成把一套完整可复用的批量请求方案讲透。不管你是刚接触接口测试的新人还是已经在用 Postman 但只会一条条手工点的开发按这个流程走一遍都能把日常重复的请求工作交给工具去跑自己只负责看结果、盯异常。1. 批量请求适用的真实场景与核心思路1.1 哪些场景最适合用批量发送请求先说场景不然容易把批量请求用错地方。我自己的经验里批量发送请求最典型的四类场景是接口回归验证接口本身逻辑没变但底层数据库、缓存、鉴权逻辑变了需要把线上真实参数抽一批出来逐个请求一遍确认响应码和关键字段没跑偏。这活儿手工做会崩溃批量跑最省心。测试数据准备比如要造 30 个不同手机号、不同渠道来源的用户记录或者给一批商品批量上架、批量修改价格。这类写代码也能做但用 Postman 的好处是可视化、可留痕跑完还能直接看哪些失败了。接口巡检与健康检查每天早上对核心接口列表跑一遍批量请求检查响应时间、状态码、关键 business code。用 Runner 跑一遍导出报告异常一目了然。压测前的冒烟正式压测之前先用少量数据把链路通一遍。这时候批量请求能确认每个参数组合都能正确打到服务器避免压测时因为参数错误白白烧流量。1.2 批量请求背后的核心思路数据与请求分离批量发送请求和写代码时的“遍历执行”本质上是一回事但 Postman 在这一层的核心设计是数据驱动。你不需要把请求复制几十份只需要准备好一份测试数据文件让同一个请求模板去逐个读取数据并把数据填到对应的变量位置里。打个比方批量发请求就像给一千个收件人发快递。手工操作是一个个手写地址、手填快递单批量操作则是做一张地址清单套用同一个打印模板往打印机里一塞自动出一千张单子。Postman 里这个“地址清单”就是 CSV 或 JSON 数据文件“打印模板”就是录好的 HTTP 请求而“打印机”就是 Collection Runner。理解了这一点整个批量请求的配置逻辑就顺了先整理请求模板再准备数据文件最后跑 Runner 看结果。下面按这个顺序一步步来。2. 动手前先把集合和环境整理干净2.1 集合Collection的整理规范很多人批量跑失败或者跑完结果没法看问题往往不是 Runner 不会用而是集合本身一团乱麻。集合是 Postman 里承载请求的基本容器我建议至少按以下方式整理按业务模块建 Collection比如“用户服务”“订单服务”“支付服务”不要把所有请求塞进一个叫“测试”的集合。请求命名用“模块_接口名_用途”格式例如order_create_正常流程、order_create_参数缺失。批量跑完看结果时名字清不清楚直接决定你定位问题的速度。每个请求写 Description说明这个请求依赖什么前置条件、期望什么返回值。结合 Postman 的文档生成功能团队协作时其他人也能看懂这个请求为什么这么配。用 Folder 做二次分组同一个集合里把正向用例、异常用例、基础数据准备分开存放Runner 可以按 Folder 跑没必要每次都全量跑。这里有一个很实在的教训请求里如果直接写死了 IP、域名、鉴权 token等换一套测试环境就得把所有请求改一遍。正确做法是用变量占位这也是我要说的第二点环境变量的管理。2.2 环境Environment与全局变量的正确用法Postman 里变量有几种层级Global、Environment、Collection、Local。批量请求最常用的是 Environment。Environment 本质上是一组键值对比如{ baseUrl: http://test-api.example.com, token: eyJhbGciOi... }请求 URL 写成{{baseUrl}}/v1/order/detail鉴权 Header 写成Authorization: Bearer {{token}}。切换环境时只需要在右上角下拉框换一个 Environment所有请求自动指向新环境的基础地址和凭证。这样做有两个直接好处第一同一套 Collection 可以在开发环境、测试环境、预发布环境之间无缝切换第二批量跑数据时Environment 里的变量可以被所有迭代的请求共用比如 token 只需要请求前置脚本里设置一次后续所有迭代都能读取。需要注意Global 变量尽量不要存环境相关的东西因为它不随环境切换而变化容易造成“我明明切到测试环境了怎么还请求到开发环境”的诡异问题。Environment 里再细分也要区分哪些是会变的token、验证码、哪些是固定的baseUrl。3. Collection Runner 批量发送请求实操全流程3.1 准备数据文件CSV 和 JSON 怎么选批量请求要“遍历”数据文件是重头戏。Postman 支持 CSV 和 JSON 两种格式实际使用中差别还挺大。CSV 格式适合字段少、结构扁平的数据在 Excel 里可以直接编辑团队里非技术同学也能维护。一个典型的用户批量查询数据文件长这样userId,expectCode 10001,0 10002,0 10003,1004列名就是请求里用的变量名。请求 URL 里写{{baseUrl}}/v1/user/{{userId}}Runner 每次迭代会读取一行把userId替换成对应值。配合断言可以检查返回的 code 是否等于{{expectCode}}。JSON 格式适合数据结构复杂、存在嵌套的场景。比如批量创建订单订单里含有多个商品项[ { orderNo: SO20240101001, customer: 张三, items: [ {sku: A001, qty: 2}, {sku: B002, qty: 1} ] }, { orderNo: SO20240101002, customer: 李四, items: [ {sku: C003, qty: 5} ] } ]JSON 数组里的每个对象对应一次迭代。请求体里可以直接用{{orderNo}}、{{customer}}做替换嵌套数组如果想完整传递需要在 Pre-request Script 里用pm.iterationData.get(items)获取原始对象再塞进请求体这个我后面进阶部分细说。两种格式的取舍我的建议是对比项CSVJSON可读性表格化直观嵌套后稍显复杂嵌套结构不支持支持中文编码需注意 UTF-8 BOM一般无乱码问题适用场景参数少、扁平结构、批量接口回归请求体复杂、需要结构化数据维护门槛低可用 Excel建议直接用 VS Code 等编辑器注意CSV 文件如果是从 Excel 导出的默认编码可能是 ANSI 或 GBKPostman 读取经常乱码。建议用文本编辑器另存为 UTF-8 with BOM 格式再导入。3.2 Collection Runner 面板参数逐项拆解Runner 入口在 Collection 右侧的箭头图标选中集合点“Run”就进入配置页。这个页面参数不多但每个都影响行为我按实践经验逐个说清楚。Iterations迭代次数指定跑多少轮。如果指定了数据文件迭代次数默认等于数据文件行数也允许手动改小但一般不建议改容易漏数据。如果没有数据文件迭代次数就是请求重复执行的次数比如想连发 10 次相同请求看有没有偶发超时可以把次数设成 10。Data File数据文件选择上一步准备的 CSV 或 JSON。选完可以先点 Preview 看一下 Postman 解析出来的字段是否正确这一步非常关键可以避免跑完才发现变量没替换上。Delay请求延迟两轮迭代之间的间隔时间单位毫秒。这个参数在请求目标服务器有频控、或者接口之间有依赖比如创建订单后立刻查询但数据库同步有延迟时特别有用。我平时做回归会设 200ms 左右避免对测试环境造成过大压力。Log Responses响应日志可以选记录所有响应、只记录失败响应或者不记录。批量数据量大的时候全量记录会导致 Runner 结果页面加载很慢建议选“Failed Responses Only”只看失败的。Save Responses保存响应体默认会把每次请求的响应体保存下来方便跑完回看。如果只是巡检状态码可以关掉节省内存和导出报告体积。Stop on error报错即停勾选后如果某个迭代断言失败Runner 会中断。我默认不勾。批量跑的目的就是要一次性暴露所有问题而不是遇到一个错就停那样反而要反复跑好几轮。只有调试阶段排查单个问题时才会开。配置完成后点“Run 集合名”会弹出跑批进度页可以看到当前跑到第几条、每条的状态和耗时。跑完进入结果面板先看概览Total总迭代数Passed断言通过数Failed断言失败数平均响应时间Response 列表里可以点开任意一条看请求头、请求体、响应体和断言结果和平时单请求调试一样。3.3 跑完结果怎么看指标含义与报告导出Runner 结果页最容易被忽略的是右上角的“Export Results”按钮。Postman 可以导出 JSON 格式的运行报告里面记录了每次迭代的请求信息、响应信息、断言结果、消耗时间。为什么强调要导出因为 Runner 界面上看单条结果没问题但你要统计“100 条用例里失败率是多少”“哪个接口平均响应时间最长”界面给不了聚合视角。把 JSON 报告拿下来用脚本或者导入到报表工具里可以快速做二次分析。更工程化的做法是安装 Newman直接用命令行生成 Junit XML 报告Jenkins 或 GitLab CI 都能直接识别这个放到后面第 4 章展开。这里分享一个我常用的报告分析思路导出 JSON 后优先关注“断言失败”和“响应时间超过阈值”两类记录而不是对所有 Success 条目逐一过目。批量请求的意义是让你把目光聚焦在异常上而不是淹没在大量正常数据里。4. 把批量请求玩出花脚本、断言与工程化4.1 用 Pre-request Script 和 Tests 处理动态数据真实接口场景很少是“数据文件里写死什么就提交什么”往往需要在请求发出前生成时间戳、随机字符串、签名参数字段等。这些可以通过 Postman 的脚本能力在请求前后动态处理。**Pre-request Script请求前脚本**在请求发出前执行适合生成动态参数。比如批量创建订单时要求订单号唯一不能在数据文件里写死可以用const timestamp Date.now(); const randomStr Math.random().toString(36).slice(2, 8); pm.variables.set(dynamicOrderNo, SO timestamp randomStr);然后在请求体里写orderNo: {{dynamicOrderNo}}。这样每轮迭代都会生成一个不同的订单号。**Tests请求后脚本**在收到响应后执行适合做断言和提取后续需要的数据。最基本的断言pm.test(状态码为 200, () { pm.response.to.have.status(200); }); pm.test(业务码为 0, () { const jsonData pm.response.json(); pm.expect(jsonData.code).to.eql(0); }); pm.test(响应时间小于 1000ms, () { pm.expect(pm.response.responseTime).to.be.below(1000); });断言越多批量跑完后你能掌握的信息越立体。只校验状态码会漏掉很多业务异常因为很多接口哪怕业务失败也返回 HTTP 200只在响应体里给一个错误码。4.2 迭代间数据传递如何处理接口依赖批量请求最麻烦的场景是接口之间存在依赖。比如先批量创建订单再批量查询这些订单的状态。两种常见做法做法一把查询需要的数据预先生成好放进数据文件。这个最简单但只适用于“数据已经是现成的”场景。做法二用 Environment 变量在请求之间传递。比如创建订单接口的 Tests 脚本里提取响应中的 orderNo 并保存到环境变量const jsonData pm.response.json(); pm.environment.set(latestOrderNo, jsonData.data.orderNo);查询订单接口的 URL 写成{{baseUrl}}/v1/order/{{latestOrderNo}}。这样几轮迭代执行时会按照集合里请求的排列顺序先跑创建再把创建出来的订单号交给查询接口。需要确认一下这种方法拿到的实际上只是上一轮设置的环境变量值对于“每个迭代都相互独立”的场景没问题但如果同一个迭代内的多个请求之间有依赖也可以在请求间传递。还有一种更可控的方式是直接在 Pre-request Script 里读取迭代数据并动态赋值const currentItems pm.iterationData.get(items); pm.variables.set(requestBody, JSON.stringify(currentItems));请求体里引用{{requestBody}}可以处理复杂嵌套数据。4.3 与 Newman 结合批量请求的持续集成玩法Postman 图形界面适合日常调试和小规模跑批数据上千条时 UI 就有点吃力。更稳的做法是把 Collection 和 Environment 导出成文件交给 Newman 在命令行里执行。导出方式点击 Collection 右边的三个点选 Export得到 collection.jsonEnvironment 同理导出。然后在命令行执行newman run collection.json \ -e environment.json \ -d data.csv \ --delay-request 200 \ --reporters cli,junit \ --reporter-junit-export results.xml几个参数含义直接说-d指定数据文件--delay-request等价于 Runner 里的 Delay--reporters指定输出格式junit 是 CI 平台通用的报告格式。跑完打开 results.xml里面每条用例、每个断言的通过失败情况都很清楚。把这个命令嵌入到 CI 流水线里可以做到每次代码合并后自动跑一轮接口回归。这一步才是“批量发送请求最佳实践”的最终形态从人工在 GUI 里点 Run变成流水线自动触发、结果自动归档。5. 常见问题与排查技巧实录5.1 CSV 文件中文乱码和数据行对不上这是最频繁踩的坑。CSV 文件在 Excel 里改了保存拿到 Postman 里读取时中文字段变成乱码或者最后一行数据读不出来。排查思路先看数据文件编码。用 VS Code 或 Notepad 打开看右下角编码格式。不是 UTF-8 的话另存为 UTF-8 with BOM。还有一个隐蔽问题CSV 文件里字段值本身就包含逗号或换行比如备注字段里写了 “你好,世界”会导致 Postman 解析列错位。解决办法是导出 CSV 时对包含特殊字符的字段加双引号或者干脆用 JSON 格式保存这类数据。我的习惯是凡是涉及中文长文本或特殊字符一律用 JSON 数据文件省心。5.2 请求里变量变成字符串“{{userId}}”原样发送如果 Runner 跑完之后服务端收到的参数是字面量{{userId}}说明变量没有被替换成功。常见原因有三个变量名拼写和数据文件列名不一致Postman 是精确匹配userid和userId是两回事。变量在请求体里被引号包住但 JS 脚本里又用字符串拼接处理了一遍导致替换时匹配上的是转义后的文本。变量不在当前作用域内比如数据文件里的变量应该用{{变量名}}直接引用脚本里读则用pm.iterationData.get(变量名)如果用了pm.variables.get()去取拿到的可能是空值。排查办法先在 Runner 配置页点 Data File 旁边的 Preview确认解析出来的字段名、值都是对的再在请求前脚本里加一行console.log(pm.iterationData.get(userId))发送后在 Postman 控制台看实际值。5.3 迭代次数和数据文件行数不一致Postman 的规则是指定了数据文件后迭代次数默认等于数据文件行数手动改了 Iterations 为更大值多出来的迭代会复用最后一行数据。这不是 bug但很容易让测试结果产生“重复数据干扰”的假象。比如造数场景里你以为跑了 10 条不同数据实际后 2 条是重复的等于创建了重复订单。所以我的习惯是准备了 N 行数据就把 Iterations 显式设为 N并且勾选 Runner 里“Data File 行数超过迭代次数时自动截断”之类的行为或者不设置 Data File 的情况下才手动指定迭代次数。5.4 断言失败定位困难批量几十条数据里失败了两三条点开失败项看到断言消息是“expected 200 to be 500”但这个请求用的什么参数、哪个环境、哪一轮迭代界面上没直接显示。我常用的做法是在 Tests 脚本里把关键信息拼进断言消息或者直接用console.log输出const requestBody JSON.parse(pm.request.body.raw); console.log(当前请求参数, requestBody.orderNo); pm.test(业务码为 0当前订单 requestBody.orderNo, () { const jsonData pm.response.json(); pm.expect(jsonData.code).to.eql(0); });这样断言失败列表里直接能看到是哪条订单数据有问题不用再猜。还有一个习惯是给每个请求加自定义 Header比如X-Case-Name批量跑的时候后端日志里也能对得上这条请求来自哪个用例。5.5 接口响应太慢拖垮整个跑批如果批量请求的文件里有几个慢接口比如导入导出类接口要几十秒而其他接口正常Runner 会等每个请求完成后再进入下一轮几个慢请求就把整个批次拖得很长。两种处理方式一是给 Runner 设置合理的 Delay 反而没用这里应该做的是把慢接口单独拆成一个 Collection 或 Folder 单独跑避免和普通接口混跑二是在接口脚本层面考虑如果响应时间本身就是被测指标建议在断言里设置最长响应时间阈值快速标记出慢请求而不是干等所有数据跑完。注意Postman 本身没有全局“请求超时时间”的直接配置项超时逻辑更多依赖被调接口的表现。遇到长时间挂起的请求可以在 Newman 层面配合超时参数做整体控制避免 CI 卡死。写在最后的实操体会我自己的日常工作流里凡是超过 5 条数据的请求验证基本不会在 Postman 里一条条手点一律走批量。做得多了慢慢总结出几个让批量请求真正省心的习惯第一数据文件永远和 Collection 放一起做版本管理不管是 Git 还是网盘确保所有人用的是同一份数据而不是各改各的。第二批量跑之前先跑一次小样本数据确认变量替换、断言行为都对再放全量数据进去避免几十分钟跑完发现第一步就错了。第三善用 Newman 的 junit 报告把批量请求的结果接入到现有的 CI 流程里这样每次代码变更都会自动知道接口有没有被改挂。批量发送请求这个能力看上去只是 Collection Runner 一个按钮的事但真正把它用好涉及到数据准备、变量管理、脚本断言、结果分析、CI 集成这一整条链路。一次性把这套链路搭好后面每次批量跑请求都只是换一个数据文件的事。