Storybook Test Runner logo

Storybook Test Runner

Storybook 官方组件自动化测试运行器

测试工具组件测试Storybook可访问性测试

Storybook Test Runner 是 Storybook 官方提供的测试运行器,基于 Playwright 在真实浏览器中自动执行 Story 的交互测试和可访问性检查,将组件文档与自动化测试打通,实现 Story 即测试用例的 workflow。

Storybook Test Runner 组件自动化测试技术调研

Storybook Test Runner 是 Storybook 官方提供的测试运行器,基于 Playwright 在真实浏览器中自动执行 Story 的交互测试(play 函数)和可访问性检查,将组件文档与自动化测试打通,实现「Story 即测试用例」的组件质量保障 workflow。


一、 基本信息

维度关键指标 / 描述
技术标签组件测试 / Storybook / Playwright / 交互测试 / a11y
开发商Chromatic(Storybook 团队)
官方网站https://storybook.js.org/docs/writing-tests/test-runner
npm 包@storybook/test-runner
许可协议MIT License
首次发布2022 年
生态成熟度中高(Storybook 测试体系核心组件)

二、 技术定位与简介

Storybook Test Runner 的工作方式:

  1. 启动或连接已运行的 Storybook 实例。
  2. 使用 Playwright 访问每个 Story 的 iframe URL。
  3. 自动运行 Story 中定义的 play 函数@storybook/test 交互步骤)。
  4. 可选运行 axe 可访问性检查。
  5. 输出 Jest 风格测试结果,可集成 CI。

它与 Vitest 组件测试Chromatic 视觉回归 共同构成 Storybook 现代测试三角:交互 + 视觉 + 单元。


三、 快速上手安装说明

1. 安装

pnpm add -D @storybook/test-runner @storybook/test

2. 配置 package.json

{
  "scripts": {
    "test-storybook": "test-storybook"
  }
}

3. Story 带 play 函数

import type { Meta, StoryObj } from '@storybook/react'
import { expect, userEvent, within } from '@storybook/test'
import { Button } from './Button'
 
const meta: Meta<typeof Button> = {
  component: Button,
}
export default meta
 
type Story = StoryObj<typeof Button>
 
export const Click: Story = {
  args: { label: 'Click me' },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement)
    await userEvent.click(canvas.getByRole('button'))
    await expect(canvas.getByText('Clicked')).toBeInTheDocument()
  },
}

4. 运行

pnpm storybook &  # 或先 build 静态 storybook
pnpm test-storybook

5. test-runner-jest.config.js

const { getJestConfig } = require('@storybook/test-runner')
 
module.exports = {
  ...getJestConfig(),
  /** 自定义 setup */
}

四、 核心特性

1. 自动遍历 Stories

无需手写每个 Story 的测试文件。

2. play 函数执行

@storybook/addon-interactions 共享交互定义。

3. 可访问性测试

集成 @storybook/addon-a11y 与 axe 自动扫描。

4. Playwright 底层

真实浏览器环境,非 jsdom。

5. 并行执行

Jest worker 并行访问 Stories。

6. CI 友好

--ci--maxWorkers 控制资源。

7. 标签过滤

--includeTags--excludeTags 选择性运行。

8. 与 Chromatic 协同

视觉回归在 Chromatic 云,交互在 Test Runner 本地/CI。


五、 适用场景

1. 黄金适用场景

  • 已采用 Storybook 的组件库/设计系统。
  • 需要 Story 级交互回归(按钮、表单、对话框)。
  • 组件 a11y 基线检查。
  • 设计系统 CI 质量门禁。
  • play 函数即活文档又即测试。

2. 局限适用场景

  • 未使用 Storybook 的项目。
  • 全应用 E2E 流程(用 Playwright/Cypress)。
  • 纯逻辑单元测试(Vitest)。
  • 按本项目规范:营销页、纯展示组件可不测。

六、 技术亮点

1. DRY 测试

交互逻辑只在 Story play 中写一次。

2. 真实浏览器

弥补 jsdom 组件测试盲点。

3. 与 Interactions 面板统一

开发时调试的 play 即 CI 执行的 play。

4. 零额外测试文件

减少 Story 与 Test 重复维护。

5. 官方维护

与 Storybook 版本同步演进。


七、 核心概念与架构

digraph SB_TestRunner {
  rankdir=LR
  node [shape=box, style="rounded,filled", fillcolor="#f0f9ff"]
  Runner [label="test-storybook\n(Jest)", fillcolor="#bae6fd"]
  Playwright [label="Playwright"]
  SB [label="Storybook Server"]
  Story [label="Story iframe\n+ play()"]
  A11y [label="axe a11y"]
 
  Runner -> Playwright
  Playwright -> SB
  SB -> Story
  Runner -> A11y
  Story -> A11y
}

八、 技术局限与边界

  1. 依赖 Storybook:无 Storybook 则无用。
  2. 启动成本:需运行 Storybook 服务或静态构建。
  3. 速度:比纯 Vitest 慢。
  4. 覆盖范围:组件级,非页面级路由。
  5. 配置门槛:Monorepo、Vite、Next 需正确 Storybook 配置。
  6. flaky:异步 play 需良好等待实践。

九、 生态地图

组件关系
@storybook/testplay 内 expect/userEvent
addon-interactions开发时调试 play
addon-a11y可访问性规则
Chromatic视觉回归云
Viteststorybook-addon-vitest 替代/补充

十、 生态集成

方向说明
PlaywrightTest Runner 底层浏览器驱动。
Jest测试结果与 worker 模型。
CIbuild storybook → test-storybook。
Vitest新版可用 vitest 运行 story 测试。
Chromatic视觉 + 交互分工。

十一、 开发与工程化

1. CI 流水线

- run: pnpm build-storybook
- run: pnpm test-storybook --ci --url file://$(pwd)/storybook-static

2. 仅为交互 Story 写 play

展示型 Story 可跳过 play,Test Runner 仍可做 a11y smoke。

3. 与项目规范对齐

稳定业务组件写 play;营销展示组件可不纳入。


十二、 性能与安全

  • --maxWorkers 控制 CI 并行度。
  • 静态 storybook 比 dev server 更稳定快速。
  • Story 中勿使用生产 API 与真实密钥。
  • MSW 在 Storybook preview 中 Mock API。

十三、 技术对比

方案优势局限适合
Test RunnerStory=测试、真实浏览器需 Storybook设计系统
Vitest CT快、与 Vite 集成较新Vite 组件库
Testing Library灵活独立测试文件应用组件
Chromatic视觉回归付费云UI 像素对比

十四、 最佳实践

  1. 每个交互组件至少一个带 play 的 Story。
  2. 使用 @storybook/testwithin(canvasElement) 限定查询范围。
  3. CI 用静态 storybook-static 而非 dev server。
  4. 启用 a11y addon,Test Runner 自动跑 axe。
  5. 与 Chromatic 分工:视觉云测,交互本地 CI。
  6. 异步 UI 用 await expect(...).toBeVisible() 等待。
  7. 复杂 API 在 preview.ts 配置 MSW handlers。
  8. 用 tags 区分 testskip-test stories。
  9. 不要为纯样式 Story 写无意义 play。
  10. 评估 storybook-addon-vitest 是否与 Test Runner 重复。

十五、 学习与社区资源