首页
/ Storybook Test Runner 安装与实战指南:将每个 Story 变成可执行的自动化测试

Storybook Test Runner 安装与实战指南:将每个 Story 变成可执行的自动化测试

2026-09-09 10:55:39作者:范靓好Udolf

导读

Storybook Test Runner 是 Storybook 官方提供的独立测试工具,它能将项目中的每一个 Story 自动转化为可执行的测试用例:没有 play function 的 Story 会验证其能否无错误渲染,带有 play function 的 Story 还会进一步校验交互逻辑与断言是否通过。这些测试运行在真实浏览器中(底层由 Jest 与 Playwright 驱动),既可在命令行本地执行,也可接入 CI 流水线。阅读本文后,你将掌握三种包管理器的安装方式、零配置启动流程、全部 CLI 参数、快照测试与代码覆盖率配置,以及面向 CI 的部署方案和高级 Hook 扩展能力。

一、安装 Test Runner:三个包管理器一条命令

Test Runner 是独立于 Storybook 的框架无关工具,需要额外安装。关联文档 docs/_snippets/test-runner-install.md 给出了官方推荐的三种包管理器安装命令,均以 --save-dev(开发依赖)方式写入 package.json

# npm
npm install @storybook/test-runner --save-dev
# pnpm
pnpm add --save-dev @storybook/test-runner
# yarn
yarn add --dev @storybook/test-runner

安装前提

  • 需要 Storybook 已正确初始化并可以本地启动(Test Runner 要求存在本地运行或已发布的 Storybook 实例才能执行测试);
  • 建议在 Node.js 的 LTS 版本环境中运行;
  • Test Runner 内部依赖 Playwright 浏览器二进制,首次运行测试前需确保 Playwright 的 chromium 浏览器可用,若 CI 环境中缺失可参照 Playwright 官方 CI 文档补充安装。

安装完成后,Test Runner 会自动注册 test-storybook 命令行可执行文件。从当前仓库的沙箱工程配置(如 code/sandbox/react-vite-default-ts/project.json 等各框架 sandbox 的 project.json)可以看到,Storybook 自身的集成测试体系正是通过 test-storybook 任务来运行的,这也印证了它是官方 CI 链路的标准一环。

二、零配置启动:三步跑通第一个测试

Test Runner 官方支持 Storybook 的零配置开箱即用,完整流程记录在 docs/writing-tests/integrations/test-runner.mdx 主文档中。

第 1 步:配置 npm script

在项目根目录的 package.json 中添加脚本:

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

第 2 步:启动 Storybook

npm run storybook

注意:Test Runner 要求要么有一个本地运行的 Storybook 实例,要么有一个已发布的 Storybook,否则无法运行现有测试。

第 3 步:新开终端运行测试

npm run test-storybook

默认情况下 Test Runner 假设本地 Storybook 运行在 6006 端口。执行后它会遍历所有 Story:无 play function 的 Story 校验渲染是否报错;有 play function 的 Story 额外执行 play 逻辑并检查断言结果。

自定义配置:eject 模式

零配置之外,你可以运行 test-storybook --eject 获得更细粒度的控制。它会在项目根目录生成一个 test-runner-jest.config.js 文件供你修改。由于 Test Runner 底层同时使用了 jest-playwright,你还可以在生成配置中提供 testEnvironmentOptions 进一步定制浏览器运行环境。

三、CLI 参数速查表

Test Runner 由 Jest 驱动,接受其 CLI 选项的子集(如 --watch--maxWorkers),如果你项目里已经使用这些标志,可以无缝迁移。下表完整罗列了官方文档中的全部可用参数:

