mcpField
G
glubean

glubean

github.com/glubean测试与质量140 次安装11 周前更新
代码仓库

关于 glubean

glubean 是面向使用 Glubean 进行 API 测试的 Agent 的实践指南,涵盖项目设置、验证和迁移。它根据任务意图与仓库状态选择流程,并提供测试编写和执行规则。

主要功能

  1. 01区分文档、设置与项目任务
  2. 02行动前检查仓库上下文
  3. 03指导 API 测试与契约编写
  4. 04涵盖迁移、负载和浏览器测试
  5. 05规范密钥与身份验证处理

适用场景

  1. 01在新项目中设置 Glubean
  2. 02为现有 API 编写验证测试
  3. 03设计先行地定义 API 行为
  4. 04添加负载或扩展测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/glubean/skill --skill glubean

安装后在 Claude Code 中输入/glubean确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
ci-workflow.md
cli-reference.md
cloud-onboarding.md
contract-first.md
diagnose.md
docs-index.md
docs-mode.md
implementation-derived-verification.md
index.md
load-testing.md
mcp.md
onboarding.md
references/patterns/
assertions.md
attachment-model.md
auth.md
browser.md
builder-reuse.md
case-execution.md
cloud-diagnosis.md
configure.md
context-setup.md
contract-browser.md
contract-first.md
crud.md
data-driven.md
errors.md
graphql.md
init-project.md
metrics.md
migration.md

详细介绍

Glubean

将此技能用作 Glubean 最佳实践指南。默认采用真实项目工作流。Scratch 模式是用于快速演示扩展功能的路径,并非 Agent 的常规路径。

模式

  1. 文档:产品问题、概念、比较、迁移、编辑器支持或云功能。
  2. 入门:尚无 Glubean 项目;用户需要扩展、MCP、cookbook 或项目初始化指导。
  3. 项目:用户已在 Glubean 项目中,或明确希望开展真实项目测试工作,包括从现有 API 资产迁移。

先确定路径

选择模式之前:

  • 检查是否存在 package.json、config/、schemas/、contracts/、tests/、explore/、.env、.env.secrets 和 GLUBEAN.md。
  • 检查依赖项或开发依赖项中是否已包含 @glubean/sdk。
  • 检查是否有可用的 MCP 工具。
  • 如果存在 GLUBEAN.md,先将其作为项目上下文文件读取。
  • 用户应在其中保留关键上下文,包括相关代码、文档、规范和同级工作区的位置。
  • 如果用户明确提供了其他上下文位置,也要先读取这些内容,再根据 API 猜测。

然后根据意图和环境确定路径:

意图示例

  • 文档
    • “Glubean 是什么?”
    • “Glubean 与 Postman 相比如何?”
    • “如何在 CI 中运行测试?”
    • “如何从 Postman 迁移?”(从 patterns/migration.md 中获取答案)
  • 入门
    • “为我的项目设置 Glubean”
    • “我想试试 Glubean”
    • “为 Cursor 配置 MCP”
  • 迁移(跨领域——执行请求,路由前先询问)
    • “迁移我们的 Postman 集合”
    • “转换我们的 Apifox 或 OpenAPI 导出文件”
    • “将这些旧 API 测试移植到 Glubean”
    • → 询问:“为此设置一个新的 Glubean 项目,还是添加到当前项目中?”
    • → 新项目 → 入门 → init → 迁移模式
    • → 当前项目 → 项目 → test-after → 迁移模式
  • 项目 — 简单模式(默认,test-after)
    • “为 /users 编写冒烟测试”
    • “提高我的测试覆盖率”
    • “修复这个失败的测试”
    • “添加认证边界测试”
    • → 对于现有行为,阅读 implementation-derived-verification.md;使用 explore/ 或 tests/ 中的 test() 提供最终的命令式证据
  • 云端诊断
    • “这次 Glubean 运行为什么失败了?”
    • “诊断这次 Cloud 运行:clr_...”
    • “获取这次已上传 CI 运行的失败信息”
    • → 在获取 Cloud 运行数据前,阅读 references/patterns/cloud-diagnosis.md
  • 项目 — 基于实现的验证
    • “为这个现有端点编写测试”
    • “从这个 API 实现生成契约”
    • “提高覆盖率,不要让我列出每个用例”
    • → 检查路由/控制器、验证、认证、领域/服务分支、持久化约束、错误映射和现有测试
    • → 推导出行为/用例矩阵;除非用户明确要求冒烟测试,否则不要默认只编写一个正常路径或仅检查状态的用例
    • → 将稳定承诺表达为契约,将生命周期承诺表达为 workflow(),将命令式证据表达为 test()
  • 项目 — 契约优先模式(高级,新的结构化规范)
    • “我需要一个带 CRUD 的 users API”
    • “在我实现之前设计计费端点”
    • “为我们尚未实现的 API 编写契约”
    • “我的契约覆盖率是多少?”
    • “生成投影报告”
    • → 仅在定义新行为时将其视为设计优先;在采用简单模式默认值之前阅读 contract-first.md
    • → 使用 contract.http.with() 表达端点承诺,使用 workflow() 表达生命周期承诺
    • → 仅当用户明确要求契约或项目已有 contracts/ 时使用
  • 项目 — 负载测试(选择启用;并发下的性能)
    • “以 100 个并发用户对 /checkout 进行负载测试”
    • “负载下的 p95 / 吞吐量是多少?”
    • “在 CI 中添加性能门禁”
    • → 阅读 references/load-testing.md;使用 loadScenario() + loadRunner() + 阈值编写 *.load.ts,通过 glubean load <file|dir|glob> 运行;仅在用户有意上传到 Cloud 时添加 --upload / --upload-target
    • → 仅在用户选择启用时执行——这会生成真实的并发流量;常规功能覆盖期间绝不自动编写负载测试
  • 项目 — 浏览器和 Chrome 扩展测试
    • “测试我已解压扩展程序的选项页、内容脚本或 Side Panel”
    • “证明工具栏操作可以打开和关闭原生 Side Panel”
    • → 阅读 references/patterns/browser.md;对扩展程序支持的页面使用 createExtensionTest(),并将直接文档渲染证明与原生工具栏操作生命周期分开

