为什么我用 TypeScript + VSCode 取代了 Postman

0 阅读6分钟

每次对接一个 API,我都会经历两个阶段。

第一阶段是探索:发请求、看响应、搞清楚接口实际行为。这些年来,这件事发生在 Postman、curl,或者某个不知道藏在哪里的临时文件里。

然后过一段时间,当我需要确保这些接口持续正常工作时,我会打开一个测试文件,从头重写相同的请求。到那时候,探索阶段学到的东西已经忘了一半。

我一直这样做,直到意识到问题不是懒——而是这两个阶段发生在完全不同的工具里,用完全不同的格式。探索阶段的工作永远是一次性的。

这就是我想填补的空白。

"GUI 优先"探索的问题

没错,Postman 已经解决了一部分。如果你只是想发个请求、看看响应,它够用了。

但一旦工作流变得真实起来,我希望探索阶段写的东西本身就是代码:能进 git 的代码、能在 PR 里 review 的代码、能用普通 npm 包的代码、能在 CLI 和 CI 里跑的代码。

现在这一点更重要了,因为代码和 AI 工具配合得更好。AI agent 生成、编辑、重构 TypeScript 比维护一个点击式 UI 工作流容易得多。

核心想法:探索和测试应该是同一个工作流

如果探索和测试是同一件事呢?

不是"把 Postman collection 导出为测试"。不是"录制回放"。而是:在一个真正的代码文件里写一个检查,一键运行,然后保留它。

Scratch mode 演示

TypeScript 作为探索工具,你能得到:

  1. 完整的 npm 生态: 需要随机 UUID?crypto.randomUUID()。需要模拟用户?用 faker
  2. 类型安全: IDE 会在你点"运行"之前告诉你拼错了 header 或参数。
  3. 可重构: 想在 50 个测试里改一个 URL?Cmd+F 替换。这就是普通代码——不需要特殊的脚本沙箱。

我做了什么:Glubean

我构建了一个工作流,让"我只是试试"和"我应该保留这个测试"之间的距离尽可能小。

一个测试,一次点击,一条 trace:

import { test } from "@glubean/sdk";

export const getUser = test("get-user", async (ctx) => {
  const res = await ctx.http.get("https://dummyjson.com/users/1");

  ctx.expect(res).toHaveStatus(200);
  const body = await res.json();
  ctx.expect(body.id).toBe(1);
});

如果你用过 Jest 或 Vitest 的 VSCode 插件,你知道每个测试旁边会出现一个播放按钮。这里也一样——我点击它,测试运行,一个 Trace Viewer 直接在 VSCode 里打开。

你能看到请求方法、URL、状态码,以及完整的请求/响应体。感觉像 Postman,但驱动它的是你正在编辑的文件。

Explore 模式 — 运行测试并查看结果

真实工作流——共享状态、步骤、npm 包:

当我有一个值得保留的检查时,我点击文件级播放按钮,得到一份真正的结果报告。这也是工作流开始和 Postman 不同的地方。

不再是 UI 里的一个保存请求,而是普通的 TypeScript:我可以用 builder API 构建多步骤流程,并在步骤之间传递状态。如果某一步失败,后续步骤自动跳过。

import { test } from "@glubean/sdk";

const API = "https://dummyjson.com";
let userId;

// 简单测试——获取一个已知用户
export const getUser = test("get-user", async (ctx) => {
  const res = await ctx.http.get(`${API}/users/1`);
  ctx.expect(res).toHaveStatus(200);
  const body = await res.json();
  userId = body.id;
  ctx.log(`Loaded user: ${body.firstName} ${body.lastName}`);
});

