news 2026/9/10 18:30:17

Storybook 测试在 CI 中调试失败:storybookUrl 配置与 SB_URL 环境变量实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Storybook 测试在 CI 中调试失败:storybookUrl 配置与 SB_URL 环境变量实战指南

Storybook 测试在 CI 中调试失败:storybookUrl 配置与 SB_URL 环境变量实战指南

【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook

本篇指南聚焦 Storybook 的 Vitest addon 在 CI 环境下的一处关键配置:如何通过storybookUrl插件选项配合SB_URL环境变量,让 CI 中失败的测试输出直接指向已发布的 Storybook 实例,从而把"看到报错"升级为"一键进入 Storybook 复现问题"。读完本文,你将掌握 Vitest 3 / Vitest 4 两种配置格式下的完整插件写法、CI 工作流中传递部署 URL 的方式,以及从源码层面理解storybookUrl是如何被注入测试运行时并最终拼进失败信息的。

问题背景:CI 中为什么看不到"可点击的调试链接"

Storybook 的 Vitest addon(@storybook/addon-vitest)在本地运行测试时,每个失败用例的输出都会附带一条指向 Storybook 的调试链接。这个机制依赖一个前提:有一个正在运行的 Storybook 可供跳转,本地默认就是http://localhost:6006

但在 CI 中情况完全不同——CI 环境里并没有一个活跃运行的 Storybook 服务。如果什么都不配置,失败信息里的链接就会指向一个不存在的本地地址,调试价值大打折扣。解决方案分三步:

  1. 在 CI 中先构建并发布 Storybook(例如发布到 Vercel、GitHub Pages 等平台);
  2. 把发布后的 URL 通过环境变量(约定命名为SB_URL)传给测试命令;
  3. 在 Vitest 插件配置中用storybookUrl: process.env.SB_URL把这个变量接进插件。

下面完整继承官方片段中的两段配置,并补充参数说明。

配置一:Vitest 4 的test.projects写法(vitest.config.ts)

Vitest 4 引入了内联projects配置,多项目配置统一放在vitest.config.ts中。完整继承自 官方片段文档 的写法如下:

export default defineConfig({ // ... test: { // ... projects: [ { plugins: [ storybookTest({ // ... // 👇 Use the environment variable you passed storybookUrl: process.env.SB_URL, }), ], }, ], }, });

要点说明:

  • storybookTest()@storybook/addon-vitest提供的 Vitest 插件工厂函数,安装 Vitest addon 时生成的配置中已包含它;
  • storybookUrl是插件的用户选项,类型为string,语义是"Storybook 的托管地址,用于在测试失败时输出中生成 story 链接",缺省值为http://localhost:6006(见 选项类型定义);
  • process.env.SB_URL而非硬编码 URL,是为了让同一份配置在本地(变量为空、回退默认值或显式设为本地地址)与 CI(注入发布地址)之间无缝切换。

配置二:Vitest 3 的defineWorkspace写法(vitest.workspace.ts)

如果你还在 Vitest 3,多项目配置放在独立的 workspace 文件里,写法如下(同样完整继承自 官方片段文档):

export default defineWorkspace([ // ... { // ... { plugins: [ storybookTest({ // ... // 👇 Use the environment variable you passed storybookUrl: process.env.SB_URL, }), ], }, }, ]);

两种格式的核心差异只是宿主 API:Vitest 3 用defineWorkspace的数组描述项目,Vitest 4 用test.projects内联在统一配置中;插件选项本身(包括storybookUrl)完全一致。

在 CI 工作流中传递 SB_URL

光有插件配置还不够,还需要 CI 把"Storybook 发布到哪了"这件事告诉测试命令。以 GitHub Actions 为例,In CI 官方文档 给出的模式是:利用部署平台发出的deployment_status事件——其中deployment_status.environment_url就是新生成的 Storybook 地址——在测试步骤中注入环境变量:

name: Storybook Tests + # 👇 Update this to only run when a deployment status is emitted + on: deployment_status - on: [push] jobs: test: runs-on: ubuntu-latest container: image: mcr.microsoft.com/playwright:v1.58.2-noble + # 👇 Only run on successful deployments + if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' steps: - uses: actions/checkout@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: 22.12.0 - name: Install dependencies run: npm ci - name: Run tests run: npm run test-storybook + # 👇 Pass the Storybook URL as an environment variable + env: + SB_URL: '${{ github.event.deployment_status.environment_url }}'

配合package.json中的测试脚本(vitest --project=storybook),执行npm run test-storybookSB_URL就已进入进程环境,插件的process.env.SB_URL随即生效。其他 CI 平台(GitLab、Circle CI、Azure Pipelines 等)思路相同:在测试步骤的环境变量区把发布 URL 赋给SB_URL,具体事件字段名因平台而异。

源码原理:storybookUrl 如何变成失败信息里的链接

从源码看,storybookUrl的传播链路非常清晰,共三站:

第一站:插件解析选项并写入进程环境变量。在 插件入口 中,storybookTest(options)先把用户选项与默认值合并(默认值见 defaultOptions,其中storybookUrl默认http://localhost:6006),随后执行:

// To be accessed by the global setup file process.env.__STORYBOOK_URL__ = finalOptions.storybookUrl; process.env.__STORYBOOK_SCRIPT__ = finalOptions.storybookScript;

即你传入的process.env.SB_URL在这里被固化成内部变量__STORYBOOK_URL__,供后续 global setup 与 setup file 使用。

第二站:向测试运行时注入 env。插件生成测试项目配置时,把该值再次放入test配置的env块(相关代码):

env: { ...(await presets.apply('env', {})), // To be accessed by the setup file __STORYBOOK_URL__: finalOptions.storybookUrl, // ... },

这使得浏览器端的测试代码可以通过import.meta.env.__STORYBOOK_URL__读到它。

第三站:失败信息改写。真正拼出链接的是 setup-file.ts 中的 modifyErrorMessage:当某个测试任务状态为fail且带有storyId时,它在错误信息最前面注入一行蓝色可点击提示:

const storybookUrl = import.meta.env.__STORYBOOK_URL__; const storyUrl = `${storybookUrl}/?path=/story/${meta.storyId}&addonPanel=${COMPONENT_TESTING_PANEL_ID}`; currentError.message = `\n\x1B[34mClick to debug the error directly in Storybook: ${storyUrl}\x1B[39m\n\n${currentError.message}`;

注意链接尾部还带了addonPanel参数——它会把失败 story 直接定位到组件测试面板,打开即可看到对应测试的执行结果与报错。这也解释了为什么 URL 必须指向一个已发布的 Storybook:链接是真实可访问的 story 路径,不是本地临时端口。

配置完成后的效果与验证

当 CI 测试失败时,输出会包含指向已发布 Storybook 的调试链接,点击即可在真实部署环境中复现该 story 的失败现场:

验证要点:

  1. 先确认SB_URL确实注入成功——在 CI 日志中检查测试步骤打印的失败链接域名是否为发布域名;
  2. 若链接仍指向localhost:6006,说明环境变量未生效,检查env块拼写与deployment_status事件是否触发;
  3. 若发布平台不发deployment_status事件,可改为在构建 Storybook 的步骤中解析产物 URL 并export SB_URL=...,其余步骤不变。

实践注意事项

  • 本地与 CI 的区分storybookUrl缺省为http://localhost:6006,本地开发无需配置;只在 CI 需要覆盖时通过SB_URL注入,避免把某个环境 URL 硬编码进提交到仓库的配置文件中。
  • 配置格式随 Vitest 大版本而变:升级 Vitest 4 时,vitest.workspace.ts的多项目描述会迁移到vitest.config.tstest.projects,插件选项本身不需要改。
  • 与本地运行机制的差异:在 watch 模式下插件可通过storybookScript选项自动拉起本地 Storybook(见 选项类型定义中的 storybookScript 说明);CI 的一次性运行中我们依赖的是已发布的实例,因此storybookUrl指向发布地址即可。
  • 完整 CI 搭建流程(定义test-storybook脚本、为 GitHub Actions / GitLab / Circle CI / Travis / Jenkins / Azure Pipelines 编写工作流、Playwright 镜像选择、代码覆盖率收集等)请参阅 In CI 完整文档;插件全量选项与 addon 的介绍见 Vitest addon 文档。

小结

storybookUrl: process.env.SB_URL是一行配置,但它打通了"CI 测试失败 → 已发布 Storybook 复现"的完整调试闭环:CI 事件提供发布 URL,插件将其写入__STORYBOOK_URL__,setup file 在失败时拼出带 story ID 与组件测试面板参数的链接。Vitest 3 用defineWorkspace、Vitest 4 用test.projects,插件写法不变。按本文配置后,团队成员在 CI 中遇到的每一个 UI 测试失败,都能一键跳转进真实环境定位问题。

【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 18:28:30

Caddy vs Nginx:极简配置与自动HTTPS,谁更适合作业?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 18:27:32

Codex上下文优化:预算管理、笔记系统与历史检索三重策略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华