全局规则

除非项目特定指令另有规定,否则请遵循以下规则:

  1. 密钥放在 .env.secrets 中;公开配置放在 .env 中。有关多环境设置,请阅读 references/patterns/multi-env.md。
  2. 使用 configure() 创建共享 HTTP 客户端,然后在测试中使用导出的客户端(例如 api),不要使用 ctx.http。ctx.http 仅用于临时演示。
  3. 环境变量和密钥插值使用 {{KEY}},字面值使用裸字符串。
  4. 为每个测试添加标签。
  5. 当 test() 需要 teardown、多步骤状态传递、运行时分支或运行时轮询时,使用 builder 模式。
  6. 使用 kebab-case 测试 ID,并确保在整个项目中唯一。
  7. 将每个面向人的可读测试字符串都视为诊断信息。用例标题、测试名称、步骤名称、schema 标签、断言消息、警告和日志都应说明正在检查的不变量或业务规则。避免使用“有效”“正常”“检查响应”或“应该通过”等泛泛标签。
  8. 使用 ctx.assert 时,不要省略消息。消息应具体到足以诊断故障;当断言比较运行时值时,传入 { actual, expected }。如果 ctx.expect(...) 的 matcher 已能生成结构化的实际值和预期值输出,则优先使用。
  9. 在实际项目中,将可复用的响应类型放在 types/ 中。仅在用户明确要求的极小临时示例中内联定义。
  10. 不要使用 .json<any>()。如果响应形状仍未知,先使用 .json<unknown>()。只有在已知顶层值是对象时,才使用 Record<string, unknown>。一旦字段已知,就尽快收窄为实际类型或 Zod。
  11. 在实际项目中,将可复用的 Zod schema 放在 schemas/ 中。仅在用户明确要求的极小临时示例中内联定义。
  12. 仅当每个用例都调用同一个端点或采用相同的操作模式时,才使用 test.each 和 test.pick。如果端点互不相关,就分别编写导出的测试。测试 ID 必须包含 $field 或 $_pick 占位符,以便每个用例在运行时获得唯一 ID(例如 "search-$q"、"user-$_pick")。
  13. **目标首次需要身份验证且尚未配置身份验证时,先停止编写基础身份验证配置,并向负责人询问身份验证详情。**触发条件是:目标存在身份验证边界,且尚无已确认的身份验证配置覆盖该边界——401/403、Authorization / Cookie 标头、登录/令牌端点、受保护的路由,或 OpenAPI/spec 中的 security 方案都表明存在此边界。不要猜测身份验证方案,也不要为了“先跑起来”而编写跳过身份验证的测试。先说明你的判断——采用哪种策略(bearer / apiKey / login-exchange)、标头和密钥名称、凭据的来源,以及每项判断的依据——然后等待负责人确认、纠正或补充缺失信息。**一旦目标已有身份验证配置(已设置 configure() 客户端、密钥已放入 .env.secrets,或 GLUBEAN.md 记录了身份验证决策),就静默复用,不要针对每个 contract 或测试重复询问。**绝不要根据猜测静默配置身份验证。
  14. 不要向用户复述密钥值。在生成的代码和配置中保留 {{KEY}} 占位符,不要替换为解析后的值;在聊天中引用 CLI 输出或响应正文时,删除或遮蔽 Authorization 标头、Cookie / Set-Cookie 值以及任何类似令牌的字段(bearer 令牌、API 密钥、会话 ID)。如果用户分享了看起来经过脱敏的字符串(例如 sk-****),不要尝试恢复原值,也不要根据上下文猜测完整值。
  15. 如果缺少核心项目结构,不要手动创建脚手架。已知目标目录/基础 URL 时,建议运行 npx glubean@latest init --no-interactive;用户想使用交互式提示时,建议运行 npx glubean@latest init。
  16. 用户确认项目级决策(身份验证策略、上下文位置、命名约定、业务规则)后,建议将其添加到 GLUBEAN.md,以便后续会话使用。
  17. 使用 GLUBEAN.md 记录项目级业务规则、角色/状态语义和命名决策。不要在其中手动维护端点矩阵、状态表、请求/响应形状或用例清单;这些内容应放在 contracts/ 中,并通过 projection 或 Cloud 呈现。
  18. 使用顶层 workflow() 编写生命周期 spec。contract.http.with() 定义端点行为;workflow() 使用 call() / poll() 和带类型的状态组合已有的 contract 用例;对于不值得进行 projection 的情况,test() 仍是命令式运行时的备用方案。
  19. 不要在 contract 用例中放置 setup / teardown。Contract 用例是语义承诺(description、given、needs、expect、verifyRules、runnability)。运行时设置/清理应根据具体问题放在 contract.bootstrap() overlays、defineSession()、workflow().setup/teardown() 或 test() builder 的 setup/teardown 中。
  20. 上传和同步应分开进行。glubean run --upload / glubean load ... --upload 会发送目标范围的证据。glubean sync 会发送项目范围的源代码 projection,用于 Specifications/OpenAPI/Agent 上下文,且不会运行测试。
  21. 当前 Cloud 代码使用 runs:write 控制 glubean sync 的 projection 写入,尽管令牌目录中包含了原本用于 contracts/sync 范围的 contracts:write。应先说明实际行为;在需要精准说明时,指出范围不匹配。
  22. Contract 编写的源代码会原样发布供审核——绝不要在 contract 声明中内联密钥。glubean ≥ 0.10.2 的 sync 会原样捕获每个 contract 的 export const … = contract.…(…) 代码片段(包括 verify 函数体),并将其不经脱敏地上传到 Cloud 的 Specs“Source”视图——这正是设计目的:审核者要阅读真实的 contract,因此声明中的内容都不会被遮蔽。所有凭据都必须放在代码片段之外:将真实密钥放入 .env.secrets,并通过 {{KEY}} / ctx.vars.require("KEY") 引用;将具体的非密钥值(ID、主机名)放在文件顶部的 const 中,并通过名称引用——两者都只会以符号而非值的形式进行 projection。写在 contract 对象中的字面令牌/cookie/密码都会被发布。
  23. 每个 contract 用例的 verify() 都必须配有 verifyRules——每条断言对应一项,每项都必须是完整的业务陈述,说明该断言强制执行的规则(例如 "the returned project id matches the active dogfood project",而不是 "id ok")。verify() 是运行时闭包:projection 只能记录它存在(hasVerify),因此没有 verifyRules 时,审核界面只会显示含糊的“custom assertions run”提示,审核者必须切换到源代码查看。Cloud 的 Specs 用例卡片会将 verifyRules 作为用例的 Verify 步骤呈现,位置就在审核者阅读承诺的地方——应将其写成面向审核者的 verify 函数体规范,并在断言变更时保持同步。没有 verifyRules 的 verify() 会造成审核界面缺漏,与没有 description 的 test() 属于同一类问题(规则 25)。规则需要稳定标识或单独严重性时,使用对象形式({ id, description, severity });否则使用普通字符串即可。
  24. Contract ID 是操作的标题,不是命名空间。应使用简短且能描述操作的短语——发挥 OpenAPI summary 的作用:list-projects、get-project、sign-in-with-email、validate-run-upload。绝不要使用点分隔的命名空间关键词堆叠(platform.projects.list)——带作用域的实例名称、feature、tags 和 endpoint 已经体现层级,点分隔的 ID 只是重复这些信息,读起来像内部机制而非实际含义。采用 kebab-case(规则 6),并确保在整个项目中唯一(两个服务公开相同操作时,使用具有描述性的名称加以区分:platform-health-check 与 dashboard-health-check)。ID 是 contract 的身份标识——它会映射到 OpenAPI operationId、关联运行证据并作为修订历史的键,因此之后重命名会导致历史记录失联:一开始就取好标题。
  25. 审核界面的优先顺序:测试 description(第 1 位,最重要),然后是每条断言的 message(第 2 位)——两者都必须完整,不得使用简写。Cloud 的 Specs 视图会在不运行测试的情况下将测试投影供审核:只显示测试 description、断言的消息、ctx.when/switch/while 分支的 describe 标签、tags 和端点——不会投影运行时值(这些值保存在运行证据中,并通过 testId 关联)。因此:
    • description 是审核者首先看到的标题——为每个测试都提供一条完整的一行说明,阐明整个测试验证什么("Authenticate; verify the session contract on success and the rejection contract on failure"),绝不要重复 testId、写成 "tests login" 或留空。
    • 每条断言的 message 都是该项检查的说明,也是唯一能说明该检查验证什么的内容。每条断言都必须有一条完整、自包含的结果陈述,可单独审核且不带任何缩写:"a valid session token is returned",而不是 "has token";"a missing order returns 404, not a 500",而不是 "404 ok"。简短标签、对代码的简单复述或空消息都会导致测试无法审核。 在 matcher 适用时,优先使用 ctx.expect(...).matcher(expected, "message"),而不是只用 ctx.assert(cond, "message")(matcher 名称本身——expect.toBe、expect.toContain、expect.toHaveProperty——会以语义结构呈现)。使用 ctx.when/switch/while(每个都带有 describe),而不是裸写 if/for/while`,这样每种结果的意图都会被呈现,而不只是实际执行到的分支。
  26. 对 .track("METHOD /path") 原始 ctx.http 调用进行标注,使其按端点审核。Cloud 的 Specs 视图按端点(API 表面)组织内容:每个端点都会汇集其 contract、调用该端点的测试,以及调用该端点的工作流,并标记覆盖缺口。运行 CONTRACT 用例的测试会自动关联(用例本身已包含端点信息)。但原始 ctx.http.get(/users/${id}) 会投影其字面 URL(/users/123),导致覆盖索引无法与 contract 的 GET /users/:id 对应,并让端点列表充斥一次性路径。因此,无论何时使用原始 ctx.http(临时/备用路径——根据规则 2,应优先使用已配置的客户端或 contract 用例),都应固定规范端点:await ctx.http.get(/users/${id}).track("GET /users/:id")。使用与 contract 文档完全相同的 METHOD /path 字符串,以便测试归入同一个端点条目。(如果字面 URL 已是规范路径,例如 GET /users,则 .track() 可选。)
  27. 声明 contract 的完整请求和响应形状,而不只是状态码。Cloud 会将每个 contract 呈现为 OpenAPI 操作(即发布的 API 参考视图):路径/查询/标头参数、请求正文和响应——包括每个字段的约束标签(format、enum、minLength/maximum、required)以及逐字段的 description。只声明 expect: { status } 的 contract 会投影出几乎空白的操作,无法审核。因此,对于会写入或读取正文的 contract,应声明带有约束的形状:
    • 在 contract 级别声明请求正文和请求标头:request: { body: <SchemaLike>, headers: <SchemaLike>, contentType }(裸写 request: <SchemaLike> 是正文的简写形式)。正文 schema 是 OpenAPI requestBody 的来源。
    • 为每个用例声明查询参数和路径参数:query: { page: { value, schema, description, required }} 和 params: { id: { value, schema, description }}(携带 schema 和 description 的是 ParamValue 对象,而不是裸字符串;路径参数会自动设为必填)。
    • 为每个用例声明响应正文和响应标头:expect: { status, schema: <SchemaLike>, headers: <SchemaLike>}。 使用真正的 SchemaLike({ safeParse, toJSONSchema } 返回带有 format/enum/范围/description 的 JSON Schema,或 Zod schema)——仅作为类型占位符的写法({} as SchemaLike<T>)不会投影出任何内容(requestBody 为空)。schema 的约束就是审核者要阅读的 contract。
  28. 每个不透明的工作流节点都必须有真实的 description。compute/action 节点会被投影为 opaque(无法静态呈现其转换/IO 逻辑),因此节点的 description 是审核者唯一能用来理解该步骤的内容——一个不透明节点就会使整个工作流的 projection 变为不完整。绝不要只给不透明节点一个两个词的名称:传入 { id, description },而不是字符串 ID——b.compute({ id: "mark-seed", description: "Mark the run as needing a seed user (sets state.seed=true) so a later step provisions the first account." }, (s) => ...)。description 能在不完整的 projection 中补足结构无法呈现的语义。
  29. 每个项目都必须通过 typecheck + lint,不能只看运行是否成功。glubean run 通过 tsx 执行——它不会进行类型检查,因此 contract 可以运行成功,但被 tsc 拒绝。并且 tsc 完全没有弃用诊断(@deprecated 只会在编辑器中显示删除线)——唯一能通过 CLI/CI 检测弃用项的方式是 ESLint 的 @typescript-eslint/no-deprecated。Glubean 使用 Zod 4,其弃用 API(.passthrough()、z.string().uuid()/email()/datetime())恰好是 Zod 3 时代代码所使用的 API,可能导致项目在不知不觉中逐渐腐化。因此,应确保项目有 npm run typecheck(tsc)和 npm run lint(eslint no-deprecated),并在宣布“完成”前同时运行两者,连同运行结果报告各自的退出码 0。如果项目缺少这些检查——包括较早版本的 glubean init 输出——就补上检查门禁(tsconfig + eslint.config.js + scripts + devDeps)。将 verify 写成 async verify(ctx, res: T),并使用 Zod 4 写法(z.email()/z.uuid()/z.iso.datetime()、.loose())。完整指南和改造步骤见:references/patterns/type-safety.md。
  30. 验证现有行为时,默认应根据实现推导验证内容。编写测试或 contract 前,请阅读 references/implementation-derived-verification.md。检查可访问的源代码和现有测试,推导有意义的成功、验证、身份验证、状态、冲突和错误用例,并将发现的每条规则映射到已执行的证据或明确记录的缺口。请求/响应 schema 或 OpenAPI projection 只能记录约束,不能证明实现会强制执行该约束。只有在用户明确要求 smoke 测试时,才只生成可达性/状态检查用例。
  31. 按响应状态码升序排列 contract 的 cases,并将成功路径放在最前面。用例在所有审核界面中都按源码顺序呈现——Cloud 的 Specs 用例卡片、MCP x-glubean-cases 和 projection 都是如此——因此用例达到 10 个或以上时,零散的顺序会掩盖成功路径,审核者也必须费力寻找。按 expect.status 升序排列用例(先放 2xx 成功,再按递增顺序放 4xx:400 → 401 → 403 → 404 → 409 → 422,最后放 5xx);同一状态下按常见程度从常见到极端排列(先放日常验证失败,再放罕见边缘情况)。成功用例是 2xx,因此始终会排在最前。遵循规则 23–28 的同类审核界面规范:读者应能沿着操作主线依次了解如何访问、如何成功以及如何按可预测的顺序失败,而不必通读整个代码块。(用例存在生命周期依赖时——例如后续用例会复用一个 deferred seed——应确保依赖关系清晰易读;排序是默认做法,不应因此打乱必要的执行顺序。)
  32. **使用 discover 获取资源清单,并在发布到 Cloud 前运行 doctor。**优先使用 glubean init 生成的包脚本:npm run discover 会写入资源目录;npm run doctor 会以只读方式检查资源、令牌/项目/范围/目标的就绪状态;npm run sync 会明确使用 .env 并发布项目范围的源代码 projection;npm run upload 会运行本地 profile 并上传目标范围的证据。doctor 检查成功并不代表获准运行 sync/upload——它只证明已就绪。绝不要将 sync 和 upload 合并为一个操作,也不要仅仅因为 doctor 检查通过就进行发布。 如需详细导航,请从 references/index.md 开始。

如需在实际项目中进行迁移,请先阅读 references/patterns/migration.md,然后再生成文件。

如果提供了 $ARGUMENTS,请将其视为目标端点、文件、标签或自然语言测试请求。

评论

支持 Markdown