十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Postman并发测试实战:从参数化到Newman实现API压力测试

Postman并发测试实战:从参数化到Newman实现API压力测试 1. 从单次请求到并发压测Postman的进阶玩法很多刚开始接触接口测试的朋友对Postman的印象可能还停留在“一个用来发发HTTP请求的漂亮工具”上。点点按钮看看返回的JSON数据检查一下状态码是不是200这大概就是日常操作了。确实在单接口调试和手动测试的场景下Postman凭借其直观的界面和强大的功能几乎成了开发者和测试人员的标配。但如果你以为Postman只能干这些那就太小看它了。当你的服务需要评估性能或者你想知道自己的API在同时被多个用户访问时会不会“扛不住”手动一个个点请求显然是行不通的。这时候“并发测试”就成了一个硬性需求。你可能听说过JMeter、LoadRunner这些专业的压测工具它们功能强大但学习曲线陡峭配置起来也相对复杂。而Postman其实就内置了进行基础并发测试的能力——通过它的“Collection Runner”集合运行器和更强大的“Newman”命令行工具。简单来说用Postman做并发测试核心思路就是把一组接口请求一个Collection准备好然后让Postman自动、同时地发送大量请求以此来模拟多用户并发访问的场景。你可以观察响应时间、成功率等指标从而对接口的性能和稳定性有一个初步的判断。这对于开发阶段的性能自查、上线前的压力摸底或者日常的监控脚本编写都是一个非常轻量且高效的方案。接下来我就结合自己多次用Postman做压力验证的经验带你一步步解锁这个进阶功能。2. 并发测试前的核心准备工作构建可压测的请求集合在开始让Postman“疯狂”发送请求之前我们必须把“弹药”准备好。这个弹药就是一个精心构建的请求集合Collection。这里的准备工作直接决定了并发测试的有效性和真实性绝不是简单地把几个请求丢进去就行。2.1 创建与组织测试集合首先你需要为你的并发测试场景创建一个专门的Collection。在Postman中点击“New” - “Collection”给它起个清晰的名字比如“用户登录并发压测”。我建议为每一个明确的压测场景创建独立的Collection避免不同场景的请求互相干扰也便于管理。接下来将需要测试的接口请求添加到这个Collection中。这里有一个关键点并发测试通常针对一个或少数几个核心接口而不是一次性跑完整个业务流程。例如如果你测试的是一个电商系统那么“提交订单”接口的并发能力可能比“浏览商品”接口更重要。你应该优先把这些高价值、高压力、核心业务逻辑的接口纳入测试。2.2 实现请求的动态化与参数化这是准备工作中最重要的一环。在真实的并发场景下每个虚拟用户VU发出的请求参数应该是不同的否则所有请求都一模一样不仅会触发服务器的缓存机制导致测试结果失真还可能因为数据冲突如重复用户名而大量失败。Postman提供了强大的参数化功能主要依靠环境变量Environment Variables、集合变量Collection Variables以及外部数据文件CSV/JSON。1. 使用动态变量Postman内置了丰富的动态变量可以在请求的URL、Header、Body中通过双花括号引用例如{{$timestamp}}当前时间戳、{{$randomInt}}随机整数。这对于生成唯一的订单号、随机的查询参数非常有用。2. 创建自定义环境/集合变量对于更复杂的参数比如一组不同的用户名、密码、商品ID你可以预先定义它们。集合变量适用于该集合内所有请求共享的常量如基础URL{{base_url}}。环境变量适用于不同测试环境如测试、预生产的配置切换。在并发测试中我们可以巧妙利用它来为不同的迭代虚拟用户赋予不同的值。但更推荐下面的数据文件方式。3. 通过数据文件驱动推荐用于并发这是实现参数化最有效的方式。你可以创建一个CSV或JSON文件每一行代表一个虚拟用户或一次请求的数据。CSV文件示例 (test_data.csv)username,password,product_id user1,pass123,1001 user2,pass456,1002 test_user,test_pass,1003在请求中引用在请求的Body如raw JSON中你可以这样写{ username: {{username}}, password: {{password}}, itemId: {{product_id}} }在Collection Runner中运行这个集合时导入这个CSV文件Postman就会按顺序或随机使用文件中的每一行数据来替换变量从而实现每次请求参数的差异化。实操心得数据文件中的密码等敏感信息可以使用Postman的“预请求脚本”Pre-request Script进行动态加密如MD5、SHA256。例如在Pre-request Script中写pm.variables.set(hashed_pwd, md5(pm.iterationData.get(password)))然后在Body中使用{{hashed_pwd}}。这样数据文件本身可以不存明文更安全。2.3 编写验证脚本断言与指标收集发送请求只是第一步我们还需要判断请求是否成功并收集性能数据。这就要用到Postman的“Tests”脚本标签页。断言Assertions在“Tests”中你可以用JavaScript编写断言来验证响应。常用的内置断言有// 检查状态码为200 pm.test(Status code is 200, function () { pm.response.to.have.status(200); }); // 检查响应体包含特定字符串 pm.test(Body contains success token, function () { pm.expect(pm.response.text()).to.include(success); }); // 检查JSON响应中的某个字段值 pm.test(Response has correct user id, function () { var jsonData pm.response.json(); pm.expect(jsonData.userId).to.eql(pm.iterationData.get(expected_user_id)); // 与数据文件中的值对比 });并发测试中断言能快速帮你统计出失败请求的数量和原因。收集性能指标“Tests”脚本还可以用来捕获关键的性能数据并将其保存到变量中供后续查看或导出。// 记录响应时间 var responseTime pm.response.responseTime; pm.environment.set(response_time_ pm.info.iteration, responseTime); // 按迭代存储 // 你也可以计算并记录一些统计信息但更复杂的分析建议导出结果后处理 console.log(Iteration pm.info.iteration response time: responseTime ms);踩坑提醒断言脚本不宜过于复杂或耗时过长因为它会在每次请求响应后执行占用时间。复杂的断言可能会影响你对真实接口响应时间的判断。通常只做最核心的业务正确性校验即可。3. 在Postman图形界面中发起并发测试对于小规模、快速的并发验证直接使用Postman自带的Collection Runner就足够了。它的优势是直观、无需编码适合开发自测或测试人员快速验证。3.1 配置Collection Runner在Postman侧边栏选中你准备好的Collection点击“Run”按钮。这会打开Collection Runner界面。你需要关注以下几个关键配置区域Iterations迭代次数这是并发数吗不是这是每个请求或整个集合顺序执行的次数。比如你集合里有2个请求设置Iterations5那么它会顺序执行“请求1 - 请求2”这个流程一共5遍。Delay延迟每次迭代之间的间隔时间。在并发测试中我们通常将其设置为0以最大化请求发送速度。Data数据文件点击“Select File”上传你准备好的CSV或JSON数据文件。这是实现参数化的关键。Data File Type Format确保文件类型和格式设置正确。“Keep variable values”一般取消勾选确保每次迭代都使用数据文件中的新值。“Run collection without using stored cookies”建议勾选让每次迭代都从一个干净的会话开始。3.2 理解“并发”的模拟与局限性看到这里你可能发现了Collection Runner的界面上并没有一个直接的“并发用户数”Concurrent Users设置。这是因为Postman的图形界面本身并不真正支持严格意义上的并行Parallel请求执行。它的“Run”本质上是串行Sequential但快速迭代。当你设置Iterations100 Delay0时Postman会以尽可能快的速度一个接一个地执行100次迭代。由于速度很快对于后端服务来说这些请求在极短的时间内接踵而至形成了一种“准并发”的压力。这对于测试接口在快速连续请求下的表现如数据库连接池压力、短时流量突增是有效的但它无法精确模拟“N个用户在同一毫秒同时发起请求”的场景。那么如何用Collection Runner逼近并发效果呢一种变通方法是在你的Collection中为同一个接口创建多个相同的请求例如复制粘贴5次“登录请求”将它们放在集合里。然后设置一个较小的迭代次数。这样在一次迭代中这5个请求会被依次快速执行。由于网络IO的异步性它们在一定程度上会重叠形成并发的效果。但这是一种粗糙的模拟可控性和精确度都不高。经验之谈图形界面的Collection Runner更适合用于功能回归测试和低压力下的稳定性验证。如果你需要做严肃的、可控的并发性能测试比如模拟100个用户同时登录图形界面就不是最佳选择了。这时我们需要请出Postman的命令行兄弟——Newman。4. 使用Newman进行命令行并发压测Newman是Postman的命令行集合运行工具。它的强大之处在于可以轻松集成到CI/CD流程中并且通过一些额外的Node.js库我们可以实现真正意义上的、可控的并发测试。4.1 Newman基础安装与运行首先你需要安装Node.js和npm。然后通过npm全局安装Newmannpm install -g newman安装完成后最基本的运行命令是newman run YourCollection.json但这仍然是串行执行。Newman本身可以通过-n参数指定迭代次数但同样是串行的。4.2 实现真正的并发newman-reporter-concurrent为了实现并发社区提供了很多优秀的方案。我个人常用的是结合newman-reporter-concurrent这个自定义报告器虽然它叫reporter但核心功能是控制并发。不过更直接和灵活的方式是使用Node.js的异步控制库自己编写一个小脚本。下面是一个使用async库和newman的Node.js脚本示例它可以启动指定数量的并发任务每个任务独立运行一次集合迭代创建项目目录并初始化mkdir postman-concurrent-test cd postman-concurrent-test npm init -y npm install async newman编写并发测试脚本 (concurrent_test.js)const async require(async); const newman require(newman); // 你的Collection文件路径需先从Postman导出 const collection require(./path/to/your/Collection.json); // 你的环境变量文件路径可选 const environment require(./path/to/your/Environment.json); // 你的数据文件路径可选 const iterationData ./path/to/your/test_data.csv; // 定义并发数量 const concurrency 10; // 模拟10个并发用户 // 定义一个任务函数每个任务运行一次newman function runCollectionIteration(callback) { newman.run({ collection: collection, environment: environment, // 可选 iterationData: iterationData, // 可选Newman会自动为每个任务分配不同数据行 reporters: cli, // 在命令行输出结果 // 可以添加更多newman配置如全局变量、超时时间等 }, function (err, summary) { // 每个任务完成后回调 callback(err, summary); }); } // 使用async的parallelLimit控制并发数 console.log(开始并发测试并发数: ${concurrency}); async.parallelLimit( // 创建一个包含N个相同任务的数组N并发数*每个用户执行次数 // 这里每个并发用户只执行1次创建10个任务 Array.from({ length: concurrency }, (_, i) runCollectionIteration), concurrency, // 并发限制 function (err, results) { if (err) { console.error(并发测试执行出错:, err); return; } console.log(所有 ${concurrency} 个并发任务执行完毕。); // 这里可以汇总结果例如计算平均响应时间、成功率等 let totalTests 0; let testsPassed 0; results.forEach(summary { if (summary summary.run summary.run.stats) { totalTests summary.run.stats.tests.total; testsPassed summary.run.stats.tests.passed; } }); console.log(总断言数: ${totalTests}, 通过数: ${testsPassed}, 通过率: ${((testsPassed/totalTests)*100).toFixed(2)}%); } );运行脚本node concurrent_test.js这个脚本会同时启动10个Node.js进程受parallelLimit控制每个进程独立运行一次Postman集合从而模拟10个用户同时操作。4.3 参数化与数据隔离的关键在上面的脚本中我们使用了iterationData。Newman在处理数据文件时默认会为每一次集合运行分配数据文件中的一行。在我们的并发脚本中每个runCollectionIteration任务都是一次独立的集合运行因此Newman会自动为它们分配不同的数据行完美实现了并发用户间的数据隔离。如果你需要每个虚拟用户执行多次迭代比如模拟一个用户连续操作可以在newman.run配置中设置iterationCount并在数据文件中为每个用户准备多行数据或者使用脚本动态生成数据。高级技巧对于更复杂的场景比如模拟用户思考时间Think Time、不同用户的权重比例一部分用户只浏览一部分用户下单单纯的并发脚本就不够了。这时可以考虑使用专业的压测工具如k6、Locust或者使用更复杂的Node.js工作流库如Bull。但对于API层面的基础并发压力测试上述Newman方案已经非常实用。5. 结果分析与性能指标解读测试跑完了命令行刷过一堆日志或者Collection Runner里看到了很多绿勾红叉然后呢看懂结果并从中发现问题才是测试的最终目的。5.1 主要性能指标关注点响应时间Response Time平均值整体性能的粗略体现但容易被极端值拉偏。中位数P5050%的请求在这个时间内完成更能代表“典型”用户体验。P95/P99分位值这是关键95%或99%的请求完成时间。它反映了接口的尾部延迟。比如P991200ms意味着最慢的1%的请求耗时超过了1.2秒。这个指标对于评估服务稳定性至关重要少数慢请求可能拖垮整个用户体验。在Postman Runner的结果页你可以看到每次请求的响应时间。在Newman的CLI报告或使用HTML报告器如newman-reporter-html时也能看到统计信息。请求成功率Pass Rate通过断言Tests来判断业务成功与否。成功率 通过的断言数 / 总断言数* 100%。并发测试中我们要求成功率通常接近100%。任何下降都意味着在高压力下出现了功能问题如竞争条件、数据错误或系统错误如超时、5xx错误。错误类型与日志网络错误如连接超时Timeout、连接被拒绝Connection refused。这往往意味着服务器或网络已经不堪重负。HTTP状态码错误4xx如400 429客户端错误。429表示“请求过多”是服务端限流生效的直接信号。5xx如500 502 503服务端错误。这是系统出现问题的明确警报需要结合服务器日志排查。断言失败业务逻辑错误。比如在高并发下扣减库存出现了超卖数量为负或者返回了非预期的数据。5.2 使用报告器增强结果可读性Newman支持多种报告器可以将结果输出为更易读的格式。HTML报告生成一个直观的网页报告包含统计图表。npm install -g newman-reporter-html newman run collection.json -e environment.json -d data.csv -r html --reporter-html-export report.htmlJSON报告便于用其他工具如Python, Excel进行二次分析和可视化。newman run collection.json -r json --reporter-json-export report.json5.3 常见并发问题模式与排查思路当你发现并发测试结果不理想时可以沿着以下思路排查响应时间随并发数增长而线性飙升可能原因应用服务器或数据库的某个环节存在同步锁或串行瓶颈。例如一个全局锁、一个未做缓存的热点数据库查询、或者线程池配置过小。排查方向检查服务器监控CPU、内存、线程状态、数据库慢查询日志、应用日志中是否有等待Wait信息。成功率在达到某个并发阈值后骤降可能原因达到了系统某个资源的硬性上限。如数据库连接池耗尽、服务器文件描述符File Descriptor用尽、内存溢出OOM。排查方向观察系统监控在成功率下降的时间点资源使用率连接数、内存是否达到峰值。检查应用和中间件的配置参数。出现大量4xx错误特别是429可能原因触发了服务端或网关的限流Rate Limiting策略。排查方向确认系统是否配置了限流。如果是评估当前限流阈值是否合理。测试的目的之一就是找到这个阈值。出现数据不一致断言失败可能原因典型的并发安全问题。比如库存超卖、重复下单、用户余额错误。排查方向检查相关业务代码特别是对共享数据数据库行的“读取-修改-写入”操作是否使用了事务Transaction并设置了正确的隔离级别或者是否采用了分布式锁、乐观锁如版本号等机制。踩坑实录曾经测试一个优惠券领取接口在低并发下一切正常。当并发数提高到50时开始出现“优惠券已领完”的断言失败但数据库查询显示券并未真正领完。最终排查发现是业务逻辑中“检查剩余数量”和“更新领取记录”两个操作不是原子性的中间存在时间窗口导致并发请求都认为还有券可领发生了超发。解决方案是在SQL更新语句中使用quantity quantity - 1 WHERE quantity 0这种原子操作或者使用分布式锁。6. 将并发测试融入持续集成流程单次的手动并发测试有价值但将其自动化并纳入CI/CD持续集成/持续部署流水线才能形成持续的性能守护。这样每次代码变更或上线前都能自动进行一次性能回归测试防止性能退化。6.1 基于Newman的CI流水线配置以最常用的Jenkins为例你可以在Pipeline脚本中增加一个性能测试阶段pipeline { agent any stages { stage(Build) { steps { // 你的编译构建步骤 } } stage(API Performance Test) { steps { script { // 1. 确保环境有Node.js和newman sh node --version sh npm list -g newman || npm install -g newman newman-reporter-html // 2. 运行并发测试脚本假设我们使用前面编写的Node.js脚本 sh node ./scripts/concurrent_test.js // 或者直接使用newman运行但注意这是串行迭代 // sh newman run ./postman/collection.json -e ./postman/env_ci.json -d ./postman/data.csv -r cli,html --reporter-html-export ./reports/perf_report.html // 3. 可选归档测试报告 archiveArtifacts artifacts: reports/*.html, fingerprint: true } } post { always { // 无论成功失败都发布HTML报告 publishHTML(target: [ reportName: Postman Performance Report, reportDir: reports, reportFiles: perf_report.html, keepAll: true, allowMissing: false ]) } failure { // 如果测试失败如断言通过率低于阈值可以发送通知 emailext body: API性能测试失败请检查构建日志和报告。, subject: 【告警】${JOB_NAME} - 性能测试失败 (#${BUILD_NUMBER}), to: teamexample.com } } } stage(Deploy) { // 性能测试通过后才部署 steps { // 你的部署步骤 } } } }6.2 设定质量门禁与告警自动化测试必须有明确的通过标准否则失败了也没人关心。定义性能基线Baseline在系统性能良好的时候运行一次并发测试记录下关键的P95响应时间、成功率等指标作为基线。在CI脚本中增加断言修改你的并发测试脚本或在新曼运行后增加分析步骤。例如在Node.js脚本的最终回调里// ... 汇总results后 ... const avgResponseTime calculateAverage(results); const successRate testsPassed / totalTests; // 质量门禁 const BASELINE_P95 500; // 基线P95响应时间500ms const MIN_SUCCESS_RATE 0.99; // 最低成功率99% if (currentP95 BASELINE_P95 * 1.2) { // 如果当前P95比基线恶化超过20% console.error(性能退化P95响应时间 ${currentP95}ms 超过阈值 ${BASELINE_P95*1.2}ms); process.exit(1); // 非零退出码会让CI任务标记为失败 } if (successRate MIN_SUCCESS_RATE) { console.error(成功率不达标${successRate} 低于阈值 ${MIN_SUCCESS_RATE}); process.exit(1); }集成监控告警将Newman输出的结果如平均响应时间通过脚本提取出来发送到你的监控系统如Prometheus, Datadog中这样就能在仪表盘上看到性能趋势并设置告警规则如响应时间连续5分钟高于阈值。6.3 测试环境与数据管理CI中的自动化并发测试对测试环境和数据提出了更高要求环境隔离必须有一个专用于性能测试的稳定环境其配置应尽可能接近生产环境尤其是数据库、缓存、中间件版本和配置。数据可重复性每次测试前需要将数据库恢复到某个已知的快照状态确保每次测试的起点一致。可以使用数据库备份还原或通过脚本初始化测试数据。数据清理测试后要能清理测试过程中产生的脏数据避免影响下次测试。通常会在测试集合的“Tests”脚本最后或CI的post阶段调用专门的清理接口。将Postman并发测试自动化并融入CI/CD是从“偶尔做一下”到“持续守护质量”的关键一步。它让性能问题在早期就能暴露出来修复成本远低于在生产环境发现后再救火。
返回列表