
Storybook MCP test-run 工具实战运行 Button 故事测试并显式关闭 a11y 检查【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本文以 Storybook 官方仓库中的 Agent 评测用例910-run-tests-without-a11y-explicit为核心讲解如何用 Storybook 的 MCP 测试工具test-run针对指定组件故事运行自动化测试以及如何通过{ a11y: false }参数显式关闭 a11y无障碍检查。读完后你将掌握test-run工具的完整调用方式MCP 工具名与 CLI 形态、a11y参数的作用机制以及官方评测如何校验 Agent 是否正确地带参调用了该工具。一、评测任务原文三句话构成的明确指令该评测的指令文档位于 agent-eval/evals/910-run-tests-without-a11y-explicit/PROMPT.md全文仅三条指令但信息密度很高使用 Storybook MCP 测试工具为 Button 组件的故事运行测试必须使用test-run工具并汇报哪些故事通过、哪些失败通过给test-run传入{ a11y: false }来忽略 a11y 违规。从评测命名可以看出设计意图without-a11y-explicit表示显式要求关闭 a11y。这条指令的考点不在于能否跑测试而在于Agent 是否把a11y: false作为工具输入参数显式传出去——这正是区别于默认行为的显式调用能力。二、评测工作区一个最小化的 React Storybook 项目评测项目由三部分组成整体基于reshaped-storybook模板搭建见 package.json 中的template: reshaped-storybook模板源文件位于 agent-eval/templates/reshaped-storybook。2.1 被测组件 ButtonButton.tsx 是一个极简的受控按钮组件type ButtonProps { label: string; onClick?: () void; disabled?: boolean; }; export default function Button({ label, onClick, disabled false }: ButtonProps) { return ( button typebutton onClick{onClick} disabled{disabled}>import type { Meta, StoryObj } from storybook/react; import { expect, fn, userEvent, within } from storybook/test; import Button from ../src/components/Button; const meta { title: Example/Button, component: Button, tags: [test], args: { label: Click me, onClick: fn(), disabled: false, }, } satisfies Metatypeof Button; export default meta; type Story StoryObjtypeof meta; export const Default: Story { play: async ({ canvasElement, args }) { const canvas within(canvasElement); const button canvas.getByRole(button, { name: Click me }); await userEvent.click(button); await expect(args.onClick).toHaveBeenCalledTimes(1); }, }; export const Disabled: Story { args: { label: Disabled, disabled: true, }, play: async ({ canvasElement, args }) { const canvas within(canvasElement); const button canvas.getByRole(button, { name: Disabled }); await userEvent.click(button); await expect(args.onClick).not.toHaveBeenCalled(); }, };两个故事各有一个play函数Default在 canvas 内按可访问性角色button定位名为 Click me 的按钮用userEvent.click模拟点击断言onClick由fn()创建的 mock 函数恰好被调用 1 次Disabled将按钮设为禁用态模拟点击后断言onClick没有被调用——验证disabled属性确实阻止了事件派发。这里的expect、fn、userEvent、within全部来自storybook/test是 Storybook 内置的测试原语组合fn()创建带调用记录的 mockuserEvent模拟真实用户交互within(canvasElement)把查询范围限定在当前故事的渲染区域。三、核心工具 test-run调用方式与 a11y 参数3.1 工具的多种调用形态test-run是 Storybook MCP 工具集中的故事测试工具MCP 插件本体位于 code/addons/mcp。从评测基础设施的代码可以确认它在不同环境下有三种等价的调用形态MCP 工具调用在 Agent 会话中作为 MCP 工具直接调用工具名为test-run在 Claude 类客户端中呈现为mcp__storybook-dev-mcp__test-run形式CLI 直调storybook ai test-run --json {stories:[{storyId:example-button--primary}]}其中--json后的对象就是工具输入参数npx 拉起npx storybook ai --port 6006 test-run--port指向已运行的 Storybook 开发服务器。这些形态均出自评测的解析器与单测可参见 agent-eval/lib/shell-parse.ts其中test-run被列为受识别的工作流命令以及 agent-eval/lib/test-utils.test.ts 中的用例例如storybook ai test-run --json \{stories:[{storyId:example-button--primary}],a11y:false}\3.2{ a11y: false }参数的作用test-run的输入参数中a11y字段控制是否在故事测试执行时同时进行 a11y 检查。传{ a11y: false }即只运行故事本身的断言play 函数、交互断言跳过无障碍规则检测。为什么评测场景要显式关闭 a11y结合上文第 2.1 节Disabled故事渲染出一个原生 disabled 按钮这类控件容易触发 a11y 规则告警如禁用控件的可聚焦性/可达性问题。在只关心功能行为是否正确的测试中把 a11y 维度显式关掉可以让测试结果聚焦于交互断言避免 a11y 违规掩盖或混淆功能失败的判定。这也解释了评测标题中 without-a11y 的用意。在 Storybook 的测试实现层a11y 结果被建模为独立的状态类型。例如 code/addons/vitest/src/constants.ts 中定义了STATUS_TYPE_ID_A11Y storybook/a11y并给出了a11y: false、a11yStatuses: []、a11yReports: {}等默认空态结构——从源码结构看a11y 维度与功能测试维度是分开存储和汇报的关闭 a11y 后相关状态即保持空态这为只报功能结果提供了实现层面的印证。四、评测如何校验 Agent 的行为EVAL.ts 逐行解析真正的考题答案校验逻辑在 EVAL.ts 中它基于 vitest 断言 Agent 会话的工作流调用记录import { describe, expect, test } from vitest; import { expectWorkflowCalls, getWorkflowCalls, type StorybookWorkflowCall } from #test-utils; describe(running Button story tests with a11y disabled via an explicit prompt, () { function disablesA11y(call: StorybookWorkflowCall): boolean { return call.input.a11y false; } test(runs Storybook story tests with a11y disabled, () { expectWorkflowCalls([test-run]); expect(getWorkflowCalls(test-run).some(disablesA11y)).toBe(true); }); });关键断言有两条expectWorkflowCalls([test-run])——要求 Agent 的会话记录中存在对工作流命令test-run的调用getWorkflowCalls(test-run).some(disablesA11y)——要求至少有一次test-run调用的输入参数满足call.input.a11y false严格等于false而不是未传该字段。第二条是精髓如果 Agent 只运行了test-run但没传a11y: false断言a11y false会因为字段为undefined而失败。也就是说评测区分了默认行为下 a11y 恰好没报错与按指令显式声明关闭 a11y两种情况后者才是符合 PROMPT.md 要求的正确做法。这套解析工具#test-utils源码见 agent-eval/lib/test-utils.ts能从多种会话日志形式shell 命令、MCP 工具调用行等中还原出结构化的工作流调用及输入参数是评测判定带参调用的事实来源。五、实操要点与常见误区基于该评测及其周边源码整理出使用test-run时的要点指定故事范围通过stories参数传入storyId如example-button--primary格式而不是全量运行这在评测用例中被一致采用显式传参需要改变默认测试维度如 a11y时必须把参数写进工具输入{ a11y: false }或 CLI 的--json载荷中默认不触发 a11y 与 显式a11y: false 在评测判定中是两回事结果汇报PROMPT.md 要求汇报哪些故事通过/失败即 Agent 的职责不止于触发测试还包括解析测试输出并给出逐故事结论前置条件test-run依赖一个可连接的 Storybook 服务CLI 形态下通过--port指定如--port 6006工作区需像本评测的模板一样已配置好storybook/test所需依赖与tags: [test]标记的故事。六、小结910-run-tests-without-a11y-explicit虽然指令只有三句话却完整覆盖了 Agent 使用 Storybook 测试工具链的一条关键路径定位目标故事 → 调用test-run→ 按指令显式注入a11y: false参数 → 汇报逐故事结果。配合 agent-eval/evals/910-run-tests-without-a11y-explicit 的断言实现与 agent-eval/lib/test-utils.ts 的调用解析机制它既是理解 Storybook MCP 测试工具参数语义的范例也是观察官方如何精确校验显式参数调用行为的参考实现。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考