Bruno 搞定 API 测试里的时间问题:3 个内置变量 + 1 套沙箱断言
【免费下载链接】brunoOpensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)项目地址: https://gitcode.com/GitHub_Trending/br/bruno
API 测试里时间相关的断言最容易在不同时区的机器上翻车。Bruno 这款开源 API 客户端把时间变量和脚本沙箱做成了内置能力,"服务器时间对不对、响应够不够快"这类检查几行代码就能落地。读完你能直接复制出一套跨时区可用的时间校验用例。
一分钟看到效果:最快写出时间断言
把一个请求存成.bru文件,时间戳交给内置变量,校验交给测试脚本,发一次请求就能看到结果:
### sync-check POST {{apiHost}}/api/time Authorization: Bearer {{token}} {{ "ts": "{{$timestamp}}", "sentAt": "{{$isoTimestamp}}" }} tests: test("server clock within 5s", function () { expect(Math.abs(Date.now() - res.headers.Date)).to.be.lessThan(5000); });上面这段里,{{$timestamp}}是秒级 Unix 时间戳、{{$isoTimestamp}}是 UTC 的 ISO 字符串,发出前会被自动替换;断言部分只在响应返回后执行,拿res.headers里服务端时间和本机时钟做 5 秒的偏差比对,超过就标红。
原理拆解
{{$timestamp}} 和 {{$isoTimestamp}} 是怎么生成的
这两个变量不是占位符,而是插值器内置的一小撮"动态函数"之一,源码里就两行:
timestamp: () => Math.floor(Date.now() / 1000).toString(), isoTimestamp: () => new Date().toISOString(),也就是说:前者取当前毫秒除以 1000 再转字符串,后者直接调toISOString()。它们和{{$guid}}、{{$randomInt}}这类随机变量共用同一条替换流水线(实现在 packages/bruno-common/src/utils/faker-functions.ts)。关键差别在于:随机变量每次插值结果都不同,时间变量虽然也随插值时刻变化,但格式是稳定的,所以能放心写进请求体做签名或有效期字段,而不必担心下游解析失败。
为什么断言可以拿"时间"直接比
请求发出前,插值器先把所有{{...}}换成真实值;响应回来后,测试脚本跑在一个隔离沙箱里,拿到的res对象已经带好了res.headers、res.body,还有毫秒级的res.responseTime(见 packages/bruno-js/src/bruno-response.js)。所以时间类检查只需要对比两个现成的时间点,不用自己 start/stop 计时器,也不用关心脚本在哪个进程里执行——GUI 和 CLI 走的是同一套插值与沙箱逻辑。
场景组合:三种时间问题各归各位
| 场景 | 做法 | 用在哪一层 |
|---|---|---|
| 请求要带时间戳(签名、有效期) | {{$timestamp}}/{{$isoTimestamp}}直接插值 | 请求体 |
| 断言服务器时间和本机偏差 | 脚本里Math.abs(Date.now() - serverTime)比对 | tests |
| 团队统一基准时间、各时区换算 | 环境文件里存 UTC 基准 + 偏移量,请求引用变量 | 环境 + 脚本 |
第三种适合团队里有人在北京、有人在纽约的情况:把时区配置放进 Bruno 的环境文件,按环境切换而不是改代码——
vars: utc: "{{$isoTimestamp}}" tokyoOffset: "32400000" nyOffset: "-18000000"存偏移量(毫秒数)而不是存"格式化后的本地时间",好处是不依赖脚本运行机器自己的系统时区;真要展示本地时间,再在测试脚本里用Intl.DateTimeFormat带 IANA 时区名转换,那是脚本层的事,别塞进环境文件。环境配置纳入 Git 后,时区基准的变更就跟着代码一起评审。
遇到问题时
Q:同一用例在本地过、在同事机器上时差忽大忽小?大概率是对方服务返回的不是 UTC 而是本地时间,或者某台机器的时钟漂移了。先别改断言阈值,在脚本里把serverTime、Date.now()、差值三个数都打出来看一眼:差值稳定偏大就去找服务端,差值随机抖动就去校本机时钟。
Q:时区偏移可以直接写死 ±N 小时吗?可以临时用,但会踩夏令时的坑。业务如果严格校验某个时区的本地时间,用Intl.DateTimeFormat('en-US', { timeZone: 'Asia/Tokyo' })这类 IANA 时区名做转换,浏览器和 Node 都能识别,别手写偏移表。
Q:CLI 跑出来的时间行为和 GUI 一致吗?一致。变量替换和脚本执行都在公共库里(packages/bruno-common/),GUI 和命令行只是两个入口。本地 Bruno CLI 能过的时间用例,CI 里换台机器的时区也不会翻车——前提是你的断言比的是 UTC 基准而不是本地格式。
收尾
更多变量和脚本的完整清单在 官方文档 里;想深挖断言沙箱怎么拿响应对象,可以直接翻 packages/bruno-js/src/,bruno-response.js和test.js是最短的两条阅读路径。
【免费下载链接】brunoOpensource IDE For Exploring and Testing API's (lightweight alternative to Postman/Insomnia)项目地址: https://gitcode.com/GitHub_Trending/br/bruno
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考