用途
Storybook Testing 是一套面向 Storybook 10 的组件测试技能,目标是把组件测试统一到单一工作流中:通过 play() 函数编写交互测试,通过 Chromatic TurboSnap 做视觉回归,通过 a11y 插件做无障碍审计,全部经由 Vitest 运行。其核心理念是:故事(stories)本身就是可执行的测试规格,而不仅是文档。
主要能力
- CSF3 类型安全工厂:使用
satisfies Meta<typeof Component>获得 args 与 play 函数的完整类型推断。 - play() 交互测试:每个带 play() 的故事都是可在 Vitest 中运行的交互测试,使用
storybook/test提供的 expect、fn、userEvent、within 等工具。 - Vitest 集成:通过
@storybook/addon-vitest的 vitest-plugin 将故事作为 Vitest 测试运行。 - Chromatic TurboSnap:仅对受代码变更影响的故事生成快照,据资料称可减少 60–90% 的 Chromatic 用量。
- 模块自动模拟(sb.mock):Storybook 10 新增的构建期模块模拟,在
.storybook/preview.ts中注册sb.mock(import(...)),并在 beforeEach 中用 mocked() 按故事配置。 - 无障碍测试:
@storybook/addon-a11y对每个故事运行 axe-core 扫描,并在 CI 中对违规进行门禁。 - Autodocs:通过
tags: ['autodocs']从故事自动生成 prop 表与用法示例。 - MCP 集成:安装
@storybook/addon-mcp后,智能体可通过 MCP 运行测试与预览故事,形成“生成 → 测试 → 自愈”循环。
Storybook 10 相对 9 的变化
- 强制 ESM-only(唯一的破坏性变更),要求 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。
使用方式
CSF3 故事与 play 函数示例:
// 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'],
},
})
MCP 安装:
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
MCP 测试工具包括:run-story-tests(运行组件与 a11y 测试,返回通过/失败及违规详情)、preview-stories(返回预览 URL 用于在对话中视觉验证)、get-storybook-story-instructions(编写有效故事与交互测试的指导)。
测试金字塔
从下到上依次为:单元测试(Vitest + storybookTest 插件,基于故事)、交互测试(play() 函数,@storybook/test)、无障碍测试(@storybook/addon-a11y,axe-core 扫描)、视觉回归(Chromatic TurboSnap,快照差异)。每层捕获不同缺陷:单元测试验证逻辑,交互测试验证用户流程,a11y 测试捕获无障碍违规,视觉测试捕获非预期的 UI 回归。
适用场景
- 以 CSF3 + TypeScript 编写组件故事。
- 用 play() 函数搭建交互测试。
- 配置带 TurboSnap 的 Chromatic 视觉回归。
- 在故事级别使用模块自动模拟。
- 在 CI 中通过 a11y 插件运行无障碍测试。
- 用 autodocs 生成活文档。
- 从 Storybook 9 迁移到 10。
限制与禁止事项
- 禁止使用 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-only),应使用 ESM 导入并在 tsconfig 中设置
"module": "ESNext"。
参考资料
- 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 流水线模式