选项 说明
--help 输出用法信息,如 test-storybook --help
-s, --index-json 以 index.json 模式运行(要求 Storybook 兼容,可自动检测),如 test-storybook --index-json
--no-index-json 禁用 index.json 模式,如 test-storybook --no-index-json
-c, --config-dir [dir-name] 指定加载 Storybook 配置的目录,如 test-storybook -c .storybook
--watch 监听模式运行
--watchAll 监听文件变更并重跑所有测试
--coverage 对 stories 和组件运行覆盖率测试,如 test-storybook --coverage
--coverageDirectory 指定覆盖率报告输出目录,如 test-storybook --coverage --coverageDirectory coverage/ui/storybook
--url 指定测试目标 URL,适合自定义 Storybook 地址,如 test-storybook --url http://the-storybook-url-here.com
--browsers 指定测试浏览器,可选 chromium、firefox、webkit 中的一个或多个,如 test-storybook --browsers firefox chromium
--maxWorkers [amount] 限制 worker 池最大并行数,如 test-storybook --maxWorkers=2
--testTimeout [amount] 定义单个测试超时毫秒数,适合长耗时测试,如 test-storybook --testTimeout=60000
--no-cache 禁用缓存
--clearCache 清空 Jest 缓存目录后退出,不运行测试
--verbose 按测试套件层级展示单个测试结果
-u, --updateSnapshot 重新记录本次运行中失败的快照
--eject 生成本地配置文件以覆盖默认值
--json 以 JSON 格式输出测试结果(其余输出写入 stderr)
--outputFile 配合 --json 将结果写入文件,如 test-storybook --json --outputFile results.json
--junit 以 junit 文件格式上报测试信息
--ci CI 模式下不自动存储新快照,而是让测试失败并要求配合 --updateSnapshot
--shard [index/count] 要求 CI 环境,将测试套件拆分到多台机器并行,如 test-storybook --shard=1/8
--failOnConsole 浏览器控制台出现错误即判定测试失败
--includeTags 实验特性,只测试匹配 tags 的 stories,如 test-storybook --includeTags="test-only, pages"
--excludeTags 实验特性,排除匹配 tags 的 stories,如 test-storybook --excludeTags="no-tests, tokens"
--skipTags 实验特性,跳过匹配 tags 的 stories,如 test-storybook --skipTags="skip-test, layout"

针对部署版 Storybook 运行测试

默认目标端口是本地 6006。若要测试已部署的 Storybook,有两种方式:

# 方式一:--url 参数
test-storybook --url http://the-storybook-url-here.com

# 方式二:TARGET_URL 环境变量
TARGET_URL=https://the-storybook-url-here.com yarn test-storybook

四、无障碍(a11y)测试

安装 a11y 插件 后,Test Runner 可以在交互测试的同时运行无障碍测试。仓库中的 code/addons/a11y 目录即该插件的完整实现,包含测试规则、面板组件与配置项。更详细的配置说明见 docs/writing-tests/accessibility-testing.mdx

五、快照测试

快照测试 用于验证边界情况(如错误态)是否被正确处理,以及组件渲染输出在不同测试运行间是否保持一致。

启用快照测试

在 Storybook 目录(.storybook/)下新增配置文件,利用 postVisit Hook 捕获渲染结果:

module.exports = {
  async postVisit(page, context) {
    // #storybook-root 元素包裹着 story;在 Storybook 6.x 中该选择器为 #root
    const elementHandler = await page.$('#storybook-root');
    const innerHTML = await elementHandler.innerHTML();
    expect(innerHTML).toMatchSnapshot();
  },
};

完整示例见 docs/_snippets/test-runner-dom-snapshot-testing.md。运行 test-storybook 后,会为每个 story 在项目 __snapshots__ 目录生成对应的快照文件。

自定义快照目录

默认快照路径有固定的命名约定,如需变更可自定义 snapshotResolver:创建 snapshot-resolver.js 实现自定义解析器(参考 docs/_snippets/test-runner-config-snapshot-resolver.md),然后在 test-runner-jest.config.js 中启用 snapshotResolver 选项。

自定义快照序列化

默认使用 jest-serializer-html 序列化 HTML 快照。如果项目使用 Emotion、Angular 的 ng 属性等会生成基于 hash 的类名库,序列化可能不稳定。此时可创建 snapshot-serializer.js 自定义序列化器(参考 docs/_snippets/test-runner-custom-snapshot-serializer.md),并在 test-runner-jest.config.js 中通过 snapshotSerializers 启用。执行时 Test Runner 会先用正则将动态生成的属性替换为静态值,再生成快照,从而保证跨运行的一致性。

六、代码覆盖率

安装与运行

Storybook 提供了 @storybook/addon-coverage 相关的覆盖率插件(见官方文档说明),底层由 Istanbul 驱动,可为 JavaScript 生态中最常用的框架和构建器提供开箱即用的代码插桩。它与 Playwright 等现代测试工具协同工作,推荐搭配 Test Runner 使用。

npm install @storybook/addon-coverage --save-dev

启动 Storybook 后,在新终端运行:

test-storybook --coverage

Storybook Test Runner 覆盖率测试输出

覆盖率配置项

覆盖率插件对 Storybook 提供零配置支持:Webpack 下通过 istanbul-lib-instrument 插桩,Vite 下通过 vite-plugin-istanbul 插桩。可在 .storybook/main.js|ts 中通过 options.istanbul 传递更多参数。

Vite 选项checkProd(生产环境跳过插桩,boolean)、cwd(工作目录,默认 process.cwd()string)、cypress(用 CYPRESS_COVERAGE 替换 VITE_COVERAGEboolean)、exclude / include(覆盖/包含的文件列表,Array<String>string)、extension(扩展参与覆盖的文件后缀)、forceBuildInstrument(构建模式强制插桩,boolean)、nycrcPath(现有 nyc 配置文件相对路径,string)、requireEnv(覆盖 VITE_COVERAGE 环境变量值,boolean)。

