关于 reproduce-bug
面向 n8n 开发者的测试技能,可依据 Linear 工单调查缺陷并编写失败的回归测试。它按受影响区域选择测试层级,最后生成带置信度的报告;流程明确不修复缺陷。
主要功能
- 01解析工单信息与受影响区域
- 02选择测试层级和模式
- 03追踪代码并提出假设
- 04编写并运行失败的回归测试
- 05报告复现置信度与结果
适用场景
- 01复现节点或服务缺陷
- 02为编辑器或 API 问题选择测试
- 03检查当前代码是否仍有回归
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ n8n-io/ n8n --skill reproduce-bug安装后在 Claude Code 中输入/reproduce-bug确认已加载。
详细介绍
Bug 复现框架
给定 Linear 工单上下文($ARGUMENTS),系统地复现 bug, 并编写一个失败的回归测试。
步骤 1:解析信号
从提供的工单上下文中提取以下信息:
- 错误消息 / 堆栈跟踪(如果提供)
- 复现步骤(如果提供)
- 工作流 JSON(如果附有)
- 受影响的区域(节点、执行引擎、编辑器、API、配置等)
- 出问题的版本 / 最后一个正常工作的版本
步骤 2:选择测试策略
根据受影响的区域,选择测试层级和模式:
| 区域 | 测试层级 | 模式 | 关键位置 |
|---|---|---|---|
| 节点操作 | Jest 单元测试 | NodeTestHarness + nock | packages/nodes-base/nodes/*/test/ |
| 节点凭据 | Jest 单元测试 | jest-mock-extended | packages/nodes-base/nodes/*/test/ |
| 触发器 webhook | Jest 单元测试 | mock IHookFunctions + jest.mock GenericFunctions | packages/nodes-base/nodes/*/test/ |
| 二进制数据 | Jest 单元测试 | NodeTestHarness assertBinaryData | packages/core/nodes-testing/ |
| 执行引擎 | Jest 集成测试 | WorkflowRunner + DI container | packages/cli/src/__tests__/ |
| CLI / API | Jest 集成测试 | setupTestServer + supertest | packages/cli/test/integration/ |
| 配置 | Jest 单元测试 | GlobalConfig + Container | packages/@n8n/config/src/__tests__/ |
| 编辑器 UI | Vitest | Vue Test Utils + Pinia | packages/frontend/editor-ui/src/**/__tests__/ |
| E2E / Canvas | Playwright | 测试容器 + composables | packages/testing/playwright/ |
步骤 3:定位源文件
找到受影响区域的源代码:
- 搜索工单中提到的节点 / 服务 / 组件
- 找到 GenericFunctions 文件(节点 bug 的常见位置)
- 检查同一区域是否有现存的测试文件
- 查看受影响文件最近的 git 历史(
git log --oneline -10 -- <path>)
步骤 4:追踪代码路径
阅读源代码并追踪触发 bug 的执行路径:
- 从入口点沿调用链追踪到故障位置
- 找出 bug 显现的具体代码行
- 留意 bug 周围的错误处理(或缺少的错误处理)
步骤 5:提出假设
明确提出可测试的假设:
- “当 [输入 / 条件] 时,代码会因 [根本原因] 而执行 [错误行为]”
- 找出需要修改的确切代码行
- 预测测试会显示什么结果
步骤 6:查找测试模式
查找同一区域现有的测试:
- 检查受影响代码附近的
test/目录 - 确认它们使用的 mock / 设置模式
- 使用相同模式以保持一致
- 如果没有测试,则找最相似的节点 / 服务测试作为模板
步骤 7:编写失败测试
编写回归测试,要求:
- 使用步骤 6 中找到的模式
- 针对步骤 5 中提出的具体假设
- 添加注释,引用工单 ID
- 断言正确行为(测试在当前代码上会失败)
- 另外编写一个“正常路径”测试,以证明测试设置有效
步骤 8:运行并评分
从包目录运行测试(例如,cd packages/nodes-base && pnpm test <file>)。
对结果进行分类:
| 置信度 | 标准 | 输出 |
|---|---|---|
| CONFIRMED | 测试稳定失败,且失败情况符合假设 | 复现报告 |
| LIKELY | 测试失败,但失败模式略有不同 | 报告 + 注意事项 |
| UNCONFIRMED | 无法触发故障 | 报告:尝试过的内容 |
| SKIPPED | 触发了硬性中止条件 | 报告:跳过原因 |
| ALREADY_FIXED | 当前代码已无法复现 bug | 报告:修复时间 |
步骤 9:迭代或放弃
如果首次尝试后仍未确认:
- 重新审视假设——再次阅读代码路径
- 尝试不同的测试方法或层级
- 最多尝试 3 次,然后再将结果声明为未确认
必须立即放弃的情况(立即停止):
- 需要真实的第三方 API 凭据
- 存在竞态条件/依赖时序
- 需要特定的云/企业基础设施
- 需要无法脚本化的手动 UI 交互
输出:复现报告
按以下格式呈现调查结果:
工单: [ID] — [标题] 置信度: [已确认 | 很可能 | 未确认 | 已跳过 | 已修复]
根本原因
[用 1-2 句话说明 Bug 的触发机制]
位置
| 文件 | 行号 | 问题 |
|---|---|---|
path/to/file.ts | XX-YY | 问题描述 |
失败的测试
path/to/test/file.test.ts — X/Y 个测试失败:
test name— [失败描述]
修复提示
[伪代码或修复方案描述]
重要事项
- 不要修复 Bug——只需通过失败的测试复现
- 保留测试文件作为证据(除非有人要求,否则不要提交)
- 在包目录中运行测试(例如,
pushd packages/nodes-base && pnpm test <file> && popd) - 始终重定向构建输出:
pnpm build > build.log 2>&1 - 不要查看现有的修复 PR——目标是仅凭信号复现问题
评论
支持 Markdown