ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

轻量API调试利器:10MB开源的Bruno如何替代Postman?

轻量API调试利器:10MB开源的Bruno如何替代Postman? 说实话我现在已经很少主动打开 Postman 了。不是因为它不好用而是对于一个天天跟接口打交道的人来说它越来越像一个“重型巨无霸”安装包动辄几百 MB启动转圈要等好几秒偶尔还要被登录界面和一堆弹窗打断思路。所以我一直在找一款真正的轻量替代品要求很简单——体积小、启动快、核心功能不缩水。直到我试了 Bruno一个几乎满足我所有幻想的开源 API 客户端。这篇文章就以“10 MB 的 Postman 替代品启动不到 1 秒”为切入点聊聊我为什么抛弃 Postman、Bruno 凭什么能这么轻以及从安装到日常接口测试、自动化脚本、持续集成的完整实操记录。如果你平时用 Postman 做接口调试、接口自动化测试或者经常被 Postman 的启动速度和体积折磨这篇文章应该能帮你省下不少时间。1. 为什么我要找 Postman 的替代品1.1 我受够了 Postman 的几个典型痛点先说清楚我不是无脑黑 Postman。在接口调试这件事上Postman 依然是这个领域功能最全、生态最成熟的工具之一。但正因为功能太全它逐渐变得“重”了。首先是安装包体积。Postman 10.x 时代的安装包基本在 100 MB 左右装完之后的磁盘占用甚至会到 400-500 MB。对于一台配置普通的开发机来说可能不算什么但如果你经常在 Docker 容器、临时虚拟机或者低配笔记本上干活体积就是实打实的负担。其次是启动速度。我不止一次点开 Postman 图标然后去倒杯水回来发现它还在加载。尤其是电脑上跑着一堆服务的时候Postman 的启动时间轻松超过 5 秒。不要小看这 5 秒一天开十几次浪费的时间就是几十分钟。而且那种“等一下才能继续干活”的割裂感非常影响调试状态。第三是强制登录和工作区同步。新版本 Postman 不登录很多功能用不了登录之后又默认把集合同步到云端。个人项目还好一旦涉及公司内部的敏感接口云端同步本身就是一种合规风险。我知道很多人会去搜“Postman 免登录版本”但在团队协作和合规要求下这个问题始终是个坎。最后是付费墙。Postman 免费版其实够用但有些团队功能、报告能力、高级 runner 都开始往付费方向收拢。作为个人开发者我不太愿意为了这些原本很基础的能力持续付费。1.2 轻量替代品的候选清单在找到 Bruno 之前我其实也评估过其他几个热门替代品。Hoppscotch 是纯 Web 方案开源界面清爽在线就能跑。但它的缺点是离线能力弱无法很好地管理本地集合文件网络受限的环境基本废掉。Insomnia 也曾经是我喜欢的工具设计漂亮、支持 GraphQL但它的体积同样不小而且近年也加入了登录同步机制轻量程度并没有达到我的预期。Apifox 功能确实很强国内团队用得也多但它更像“Postman Swagger JMeter”的组合体概念重、学习曲线陡跟“轻量”两个字搭不上边。Bruno 不一样。它的整个设计哲学就是“反云端、反重量”。它把每个请求集合保存为本地文件夹里的纯文本文件用 Git 就能直接管理不需要账号体系不需要云端同步启动就是一瞬间。文章标题里说的 10 MB 体量如果指安装后的核心体积或者运行时的内存占用实测下来确实非常接近这个量级跟 Postman 完全不是一个次元。1.3 最终为什么锁定 Bruno我选择 Bruno 做主力工具核心原因有三条。第一离线优先。Bruno 的集合是本地文件不保存到任何远程服务器这意味着我的接口配置、环境变量、脚本都掌握在自己手里。对于涉及企业内部数据的接口这个特性解决了很大的安全问题。第二Git 原生友好。因为集合本身就是目录结构我可以直接把集合丢进 Git 仓库分支管理、代码审查、多人协作全部复用现有的 Git 流程。这是传统 API 工具很难做到的体验。第三功能和体积的平衡。Bruno 虽然轻但日常接口调试需要的功能几乎都有请求构建、环境变量、断言脚本、集合运行器、CLI 工具、甚至支持 OpenAPI 导入。对我这种“90% 时间在做增删改查接口调试”的人来说完全够用。2. Bruno 的核心设计思路与原理2.1 本地文件夹即集合为什么这样设计用过 Postman 的人应该对“集合”这个概念很熟悉。Postman 的集合本质是一个被云端数据库索引的 JSON 数据块你看到的每个请求、每个环境配置最终都存储在 Postman 的服务器上。Bruno 则完全不同它把“集合”直接定义为一个本地文件夹文件夹里每个请求是一个扩展名为.bru的纯文本文件。你可以在任意文本编辑器里直接打开.bru文件查看内容。举个例子一个简单的 GET 请求文件长这样meta { name: 获取用户列表 type: http seq: 1 } get { url: https://api.example.com/users body: none auth: none }整个文件没有特殊编码就是纯文本。这种设计带来的最大好处就是“可读、可查、可 diff”。团队里有人改了接口地址你用 Git diff 就能看到改动内容不用像 Postman 那样在 UI 里翻来翻去。而且因为是文本文件文件搜索、批量替换、脚本生成都非常方便。再往深一层说这种设计也决定了 Brunco 的轻量天花板。它不需要数据库服务不需要本地缓存同步引擎不需要在线状态管理核心程序只需要做好“读取文本文件 - 解析请求 - 发出去 - 展示响应”这一件事。功能边界清晰程序体积自然就小。2.2 为什么能做到启动不到 1 秒很多电子的启动速度其实和功能多少没有必然关系更多取决于架构设计。Postman 是基于 Electron 框架构建的渲染进程和主进程之间的通信开销、庞大的前端渲染逻辑、初始化时的账号状态检查都会拖慢启动。Bruno 同样用了 Electron但做了大量减法。Bruno 启动时不需要联网检查不需要加载账号信息不需要同步远程集合。它只需要扫描当前打开的工作区目录把集合列表渲染出来即可。我实测从双击图标到进入主界面普通机械硬盘上大约 1 秒放在 NVMe 固态上是“点下去就出来了”的体感。如果你对“启动时间”很敏感这一项体验足以让你回不去 Postman。另外Bruno 在 Linux 和 Windows 上的表现也很稳定。我在 Ubuntu 上装过在 Windows 11 上也跑过都没有出现 Electron 应用常见的白屏问题。这跟项目迭代质量有关Bruno 的社区版本更新很勤稳定性一直在提升。2.3 请求脚本bru 语言的表达能力Bruno 内置了一套名为bru的脚本语言用于处理请求参数、变量赋值、响应断言等场景。它比 Postman 的脚本机制更简洁语法上有点像 JS 和 Bash 的混合体。比如你想在发送请求前生成一个时间戳并赋值给变量可以这样写set: now new Date().getTime()在请求 URL 中使用变量get { url: https://api.example.com/data?ts{{now}} }如果要在请求头里动态设置 Token可以结合 process 环境变量set: token process.env.API_TOKEN然后在请求头里引用。这种“设置变量 - 请求中引用”的流程比 Postman 里打开 Pre-request Script 写一堆 JavaScript、再小心翼翼处理异步回调要直观得多。对刚接触接口调试的新人来说上手成本低了很多。2.4 环境变量与数据变量的机制Bruno 的环境变量使用方式和 Postman 类似也是“环境 变量”的二元结构。你可以创建 dev、staging、prod 等多套环境每套环境里维护独立的变量值。在请求中统一用{{变量名}}的语法引用。我之前做一个多环境部署的项目需要在 dev、test、prod 三套环境间来回切换接口测试。Postman 里我确实也能做但环境切换总有一种“慢半拍”的感觉。Bruno 的右侧栏点击切换非常快并且变量名会自动高亮显示一眼就能看出哪个请求引用了哪些变量排查问题非常方便。数据变量对应了 Postman 里的 Runner 数据文件。Bruno 支持 CSV 和 JSON 格式的数据驱动在做批量接口测试时非常有用。你可以准备一个测试用户列表的 CSV让集合运行器逐个账号跑同一组接口。3. 从 Postman 迁移到 Bruno 的完整实操3.1 各平台安装 Bruno 的方式汇总Bruno 官方提供了 Windows、macOS、Linux 的安装包也支持通过包管理器安装。我的主力系统是 Ubuntu直接用的 AppImage 版下载后在文件管理器里双击即可运行不需要 root 权限。Windows 用户从官网或者 GitHub Releases 下载 exe 安装包一路下一步就行。macOS 用户可以直接用 Homebrewbrew install brunoLinux 也可以使用 snap 安装snap install bruno安装完成后首次启动会要求设置一个工作区目录。你可以理解为“接口集合仓库根目录”。我建议把它放在代码仓库同级或者内部目录里这样后续方便 Git 统一管理。注意Bruno 和 Postman 的数据模型完全不一样。Postman 的集合数据在云端或本地配置库里Bruno 的就是普通文件夹。所以不要想着“自动无缝迁移”需要先通过导入功能把 Postman 的集合导出来。3.2 把 Postman 集合导入到 BrunoBruno 支持直接导入 Postman 导出的 JSON 文件。操作路径是菜单栏 Collection - Import - Postman。在 Postman 客户端里你需要先导出一个集合文件打开 Postman选中要导出的集合。点击右侧的“导出”按钮选择导出为 JSON 格式。将 JSON 文件保存到本地。然后在 Bruno 里导入这个 JSON 文件。Bruno 会自动把 Postman 里的请求、文件夹结构、环境变量、认证配置转换成自己的本地文件结构。导入后建议在资源管理器里看一眼生成的目录结构my-collection/ ├── requestA.bru ├── requestB.bru └── subfolder/ └── requestC.bru这种文件和接口一一对应的结构一眼就知道哪些接口存在哪些请求被放在了哪个目录下。不过导入不是完美的。我在实际导入一个老项目时发现部分 Postman 自带的脚本特别是复杂的 Pre-request Script 和 Test Script不会一比一转换。Postman 用的是完整的 JavaScript 运行时Bruno 的脚本引擎更简洁所以复杂脚本需要用 bru 语法重写。3.3 第一次发起一个 GET/POST 请求Bruno 的主界面很清爽左边是集合树右边是编辑区。新建请求只需要在集合目录上右键选择“创建请求”给请求起个名字然后选择请求方法。一个典型的 GET 请求配置get { url: https://api.example.com/users?page1 body: none auth: none }点击右上角的发送按钮响应会直接展示在下方。响应体支持 JSON、XML、HTML 等常见格式的自动格式化JSON 字段还会语法高亮阅读体验和 Postman 差距不大。如果你要发送一个 POST 请求并且请求体是 JSON配置就会变成这样post { url: https://api.example.com/users body: json auth: none } body:json { { name: 张三, email: zhangsanexample.com } }注意这里body: json表示请求体使用 JSON 格式Bruno 会在发送前自动做 JSON 序列化校验。如果 JSON 格式不对它会直接报错不会把错误请求发出去。这一点对我的日常调试非常友好省去了很多因手抖导致的多余请求。3.4 环境变量的配置与切换在 Bruno 里配置环境变量很简单点击右上角环境选择器选择“配置环境”即可看到环境列表页面。添加环境后再添加变量例如环境名dev变量名baseUrl变量值http://localhost:8080然后你的请求 URL 可以写成{{baseUrl}}/users。切换环境时只需要选择另一个环境所有引用{{baseUrl}}的请求都会自动指向新的地址。这里有一个经验变量名建议统一前缀。比如 baseUrl、apiKey、timeout 都用小驼峰环境相关的后缀用_dev、_prod。不要小看命名规范当你的项目有几十个接口的时候规范命名能避免大量低级错误。3.5 断言与测试脚本的写法对比接口测试里断言是最关键的一环。Bruno 脚本的断言语法非常易读我随便写一个响应状态断言assert: res.status 200再做一个 JSON 字段判断assert: res.body.data.length 0如果你还想验证某个字段的具体值assert: res.body.user.name 张三Bruno 支持在请求的“脚本”标签页里写这些断言规则发送请求后会显示通过/不通过。配合集合运行器可以批量跑整个集合里所有请求的断言输出简洁的测试通过/失败统计。对比 PostmanPostman 的断言语法更接近标准 JavaScript功能更灵活但学习成本更高。Bruno 的断言是一种专门的 DSL表面上看能力弱一些实际上已经覆盖了绝大多数接口测试场景。如果你的断言逻辑复杂到 Brunco 写不出来那大概率应该考虑用真正的编程语言写测试用例而不是在 API 工具里硬堆脚本。3.6 使用集合运行器批量跑接口单个请求验证通过之后往往需要把整个流程串起来跑一遍。Bruno 的集合运行器位于集合菜单下的“运行”选项可以指定运行哪个集合或子目录也可以设置迭代次数、延迟时间、数据文件等。我的用法通常是把需要联调的接口比如“创建用户 - 查询用户 - 更新用户 - 删除用户”放在同一个子目录然后对这个子目录跑一次运行器。运行器会按顺序发送请求并把每个请求的断言结果汇总到一个表格里。实际使用中最舒服的一点是运行器支持断点续跑式的日志输出。如果某个请求失败了直接在运行结果里点击对应的请求就能定位到具体文件和断言语句排查效率很高。4. 进阶自动化测试与集成到 CI/CD4.1 Bruno CLI 的安装与基础用法Bruno 不只是图形化工具它还提供了一个命令行工具bru可以把集合测试嵌入到持续集成流程中。安装 CLI 的方式非常直接npm install -g usebruno/cli然后在集合目录下运行bru runCLI 会自动识别当前目录下的.bru文件按顺序执行所有请求并给出测试结果。整个过程控制台输出非常清晰有每个请求的执行时间、断言通过情况、失败原因等。我在本地开发时已经习惯用bru run来替代随手点击运行器。每次改完接口代码直接在终端敲一行命令马上就能看到接口是否被改挂比手动打开工具界面试一遍要高效得多。4.2 将 Bruno 集成进 GitHub Actions / GitLab CIBruno CLI 的存在让接口测试的自动化变得很轻松。你只需要把接口集合目录和代码仓库放在一起然后在 CI 配置里加上运行 CLI 的步骤。一个典型的 GitHub Actions 工作流片段如下name: API 测试 on: [push] jobs: api-test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - uses: actions/setup-nodev3 with: node-version: 18 - run: npm install -g usebruno/cli - run: bruno run ./tests/api这里我假设集合文件都放在仓库的tests/api目录下。实际执行时CLI 会读取目录下的所有.bru文件并逐个执行。如果你想避免测试环境写进仓库可以把环境变量放在 CI 平台的 Secrets 里然后在 CLI 运行时注入。GitLab CI 也类似只是配置文件格式不同。核心思路就是安装 CLI运行bru run解析退出码判断是否通过。如果某个断言失败CI 任务就会失败从而拦截乱改接口的代码合并。4.3 与 curl 的互操作导出一条 curl 命令很多人习惯用 curl 快速验证一个接口或者把接口分享给运维同事。Bruno 提供了“导出为 curl”的功能在请求编辑界面右键或通过菜单就能看到导出选项。导出的 curl 命令会包含完整的 URL、请求头、请求体、认证信息等。我经常用这个功能把 Bruno 里已经配置好的复杂请求尤其是带签名头、带 Token 的请求一键转成 curl 命令直接丢给同事在服务器上执行避免他在服务器上现写 curl 参数踩坑。反过来如果你手头有一个现成的 curl 命令Bruno 也支持从 curl 命令粘贴生成一个请求。路径是新建请求时选择“从 curl 导入”非常方便。5. 常见问题与避坑清单5.1 导入 Postman 集合后中文乱码这是我第一次导入时遇到的问题。Postman 导出的 JSON 文件默认是 UTF-8 编码正常情况下没问题。但某些旧项目的集合里历史请求的备注或 URL 参数里混入了 GBK 编码的中文导入 Bruno 后就会出现乱码。解决办法其实不在 Bruno而是先用文本编辑器把 Postman 导出的 JSON 文件强制转成 UTF-8 无 BOM 格式再导入。我用 VS Code 打开 JSON 文件点击右下角编码按钮选择“通过编码保存”改为 UTF-8保存后再导入。乱码问题基本能解决。另外提醒一点如果 Postman 里的集合太大几千个请求导入时 Bruno 可能会卡一会儿这是正常的。它会逐条创建.bru文件磁盘写入需要一点时间。5.2 请求超时或连接被重置Bruno 默认使用系统代理设置但如果你本地开了一些代理工具请求可能会被代理拦截导致连接重置。遇到“连接被重置”“请求超时”这类错误时先去设置里检查代理配置改成“无代理”再试一次。还有一个容易忽略的点是 TLS 证书验证。公司内部接口经常自签名证书Bruno 默认会校验证书。如果请求抛出证书相关错误可以在请求设置里临时关闭 TLS 校验或者把自签名证书加入系统信任链。需要说明的是关闭证书验证只推荐在本地调试时使用生产测试还是要按规范来。5.3 断言不生效或变量未定义很多人刚迁移到 Bruno 时会遇到“明明在设置里定义了变量但请求时显示变量未定义”。这时候先检查环境是否被正确选择。Bruno 不会像 Postman 那样自动默认一个环境必须手动在右上角选中环境否则{{变量}}不会被解析。另一个坑是变量名大小写。bru 脚本的变量名是区分大小写的。{{baseUrl}}和{{baseurl}}是两个完全不同的变量稍不留神就会踩坑。我的建议是统一用 lowerCamelCase 命名然后定义那些容易混淆的变量时尽量让名称差异明显一点。断言不生效的情况多半是断言语法写错了。例如把assert: res.body.xxx 1写成了assert: res.body.xxx 1少了一个等号看似没问题实际不是合法断言。Bruno 的断言使用严格等于不支持赋值运算符。写完之后多留意控制台输出的错误提示它会告诉你哪一行解析出了问题。5.4 集合运行器不输出完整报告集合运行器默认的输出画面是测试项列表如果想拿到更完整的 HTML 报告需要额外配置。Bruno 的 CLI 支持输出 JUnit 格式的测试报告可以直接接入 CI 平台。在 GitHub Actions 里我习惯加上一步上传测试报告- run: bruno run ./tests/api --output ./reports/report.xml - uses: actions/upload-artifactv3 with: name: api-test-report path: ./reports/report.xml这样每次跑完接口测试都能在 CI 平台上下载到格式化的报告文件。对于需要写测试汇总的场景这个功能省了大量手动整理时间。5.5 我的使用心得什么时候不建议用 Bruno最后说点真实感受。Bruno 虽然好但它不是万能替换品。如果你重度依赖 Postman 的团队协作中心、在线文档、Mock Server 这类云端服务Bruno 的“本地优先”反而会让你觉得功能缺失。毕竟它的核心哲学是“你的数据属于你”不提供中心化协作能力。另外如果你的接口测试需要复杂的脚本逻辑比如需要多重加密签名、动态验证码识别、复杂的流程状态机Bruno 的脚本能力会有些吃力。这种场景下我更推荐直接用 Postman 专业测试框架结合或者直接上 JMeter、K6 这类专门的测试工具。我自己现在的日常组合是日常开发调试、接口探索、团队接口文档维护用 Bruno需要复杂压测和完整测试报告的时候再上专业工具。Bruno 帮我解决掉了“轻量轻量再轻量”的核心诉求又没让我失去接口调试的舒适感。从我把 Postman 卸载到今天已经过去几个月了说实话完全没有不适感。10 MB 不到的体积、秒开的启动速度、纯本地的文件管理这些东西用惯了真的回不去。如果你也被 Postman 越来越重的体验困扰我强烈建议你花半小时尝试一下 Bruno从导入集合到发第一个请求整个过程远超你想象的顺畅。
返回列表