关于 storybook-testing
面向组件开发者的 Storybook 10 测试技能,涵盖交互测试、视觉回归、无障碍检查和 Vitest 集成,也介绍通过 Storybook MCP 插件进行 Agent 测试与预览。
主要功能
- 01CSF3 故事与 play() 测试
- 02Vitest 故事测试
- 03Chromatic TurboSnap 视觉回归
- 04自动化无障碍扫描
- 05故事级模块模拟
- 06基于 MCP 的测试与预览
适用场景
- 01测试组件交互
- 02在 CI 中检查视觉变化
- 03对故事运行无障碍检查
- 04通过 MCP 预览故事
MCP 相关
安装 Storybook 的 @storybook/addon-mcp 后,Agent 可通过 MCP 运行故事测试和无障碍测试,并获取故事预览。该技能介绍了 run-story-tests 和 preview-stories 等工具。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill storybook-testing安装后在 Claude Code 中输入/storybook-testing确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
test-cases.jsonreferences/storybook-addon-ecosystem.mdstorybook-ci-strategy.mdstorybook-migration-guide.mdrules/storybook-chromatic-turbosnap.md_template.mdstorybook-csf3-factories.mdstorybook-a11y-testing.md_sections.mdstorybook-autodocs.mdstorybook-sb-mock.mdstorybook-vitest-integration.mdstorybook-play-functions.md详细介绍
Storybook 测试 — Storybook 10
概述
Storybook 10 将组件测试统一为一个工作流:通过 play() 函数进行交互测试、通过 Chromatic TurboSnap 进行视觉回归测试,以及通过 a11y 插件进行无障碍审计——全部通过 Vitest 运行。故事是可执行的测试规范,而不只是文档。
Storybook 10 的新功能(对比 9):
- 强制仅使用 ESM——唯一的重大变更;需要 Node 20.16+ / 22.19+ / 24+;安装体积缩小 29%
- 模块自动模拟(
sb.mock)——在构建时模拟模块,在 preview.ts 中按项目配置作用域 - CSF 工厂函数(React,preview)——
defineMain→definePreview→preview.meta()→meta.story()调用链 - 核心内置必要插件——viewport、controls、interactions、actions 不再是独立依赖
- 导入路径变更——
@storybook/test→storybook/test(旧路径仍可作为别名使用) - 支持 React Server Component 故事——可独立测试 RSC
- 支持 Vitest 4——
experimental-addon-test重命名为addon-vitest
适用场景:
- 使用 TypeScript 编写 CSF3 格式的组件故事
- 使用
play()函数设置交互测试 - 使用 TurboSnap 配置 Chromatic 视觉回归测试
- 在故事级别使用模块自动模拟
- 通过 a11y 插件在 CI 中运行无障碍测试
- 使用 autodocs 生成动态文档
- 从 Storybook 9 迁移到 10
快速参考
| 规则 | 影响 | 描述 |
|---|---|---|
storybook-csf3-factories | HIGH | 使用 satisfies Meta 的类型安全 CSF3 故事工厂 |
storybook-play-functions | CRITICAL | 使用 play() 和 @storybook/test 进行交互测试 |
storybook-vitest-integration | HIGH | 通过 @storybook/addon-vitest 将故事作为 Vitest 测试运行 |
storybook-chromatic-turbosnap | HIGH | TurboSnap 可将快照成本降低 60-90% |
storybook-sb-mock | HIGH | 使用 sb.mock 在故事级别模拟模块 |
storybook-a11y-testing | CRITICAL | 在 CI 中自动运行 axe-core 无障碍扫描 |
storybook-autodocs | MEDIUM | 根据故事自动生成文档 |
Storybook 测试金字塔
┌──────────────┐
│ Visual │ Chromatic TurboSnap
│ Regression │ (snapshot diffs)
├──────────────┤
│ Accessibility│ @storybook/addon-a11y
│ (a11y) │ (axe-core scans)
├──────────────┤
│ Interaction │ play() functions
│ Tests │ (@storybook/test)
├──────────────┤
│ Unit Tests │ Vitest + storybookTest
│ (stories) │ plugin
└──────────────┘
每一层都能发现不同的缺陷:单元测试验证逻辑,交互测试验证用户流程,无障碍测试发现无障碍违规,视觉测试发现意外的 UI 回归。
快速入门
带 Play 函数的 CSF3 故事
// Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react'
import { expect, fn, userEvent, within } from 'storybook/test'
import { Button } from './Button'
const meta = {
component: Button,
args: {
onClick: fn(),
},
} satisfies Meta<typeof Button>
export default meta
type Story = StoryObj<typeof meta>
export const Primary: Story = {
args: {
label: 'Click me',
variant: 'primary',
},
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement)
const button = canvas.getByRole('button', { name: /click me/i })
await userEvent.click(button)
await expect(args.onClick).toHaveBeenCalledOnce()
await expect(button).toHaveStyle({ backgroundColor: 'rgb(37, 99, 235)' })
},
}
Vitest 配置
// vitest.config.ts
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin'
import { defineConfig } from 'vitest/config'
export default defineConfig({
plugins: [storybookTest()],
test: {
setupFiles: ['./vitest.setup.ts'],
},
})
核心原则
- 故事就是测试。 每个包含
play()函数的故事都是可执行的交互测试,可在 Vitest 中运行。 - 使用 CSF3 +
satisfies确保类型安全。 使用satisfies Meta<typeof Component>,为 args 和 play 函数提供完整的类型推断。 - 模块自动模拟(SB 10)。 在
.storybook/preview.ts中注册sb.mock(import(...)),并在beforeEach中使用mocked()按故事进行配置。不要在故事文件中使用vi.mock。无需工厂函数——sb.mock在构建时执行,而非运行时。 - 使用 TurboSnap 加快 CI。 只对受代码变更影响的故事进行快照——可将 Chromatic 用量降低 60-90%。
- 无障碍不可忽视。 a11y 插件会对每个故事运行 axe-core 扫描,并在 CI 中对违规情况进行拦截。
- 动态文档。 Autodocs 直接根据故事生成属性表和用法示例——无需单独的文档站点。
反模式(禁止)
| 反模式 | 失败原因 | 替代方案 |
|---|---|---|
CSF2 Template.bind({}) | 已弃用,没有类型推断,并将在 SB 11 中移除 | 使用带有 satisfies 的 CSF3 对象故事 |
@storybook/test-runner 包 | 自 Storybook 9 起已弃用 | 使用 @storybook/addon-vitest |
在故事文件中使用 vi.mock() | 会在故事之间泄漏,破坏隔离性 | 在 preview.ts 中注册 sb.mock(import(...)),并在 beforeEach 中使用 mocked() 配置 |
| 每个 PR 都运行完整的 Chromatic 快照 | 成本高且速度慢 | 使用 onlyChanged: true 的 TurboSnap |
| 手动进行无障碍检查 | 会遗漏违规问题,且无法重复执行 | 在 CI 流水线中使用 @storybook/addon-a11y |
| 单独的文档站点 | 会与组件的实际行为脱节 | 使用带有 tags: ['autodocs'] 的 Autodocs |
| 测试实现细节 | 脆弱,重构时容易失效 | 通过 play() 测试用户可见的行为 |
| 在故事中使用 CJS 导入 | 自 SB 9/10 起仅支持 ESM | 使用 ESM 导入,在 tsconfig 中设置 "module": "ESNext" |
Storybook MCP 集成(addon-mcp)
安装 @storybook/addon-mcp 后,Agent 可以通过 MCP 而非 CLI 运行测试和预览故事,从而实现 生成 → 测试 → 自我修复 循环。
用于测试的 MCP 工具
| 工具 | 用途 |
|---|---|
run-story-tests | 通过 MCP 运行组件和 a11y 测试,返回通过/失败结果及违规详情 |
preview-stories | 返回预览 URL,以便在聊天中进行视觉验证 |
get-storybook-story-instructions | 提供编写有效故事和交互测试的指导 |
Agent 测试循环
# 1. Generate component + CSF3 story
# 2. Run tests via MCP
results = run-story-tests(
stories=[{ "storyId": "button--primary" }],
a11y=True
)
# 3. If failures: read violations, fix, retry (max 3)
# 4. Preview in chat for visual confirmation
preview-stories(stories=[{ "storyId": "button--primary" }])
设置
npx storybook add @storybook/addon-mcp # current: 0.6.0, Apr 2026
# Enable docs toolset in .storybook/main.ts:
# componentsManifest: true # was experimentalComponentsManifest (SB 10.3 rename, default-on)
npx mcp-add --type http --url "http://localhost:6006/mcp" --scope project
完整的工具参考和使用模式请参阅 storybook-mcp-integration 技能。
参考资料
references/storybook-migration-guide.md— 从 Storybook 9 迁移到 10 的路径references/storybook-ci-strategy.md— 用于视觉、交互和 a11y 测试的 CI 流水线配置references/storybook-addon-ecosystem.md— 2026 年 Storybook 10 的必备插件
相关技能
storybook-mcp-integration— Storybook MCP 工具:组件发现、测试和预览react-server-components-framework— React 19 + Next.js 16 模式(组件架构)accessibility— Storybook 之外更广泛的无障碍模式devops-deployment— 自动化测试的 CI/CD 流水线模式
评论
支持 Markdown