Webpack 5 选项autoWrap(支持顶层 return,boolean)、compact(压缩插桩代码,调试时可设 false)、coverageVariable(Istanbul 存储覆盖率结果的全局变量名,默认 __coverage__string)、cwddebug(调试日志,boolean)、esModules(支持 ES Module 语法,boolean)、exclude / include / extension / nycrcPath(同上)、preserveComments(保留注释,boolean)、produceSourceMap(生成 source map,boolean)、sourceMapUrlCallback(生成 source map 时的回调函数,function)。

与其它覆盖率报告工具集成

覆盖率测试与 Test Runner、coverage 插件配合开箱即用,同时也可接入其它报告工具(如 LCOV):利用生成的 coverage/storybook/coverage-storybook.json 输出自行生成报告。若在 Vue 3、Svelte 等含特殊文件的框架中运行覆盖率,需要在 nyc 配置文件(.nycrc.jsonnyc.config.js)中启用对应文件扩展名。

七、CI 集成方案

方案一:对已部署的 Storybook 运行测试(GitHub Actions)

如果 Storybook 通过 Vercel 或 Netlify 发布,它们会在 GitHub Actions 中发出 deployment_status 事件。可以读取 deployment_status.target_url 作为 TARGET_URL 环境变量。该方案要求发布的 Storybook 可公开访问;若需鉴权,建议改用下面的本地构建方案。

方案二:对未部署的 Storybook 运行测试

使用 CI 提供方构建 Storybook 后运行测试。官方推荐借助 concurrentlyhttp-serverwait-on 三个第三方库,先构建静态站点再执行 Test Runner。注意:Storybook 默认将构建产物输出到 storybook-static 目录,若自定义了构建目录需相应调整配置。

八、高级配置:Test Hook API

Test Runner 渲染 story 并执行其 play function。某些行为无法在浏览器内的 play function 中实现(例如截取视觉快照),需要通过 Node 侧执行。Test Runner 导出了可在全局覆写的测试 Hook,用于在 story 渲染之前之后介入测试生命周期:

Hook 说明
prepare 为测试准备浏览器,签名 async prepare({ page, browserContext, testRunnerConfig }) {}
setup 在全部测试运行前执行一次,setup() {}
preVisit 在 story 初次访问、渲染前执行,async preVisit(page, context) {}
postVisit 在 story 访问并完全渲染后执行,async postVisit(page, context) {}

注意:除 setup 外的 Hook 均为异步函数;preVisitpostVisit 额外接收两个参数——Playwright 的 page 对象,以及包含 story 的 idtitlename 的 context 对象。这些 Hook 属于实验特性,可能发生破坏性变更,官方建议尽可能在 story 的 play function 内完成测试。

启用方式是在 Storybook 目录下新增 .storybook/test-runner.js(或 .ts)配置文件:

module.exports = {
  // 在测试运行器开始运行测试前执行
  setup() {
    // 在这里添加你的配置
  },
  /* 在 story 初次访问、渲染前执行。
   * page 参数是 story 的 Playwright page 对象。
   * context 参数是包含 story 的 id、title、name 的 Storybook 对象。
   */
  async preVisit(page, context) {
    // 在这里添加你的配置
  },
  /* 在 story 访问并完全渲染后执行。参数同上。 */
  async postVisit(page, context) {
    // 在这里添加你的配置
  },
};

TypeScript 版本可使用 TestRunnerConfig 类型获得类型提示,完整代码见 docs/_snippets/test-runner-hooks-example.md。测试执行的完整生命周期为:setup 先于所有测试执行 → 生成包含必要信息的 context 对象 → Playwright 导航到 story 页面 → 执行 preVisit → 渲染 story 并执行 play function → 执行 postVisit

辅助函数(Helpers)

Test Runner 还导出两个辅助函数,用于访问 Storybook 内部信息:

  • getStoryContext(page, context):获取 story 的完整上下文(parameters、args、argTypes 等)。典型用法是在 preVisit 中读取 story 的 parameters.viewport.defaultViewport,并据此设置 Playwright 页面的 viewport 尺寸(示例见 docs/_snippets/test-runner-custom-page-viewport.md)。
  • waitForPageReady(page):等待页面完全加载(包括图片、字体等异步资源),专为图片快照测试设计(示例见 docs/_snippets/test-runner-helper-function.md)。

九、按标签过滤测试(实验特性)

默认情况下 Test Runner 会测试所有 story。通过 tags 配置可以精确控制测试范围。配置方式有两种:.storybook/test-runner.js 配置文件中的 tags 选项,或 CLI 的 --includeTags / --excludeTags / --skipTags 标志(需 0.15 及以上版本)。CLI 标志优先于配置文件并会覆盖后者。

