用 Bruno 十分钟搞定跨时区 API 时间测试:脚本与环境变量实战
【免费下载链接】brunoOpensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)项目地址: https://gitcode.com/GitHub_Trending/br/bruno
当你要为一个部署在多个地区的服务写时间戳校验用例时,Bruno 的脚本(写在请求前后的 JavaScript 代码,请求发出前或收到响应后自动执行)配合环境变量(可插值的命名变量,用{{ $变量名 }}语法引用)能帮你把时间基准统一到同一口径,不用手工换算时区。
这个场景卡在哪
不同机器、不同地区的 API 返回的时间字段格式和时区不一致,直接断言容易误报。服务器时间漂移、夏令时偏移这类问题,靠人眼核对很难发现。Bruno 的解法是:把时间生成放进请求前的脚本,把时间校验放进响应后的脚本,阈值放进环境文件,三件事各归其位。
能力盘点
| 能力 | 解决的问题 |
|---|---|
| 请求前脚本 | 在发请求前统一生成时间戳,保证参数与断言用同一个值 |
响应对象res | 拿到responseTime、body、状态码,支撑时间类断言 |
| 环境变量 | 存放各环境的时间容差、基准值,切换环境即可切换口径 |
请求前脚本与响应脚本的运行时上下文由 packages/bruno-js/src/runtime/script-runtime.js 注入,res对象的字段定义见 packages/bruno-js/src/bruno-response.js,其中responseTime单位为毫秒。
照着做
请求前注入时间戳
目标:让 URL 参数和后续断言共用同一个时间戳,避免两处各取一次Date.now()产生毫秒差。
在请求的 Script 页签 Pre-request 区域写入,把当前毫秒时间戳存为环境变量requestTime,请求地址里再引用它:
# Pre-request 脚本 bru.setEnvVar("requestTime", String(Date.now())); # URL 参数(示例) GET /echo?timestamp={{ $requestTime }}&iso={{ $requestTimeISO }}bru.setEnvVar会写入当前环境的作用域(实现见 packages/bruno-js/src/bru.js),{{ $requestTime }}由插值引擎在发送前替换。请求发出后,参数里就是确定的时间值,可以在日志里直接看到。
响应后校验服务器时间
目标:自动判定服务器返回的时间与本地基准的偏差是否在容差内。
在 Script 页签 Tests 区域写入断言。这段代码从响应体取出服务器时间,与本地时间比较,偏差超过 5 秒则失败:
# Tests 脚本 const serverTime = new Date(res.body.serverTime).getTime(); const drift = Math.abs(serverTime - Date.now()); const limit = Number(bru.getEnvVar("timeDriftLimit")) || 5000; test("服务器时间漂移在容差内", () => { expect(drift).to.be.lessThan(limit); });test()和expect()由测试运行时注入,结果记录逻辑见 packages/bruno-js/src/test.js。执行后请求底部会列出每条断言的通过/失败状态,失败时附带实际值,不用打开控制台翻日志。
响应耗时与多环境容差
目标:把时间相关的阈值从脚本里挪到环境文件,不同地区环境各设各的容差。
在environments/下为各环境准备文件(JSON 或 YAML 格式均可,仓库测试里两种都有用例):
{ "name": "shanghai", "variables": [ { "name": "timeDriftLimit", "value": "5000" }, { "name": "timezone", "value": "Asia/Shanghai" } ] }切换环境后,上一段脚本里的limit自动取到当前环境的值。另外res.responseTime返回毫秒级响应耗时(不是时间戳),可直接加一条expect(res.responseTime).to.be.lessThan(2000)的断言,把"时间字段对不对"和"服务慢不慢"分开验证。
容易踩的坑
- 手写
+8*3600*1000这类固定偏移:现象是夏令时期间断言忽对忽错;原因是固定偏移不随夏令时变化;解决办法是用Intl.DateTimeFormat的timeZone选项传 IANA 时区名(如Asia/Tokyo),让运行时自己做转换。 - 把
responseTime当时间戳用:现象是断言出天文数字;原因是它只表示本次请求花掉的毫秒数,与绝对时间无关;解决办法是断言服务器时间用res.body里的时间字段,测快慢才用它。 - 容差设得太小:现象是弱网环境下偶发失败;原因是网络往返本身就有几百毫秒抖动,再加两端时钟不同步;解决办法是把
timeDriftLimit放到环境变量,按环境设 3~10 秒,而不是写死在脚本里。
动手前检查清单
- 确认 API 返回的时间字段是 ISO 8601 还是毫秒时间戳,脚本里解析方式一致
- Pre-request 脚本只生成一次时间戳,URL 与断言都引用
{{ $requestTime }} timeDriftLimit已写入对应环境文件,而不是硬编码在脚本里- 用切换环境功能分别验证过至少两个时区环境
- 集合目录已纳入 Git,环境文件变更可追溯
按上面的结构搭好后,时间类用例就只依赖环境配置而不依赖执行机器的时区了,更多变量与脚本细节可参考 docs/readme/readme_cn.md。
【免费下载链接】brunoOpensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)项目地址: https://gitcode.com/GitHub_Trending/br/bruno
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考