这些年我前后换过三四个接口调试工具,说实话,最开始看到有人聊一个 10MB 的 Postman 替代品时,我是不太信的。毕竟 Postman 的安装包动辄几百 MB,运行起来还要吃掉大量内存,一个只有它零头大小的工具能干什么?
但实际用下来,我发现这个体积和启动速度的优势根本不是什么宣传噱头。这个工具就是 Bruno,一个开源、本地优先的 API 客户端。它的安装包大约 10MB,双击打开到出现主界面基本一眨眼的功夫,而且不像 Postman 那样要登录账号、加载一堆云同步数据。对于像我这种经常要开十几个项目环境、随时切换接口集合的人来说,这种轻量感带来的体验提升,远远超出"省点磁盘空间"这个表面意义。
这篇文章我就用自己的实际经历,把这个工具的架构逻辑、日常操作、从 Postman 迁移的踩坑点、以及怎么在自动化测试和持续集成里使用它,从头到尾聊一遍。内容不会太玄乎,都是能直接动手照做的。
1. 为什么我会盯上一个 10MB 的接口测试工具
1.1 从 Postman 的体积焦虑说起
先交代一下背景。我日常工作里接口调试是高频动作,以前一直是 Postman 的重度用户。Postman 当然很强大,但有几个问题让我越来越难受:
- 安装包和安装后的占用空间很大,每次版本更新都要重下不少数据,在机器紧张时确实心疼那块硬盘。
- 启动速度越来越慢,尤其在加了多个插件、大量集合之后,打开要转好几圈。
- 每次启动还要连接官方服务,有时网络不稳定,明明只是本地调试,却被登录态、同步状态这些事情干扰。
- 数据默认往云端同步,虽说是为了方便,但团队里有些项目对数据敏感,我内心其实不太想让接口信息经过第三方服务器。
这些问题单个拎出来不算严重,但叠加在一起,就让我开始留意开源社区有没有更清爽的方案。后来看到有人推荐 Bruno,给的标签就是"10MB、秒开、离线优先",我第一反应是这会不会是个功能残缺的半成品。抱着试一试的心态下载之后,发现它比我预想的完整得多。
1.2 启动不到一秒意味着什么
很多人会把"启动速度快"理解成"省时间",但实际体验下来,真正的影响是调试节奏的改变。用 Postman 的时候,因为启动成本高,我往往会攒一批请求再打开一次工具,或者干脆一直挂着不关,结果就是内存一直被占着。
Bruno 启动不到一秒,说白了这个工具就变成了"随时打开、用完就关"的存在。前端联调的时候,改一个接口地址、验证一个字段,手边随手就能拉起来一个轻量窗口。这种即时响应的特性,直接降低了动手测试的阻力,反而让我测得更勤了。
这一点平时不觉得,真到项目进入联调阶段,一天要切换好几十个请求时,体会特别明显。
2. 它凭什么把安装包压到 10MB
2.1 本地优先的架构设计
Bruno 能做得这么轻,核心原因在于架构思路和 Postman 完全不一样。Postman 走的是"账号 + 云端存储"的路线,你建的集合、环境变量都会和服务端同步,所以客户端要内置很多网络通信、权限管理、数据同步的逻辑,体积自然就下不来。
Bruno 则是把一切数据都存放在你自己电脑的文件夹里。你创建的每一个集合,本质就是磁盘上的一个目录;集合里的每个请求,则是一个后缀为.bru的纯文本文件。没有云端数据库,没有复杂的账号体系,自然也就不需要那么多底层代码。
这种设计还带来了一个额外好处:集合目录可以直接用 Git 管理。接口变动时,你在 git diff 里能清清楚楚看到修改了哪个 URL、哪个请求头,这在多人协作时非常实用。
2.2 集合即文件夹:告别云同步
用一句话概括 Bruno 的数据模型就是:集合即文件夹,请求即文件。
这个理念我第一次接触时还有点不习惯,因为我习惯了 Postman 那种"接口都存到云端"的思维。但实际用了几天之后,我反而更喜欢这种模式:
- 备份非常简单,直接复制整个集合文件夹就行。
- 换电脑时不用通过账号拉取数据,用 Git 拉一下仓库,或者拿 U 盘拷一下就行。
- 也不用担心服务商哪天调整策略,毕竟数据完全在自己手里。
- 团队协作时,代码仓库里可以直接 review 接口变更,而不是去 Postman 的共享工作区里看一份被覆盖的版本。
当然,这种模式也有一个前提,就是你本身习惯用 Git 来管理项目资源。如果你的团队完全不用 Git,那这种"文件即接口"的思路可能还要适应一阵子。
2.3 与 Postman 的核心差异对照
我把两个工具在实际使用中的核心差异整理成了下面这个表格,方便大家快速判断它适不适合自己的场景。
| 对比维度 | Postman | Bruno |
|---|---|---|
| 安装包大小 | 数百 MB 级别 | 约 10MB |
| 启动速度 | 受插件与同步影响,偏慢 | 秒开 |
| 数据存储 | 云端优先,需登录账号 | 本地文件,无需账号 |
| 离线使用 | 部分功能受限 | 完全离线可用 |
| 集合管理 | 工作区 + 团队库 | 文件夹 + Git 仓库 |
| 请求文件格式 | 私有格式 | 纯文本.bru |
| 脚本能力 | JavaScript 脚本生态成熟 | 支持 JS 脚本,API 简洁 |
| 适合人群 | 全功能团队协作平台 | 偏好本地文件流与 Git 协作的开发者 |
这个对比不是说 Postman 不好,而是两者解决的问题不一样。Postman 更像一个全家桶,提供的是平台级的能力;Bruno 则更像是"编辑器"级别的工具,轻巧、专注,把 API 调试这一件事做到顺手。
3. 把这台"小钢炮"装起来并跑通第一个请求
3.1 下载与安装:Windows/macOS/Linux 三平台
Bruno 的安装没什么特别的门槛,官方在 GitHub 的 Releases 页面会提供各平台的安装包,选择对应自己系统的版本下载即可。
Windows 环境下,推荐下载.exe安装包,双击后按提示下一步就行。也可以用包管理器安装,比如winget install Bruno.Bruno,这样后续升级方便一些。macOS 上则下载.dmg文件,或者用 Homebrew 执行brew install --cask bruno。Linux 用户需要注意,官方提供有.deb、.rpm以及 AppImage 等格式,我自己的 Ubuntu 环境用的是.deb包,安装命令非常简单:
sudo dpkg -i bruno_1.20.0_amd64.deb如果遇到依赖缺失,再执行一下sudo apt-get install -f补救即可。
安装完第一次打开,你会发现它没有任何账户注册、登录引导页面,直接就进入主界面,这种"开箱即用"的感觉我特别喜欢。整个应用界面非常简洁,左边是集合列表,中间是请求编辑区,右边是响应区,没有多余的广告位或者诱导升级的按钮。
3.2 五分钟建出第一个集合与请求
打开主界面后,第一步是创建一个集合。点击左侧的"New Collection",给它起个名字,比如"用户服务接口"。Bruno 会在你选择的本地目录下生成一个与集合同名的文件夹。
接下来,在这个集合里新建一个请求。可以点击"New Request",也可以直接在文件夹上右键选择。请求记录里只需要填两个最核心的东西:
- Request URL,也就是接口地址。
- Method,也就是请求方法,比如 GET、POST。
我用一个非常简单的 GET 请求来验证安装是否正常。假设本地有个服务,接口地址是http://127.0.0.1:8000/api/health,我把它填进去,选择 GET,点击发送。响应区会立刻返回服务端的数据,状态码、响应时间、响应体一清二楚。
整个过程从创建集合到拿到响应结果,不到五分钟。如果是从 Postman 迁移过来的用户,基本不需要学习成本,界面布局和使用逻辑是高度相似的。
3.3 环境变量与 .env 的本地化管理
环境变量是接口调试里非常重要的功能,尤其在开发、测试、生产多套环境之间切换时。
Bruno 的环境变量逻辑比 Postman 更贴近开发者习惯。它支持创建多个环境,每个环境就是一组键值对,比如:
| 环境名 | 变量名 | 值 |
|---|---|---|
| dev | base_url | http://127.0.0.1:8000 |
| test | base_url | http://test-api.example.com |
在请求的 URL 里,用{{base_url}}这样的语法引用变量,然后通过右上角的环境切换下拉框,快速在不同环境之间切换。
额外说一句,Bruno 也支持读取项目根目录下的.env文件,这个功能在做本地开发时很方便。你可以在项目里放一个 Git 忽略的.env,把本地专属配置写进去,而集合文件本身提交到仓库,这样别人拉代码时不会把你的本地配置也带走。
注意:
.env文件不要提交到 Git 仓库。如果你的项目本身对接口地址敏感,建议把.env加入.gitignore,只把环境示例文件提交上去。
4. 从 Postman 迁移过来最容易踩的五个坑
我在切换工具的过程中遇到了一些问题,整理一下,给同样想迁移的朋友提个醒。
4.1 集合导入与格式差异
Bruno 支持直接导入 Postman 的集合文件。操作路径是:左侧集合区域点击右键,选择"Import",然后选择 Postman 导出的 JSON 文件即可。绝大多数基础的 GET、POST 请求都能正常解析,请求头、请求体参数也都能带过来。
但有一点要注意:如果你的 Postman 集合里用了比较复杂的脚本逻辑,比如多层级的动态变量、复杂的测试断言,导入后可能需要人工调整。因为两个工具的脚本 API 并不完全相同,Bruno 的脚本语法更偏向于通用的 JavaScript 风格,和 Postman 的pm.*对象有一定差异。
建议迁移时先导出一份测试集合试试水,别把生产用的超大集合一步到位迁移,避免转换结果与预期不符时不好排查。
4.2 脚本断言语法的不同
Postman 里最常见的断言是这样的写法:
pm.test("Status code is 200", function () { pm.response.to.have.status(200); });Bruno 里用了完全不同的表达方式。它的脚本 API 更接近一个简单的expect函数,我实际用的断言是这样写的:
expect(res.status).to.equal(200);如果你需要判断响应体里的某个字段,比如检查code是否为 0,可以这么写:
const data = res.body; expect(data.code).to.equal(0);这里的res对象是 Bruno 内置的响应对象,不需要额外引入任何库。整体来说,Bruno 的断言 API 更简洁,但对从 Postman 迁移过来的人来说,确实需要花 10 分钟熟悉一下新的写法。
4.3 环境变量引用方式的差异
Postman 里环境变量使用{{variable_name}},Bruno 也支持同样的语法,这一点没有太大差异。但有一个细节需要注意:Bruno 的环境变量解析是发生在本地的,所以你不能像 Postman 那样依赖云端帮你处理一些逻辑。
另外,Postman 里可以用pm.environment.set()和pm.variables.set()动态地创建变量,Bruno 也有类似的方案,但如果你在请求执行过程中动态设置了一个新变量,这个变量只对当前请求之后的脚本或依赖该变量的后续请求生效,它不会自动同步到一个"云端环境变量池"。需要更精细控制时,建议把动态值写入文件,或者通过脚本返回后再次引用。
4.4 pre-request script 与 test script 的写法
Bruno 在每个请求标签页上提供了脚本区,可以分别写"请求前脚本"和"请求后脚本"。请求前脚本适合做签名、生成时间戳、动态 token 之类的操作,请求后脚本用来做断言和数据处理。
我平时用请求前脚本最多的场景是给需要鉴权的接口动态生成签名。比如某个内部服务要求请求头里带一个时间戳和 MD5 签名,我就这样写:
const timestamp = Date.now(); const secret = "my_secret_key"; const sign = crypto.createHash("md5").update(timestamp + secret).digest("hex"); req.setHeader("X-Timestamp", timestamp.toString()); req.setHeader("X-Sign", sign);这里用到的req.setHeader()是 Bruno 暴露的请求对象方法,可以在请求发出前修改请求头。整体语法上,它比 Postman 的pm.request.headers.add()看起来更直白一些,也算是一种熟悉的 JavaScript 风格。
4.5 导出 curl 与分享请求
Postman 有非常方便的"Copy as cURL"功能,Bruno 同样支持。在请求编辑区右键,选择"Copy as cURL",就能得到一段可直接在终端运行的 curl 命令。这个功能在跟同事沟通接口问题时非常常用,直接把命令发过去,对方不用打开任何工具也能复现。
如果你想用文档形式分享整个集合,Bruno 也支持把集合导出为 OpenAPI 规格或 Markdown 文档。不过它的导出能力目前没有 Postman 那么丰富,如果团队有极强的文档生成需求,可能需要配合其他工具一起使用。
5. 用命令行场景把自动化能力补全
5.1 安装命令行运行器
Bruno 的图形界面只是其中一半,它还有一个独立的命令行运行器,叫做@usebruno/cli,专门用于在终端环境里运行集合测试。这个功能对持续集成来说非常关键。
像我这种平时依赖 Node.js 生态的人,安装过程就是一条命令的事:
npm install -g @usebruno/cli安装完成后,在项目目录里执行:
bru run它会自动运行当前目录下所有集合里的接口测试脚本,并在终端输出结果。这个命令支持的参数也比较丰富,比如--env指定环境、--env-var动态注入环境变量、--reporter指定输出格式等。
5.2 在 CI 里跑接口测试
有了命令行运行器,把接口测试接入持续集成流程就变得顺理成章了。最常见的做法是在 CI 的某个阶段执行:
bru run --env test --reporter junit --output ./reports/bruno.xml然后让 CI 平台解析这个 JUnit 格式的测试报告。目前主流的 Jenkins、GitLab CI、GitHub Actions 都支持解析 JUnit 报告来展示测试结果,集成成本很低。
我自己的一个项目就是在 GitLab CI 里加了一个 stage,每次代码合并前自动跑一遍核心接口集合。这个流水线大概长这样(简化版):
api-test: stage: test image: node:18 script: - npm install -g @usebruno/cli - bru run --env test --reporter junit --output ./reports/bruno.xml artifacts: reports: junit: ./reports/bruno.xml这个流水线跑起来之后,我基本告别了"上线前手动把所有接口点一遍"的重复劳动。之前 Postman 其实也能做类似的事情,但配置门槛明显高一些,需要用 Newman 配合一堆参数和额外插件。
5.3 自动化用例的写法建议
如果你打算把 Bruno 集合当自动化用例来用,我建议在一开始就规划好请求的命名和断言结构。命名最好不要是/getUserInfo这样的大白话,而是像用户模块-获取用户信息-正常场景这种能直接从测试报告里看懂含义的格式。
断言方面,除了检查状态码,强烈建议加一些业务字段的校验。比如一个下单接口,光是 200 状态码说明不了什么问题,只有校验到data.orderId存在且非空,才算这个用例真正有防护作用。
我自己的习惯是每个请求至少写三个断言:
- 状态码符合预期。
- 响应体能正确解析为 JSON。
- 关键业务字段存在或数值符合预期。
这样排障的时候,只需要看测试报告里哪一层断言挂了,就能快速定位是网络层、解析层还是业务层的问题。
6. 实测体验与长期使用建议
6.1 日常使用中的真实感受
连续用了一个多月之后,我最大的感受是 Bruno 确实把"本地优先"四个字落实到了每个细节里。启动快只是一个方面,更让我满意的是它完全不打扰我。没有登录提醒,没有云同步进度条,没有新版本推送弹窗,打开就是干活,干完就关。这种安静的使用体验,在接触 Bruno 之前我甚至没意识到自己会这么在意。
资源占用方面也很友好,日常挂着三四个集合再加一些脚本,内存占用也就一两百 MB 的样子,比起之前 Postman 长期占着近一个 G 内存,差距非常明显。对于我这种用公司配发笔记本、内存不太充裕的人来说,这个优势是实打实的。
团队协作这块,由于集合直接进 Git 仓库,code review 时能看到接口定义的每一次差异。之前用 Postman 的时候,接口文档和代码仓库经常是脱节的,现在接口变更跟着代码一起走,从流程上就杜绝了"代码改了但文档没更新"的尴尬场景。
6.2 适合哪些项目,不适合哪些项目
基于我的使用经验,Bruno 最适合这些场景:
- 个人开发者或者小团队,项目本身就使用 Git 管理,希望接口数据跟着代码走。
- 对数据隐私要求较高的项目,接口信息不适合放到第三方云端。
- 日常以接口调试为主,偶尔需要跑一些自动化接口测试,但不想引入太重的基础设施。
- 追求开发工具轻量化,受不了 Electron 应用长期占内存的开发者。
不适合的场景也有。如果你的团队非常依赖 Postman 的云端工作区来做多人实时协作,比如不同成员在同一个集合上同时编辑并互相看到变更,那 Bruno 的本地文件加 Git 合并模式就不是特别顺手。再比如你已经在 Postman 里积累了非常庞大的脚本资产和第三方插件依赖,迁移成本会比较高,短期内不一定划算。
还有一个值得注意的点:Bruno 目前的插件生态还在起步阶段,远不如 Postman 丰富。虽然常用的功能基本不缺,但如果你依赖一些冷门的社区插件,短期内可能找不到平替。
6.3 后续可以这样扩展
用了一段时间后,我给自己规划了几个扩展使用思路,供参考。
把 Bruno 集合作为接口测试基线,接入代码提交前的本地钩子。每次提交代码前自动跑一遍核心接口集合,不用等 CI 排队,本地就能提前发现接口回归问题。
结合.bru文件做接口文档生成。既然请求本身就是文本文件,完全可以写个小脚本解析这些文件,自动生成一份项目内部的接口文档网站,这样接口变更后文档能保持同步。
团队里新同事入职,不用再教他怎么用 Postman 导入导出、怎么处理环境变量冲突,直接把仓库拉下来,装一个 Bruno,一切就都齐了。这个 onboarding 成本降低的幅度,比我预想的要明显很多。
最后提一个我使用时的真实感受:Bruno 不是那种你用了一两天就觉得惊艳的工具,它的好是那种用得越久越能体会到的顺手。最开始从 Postman 迁过来可能会有几天不习惯,但当你开始享受"秒开即用"和"文件即接口"的清爽之后,大概率就不太想回到几百 MB 的大家伙那边去了。如果你的工作流高度依赖 Git,这个替代品值得认真试一试。