选项 说明
exclude 阻止匹配标签的 stories 被测试
include 只测试匹配标签的 stories
skip 跳过匹配标签的 stories(在结果中标记为临时禁用)
module.exports = {
  tags: {
    include: ['test-only', 'pages'],
    exclude: ['no-tests', 'tokens'],
    skip: ['skip-test', 'layout'],
  },
};

完整示例见 docs/_snippets/test-runner-tags-config.md。三个典型场景:

标签应在组件层级(meta)或 story 层级添加,跨 story 导入标签不受支持。若 includeexclude 列表出现相同标签,Test Runner 会按 exclude 执行并忽略 include,因此务必保持两列表的标签互不相同。

十、部署版 Storybook 的认证与 index.json 模式

为受保护的 Storybook 添加 HTTP 头

若托管平台需要认证,可在 .storybook/test-runner.js 中配置 getHttpHeaders 函数。该函数接收 fetch 调用与页面访问的 URL 作为输入,返回需要设置的请求头对象:

module.exports = {
  getHttpHeaders: async (url) => {
    const token = url.includes('prod') ? 'XYZ' : 'ABC';
    return {
      Authorization: `Bearer ${token}`,
    };
  },
};

示例见 docs/_snippets/test-runner-auth.md。这是因为 Test Runner 会通过 fetch 请求检查实例状态与 story 索引。

index.json 模式

测试本地 Storybook 时,Test Runner 将 story 文件转换为测试;测试远程 Storybook 时,则使用 index.json(即此前的 stories.json,是所有 story 的静态索引)。当本地与远程 Storybook 不同步或无法访问源码时,index.json 是测试目标最准确的表示。可通过 --index-json 强制开启,--no-index-json 关闭。注意 index.json 模式与 watch 模式不兼容。

检查方式:在浏览器中访问部署实例的 index.json 地址(如 https://your-storybook-url-here.com/index.json),若 JSON 以 "v": 3 键开头、紧随其后是包含 story ID 映射的 stories 键,则说明支持该模式。

十一、与 Chromatic 的区别

Test Runner 是通用的测试工具,可在本地或 CI 上运行,可配置、可扩展以运行各类测试。Chromatic 是基于云的视觉/交互测试服务,无需搭建 Test Runner,并与 git 提供方同步、管理私有项目的访问控制。两者也可组合使用:本地用 Test Runner、CI 用 Chromatic;或视觉与组件测试交给 Chromatic、自定义测试交给 Test Runner。

十二、常见故障排查

问题 解决方案
测试超时(Timeout - Async callback was not invoked within the 15000 ms timeout 故事数量过多或 CI 内存过低时,限制并行 worker 数:"test-storybook:ci": "yarn test-storybook --maxWorkers=2"
CLI 错误输出过短 默认截断 1000 字符,可通过 DEBUG_PRINT_LIMIT 调整,如 DEBUG_PRINT_LIMIT=5000 yarn test-storybook
其它 CI 环境运行异常 Test Runner 基于 Playwright,需按 Playwright CI 文档配置特定 docker 镜像等
Yarn PnP 项目报 PlaywrightError: jest-playwright-preset: Cannot find playwright package to use chromium nodeLinker 改为 node-modules,或直接安装 Playwright 依赖并执行浏览器安装命令
coverage 插件不插桩优化构建产物 --test 标志会移除影响性能的插件(如 Docs、coverage),需要在 `.storybook/main.js
coverage 插件不支持插桩代码 基于 Webpack5 loader 与 Vite 插件实现的框架(如 Angular 配置 Webpack)需要额外配置

结语与延伸阅读

至此,你已经掌握了从安装到 CI 落地的完整 Test Runner 使用链路。值得留意的是,官方文档指出 Test Runner 已逐步被 Vitest 插件 取代——后者基于更快的 Vitest 浏览器模式提供同等功能,并能直接在 Storybook 应用中运行交互、无障碍与视觉测试。若你的 Storybook 框架基于 Vite,官方建议优先选用 Vitest 插件。

更多测试主题可继续阅读:交互测试(docs/writing-tests/interaction-testing.mdx)、无障碍测试(docs/writing-tests/accessibility-testing.mdx)、视觉测试(docs/writing-tests/visual-testing.mdx)、快照测试(docs/writing-tests/snapshot-testing.mdx)、覆盖率(docs/writing-tests/test-coverage.mdx)、CI 集成(docs/writing-tests/in-ci.mdx)、端到端测试(docs/writing-tests/integrations/stories-in-end-to-end-tests.mdx)与单元测试(docs/writing-tests/integrations/stories-in-unit-tests.mdx)。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525