// Builder 测试——读取共享的 userId,运行多步骤验证
export const verifyAndUpdate = test("verify-and-update")
  .step("检查用户资料", async (ctx) => {
    const res = await ctx.http.get(`${API}/users/${userId}`);
    ctx.expect(res).toHaveStatus(200);
    const body = await res.json();
    ctx.expect(body.firstName).toBeDefined();
    return { originalName: body.firstName };
  })
  .step("更新用户名", async (ctx, { originalName }) => {
    const res = await ctx.http.put(`${API}/users/${userId}`, {
      json: { firstName: "Updated" },
    });
    ctx.expect(res).toHaveStatus(200);
    ctx.log(`Renamed ${originalName} → Updated`);
  });

注意: 同一文件中的测试共享模块作用域,按 export 顺序执行——getUser 先跑并设置 userIdverifyAndUpdate 再使用。共享变量应在模块顶层声明,但只在测试回调内部赋值。详见限制说明

Builder 的 .step() 链在单个测试内部传递状态。当我运行整个文件时,结果报告会展示每一步的状态和耗时。

这只是 SDK 功能的一小部分——还有 schema 验证、数据驱动测试、自定义指标、重试、浏览器/GraphQL/gRPC 插件支持等等。但这篇文章的重点是工作流,不是功能清单。

我在探索阶段写的代码已经是测试代码了。我不需要重写或者转换格式。这就是我想做对的事情。

Fix 工作流 — 迭代直到全绿

为什么这很重要:"摩擦税"

旧工作流的真正成本不只是重写花的时间。而是那些你根本懒得变成测试的东西,因为摩擦太大了。

你在探索时检查了一个边界情况(比如"价格为负数会怎样?"),没问题,你继续往前走了。两个月后它坏了。没人发现,因为那个检查是终端历史里的一条 curl 命令,或者 Postman 里一个忘记保存的临时标签页。

如果写检查和保留检查是同一个动作,更多检查就能存活下来。

从 VSCode 到 CI

因为它就是代码,这些文件在 CLI 和 CI 里不做任何修改就能运行。

glubean run tests/

我不想本地探索一种格式、自动化又是另一种格式。不再需要"导出 JSON"或"同步 collection"。你的测试就在它们该在的地方:在你的仓库里,在你的源代码旁边。

同一个文件,终端和 CI 里同样能跑——不需要转换,不需要导出:

# 同一个文件,同样的断言——现在在终端或 CI 管道里跑
# result.json 包含的 trace 和 VSCode Result Viewer 里看到的完全一样
npx glubean run explore/dummyjson/smoke.test.ts --verbose --emit-full-trace --result-json ./smoke.result.json

在 VSCode 里打开任何 .result.json 文件,Glubean 扩展会自动用 Result Viewer 渲染——即使测试是用 CLI 跑的,你也能用完整的可视化界面查看 trace、assertions 和 events。

现在的状态

我正在以 Glubean 的名字构建这个项目——一个免费开源的 SDK + CLI + VSCode 扩展。核心工作流免费:本地 VSCode 运行、CLI 和 CI。Cloud 上传是可选的,起步有免费额度。它的设计也让平台不需要知道你的密钥,但这是另一个话题,值得单独写一篇。项目还很早期,但它已经彻底改变了我开发 API 的方式。我也在探索一个更激进的 closed-loop 方向:不只是让 AI 帮你写检查,而是把失败后的处理尽量推向自愈工作流。这也是为什么我越来越坚定地认为,Glubean 应该长成 SDK + MCP 这个形状,不过这个话题我留到下一篇单独展开。

如果你想试试:

  1. 安装 Glubean VSCode 扩展。安装后可能需要重新加载 VSCode 窗口。
  2. 创建一个 .test.js 文件(不需要项目配置——只要一个文件)。
  3. 写一个 ctx.http.get(),然后点击播放按钮。

关于 scratch mode 的限制(TypeScript 类型错误、无 .env 支持),请参阅限制说明

就是这样。打开一个测试文件,写一个请求,点击播放。

如果你想要可运行的示例而不是玩具代码片段,我还整理了一个 cookbook 仓库,里面有你 npm install 后就能在 VSCode 里运行的模式。

如果你还在 Postman 和测试套件之间来回切换,我很想听听是什么让你留在那里。