如何用Postman实现跨多请求的接口限流功能测试?
Postman接口限流测试问题及解决方案
问题描述
一直用Postman做单请求结果测试,现在需要验证接口限流逻辑是否正常,预期测试流程如下:
- Request 1 → 响应状态码200
- Request 2 → 响应状态码200
- Request 3 → 响应状态码429
- 延迟1分钟
- Request 4 → 响应状态码200
编写了JS脚本但未达到预期效果:
pm.test("Rate limiter test", function () { OkTest(); setTimeout(OkTest, 10); setTimeout(TooManyRequestsTest, 10); setTimeout(OkTest, 5000); }); pm.test("Rate fail limiter test", function () { OkTest(); setTimeout(OkTest, 10); setTimeout(OkTest, 10); setTimeout(OkTest, 5000); }); function OkTest() { pm.sendRequest(pm.request.url, function (err, res) { tests['status code should be 200']= res.code ===200; }); } function TooManyRequestsTest() { pm.sendRequest(pm.request.url, function (err, res) { tests['status code should be 429']= res.code ===429; }); }
接口配置为5秒内最多允许2个请求,手动快速调用时第3个请求确实返回429,但上述脚本运行后所有测试均显示通过,未达到预期的失败效果。
问题原因
- 异步执行导致测试未等待结果:
setTimeout是异步操作,Postman的测试函数会直接执行完毕,不会等待setTimeout内的请求和断言完成,因此异步回调里的断言不会被正确统计到测试结果中。 - 请求顺序与延迟逻辑失效:多个
setTimeout设置相同延迟(10ms)会导致请求几乎同时发送,无法保证严格的执行顺序;同时旧版的tests对象断言方式,在异步场景下无法被Postman正确捕获。
解决方案
使用async/await结合Promise封装请求和延迟逻辑,确保请求按顺序执行,且每个断言都能被Postman正确识别:
// 封装请求并验证状态码,返回Promise function sendRequestCheckStatus(expectedStatus) { return new Promise((resolve, reject) => { pm.sendRequest(pm.request.url, (err, res) => { if (err) { reject(err); return; } // 用pm.test包裹断言,确保结果显示在测试报告中 pm.test(`状态码应为 ${expectedStatus}`, () => { pm.expect(res.code).to.eql(expectedStatus); }); resolve(); }); }); } // 封装延迟函数,返回Promise function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 主测试流程,使用async/await确保顺序执行 pm.test("完整限流逻辑测试", async () => { // 第1个请求,预期200 await sendRequestCheckStatus(200); // 第2个请求,预期200 await sendRequestCheckStatus(200); // 第3个请求,预期429 await sendRequestCheckStatus(429); // 延迟1分钟(60000毫秒),等待限流重置 await delay(60000); // 第4个请求,预期200 await sendRequestCheckStatus(200); });
说明
async/await确保每个请求完成后再执行下一个,严格遵循测试流程顺序;- 每个请求的状态验证都通过
pm.test定义,结果会直接显示在Postman的测试报告中; - 延迟函数
delay保证等待限流重置后再发送后续请求,符合测试预期。
内容的提问来源于stack exchange,提问作者FoxHound
相关产品推荐
相关产品推荐

