Storybook Test Runner 远程测试实战:使用 --url 与 TARGET_URL 针对已部署 Storybook 运行测试
Storybook Test Runner 会把你的每一个 story 变成可执行的测试,默认假设它运行在本地 6006 端口的 Storybook 实例上。本篇技术指南聚焦"如何让 Test Runner 针对已部署/远程的 Storybook 运行测试"这一核心场景,讲解 --url 命令行参数与 TARGET_URL 环境变量两种目标地址注入方式,并给出接入 CI(GitHub Actions)的完整工作流示例。读完本文,你将掌握把 story 测试指向任意线上地址、在部署事件触发时自动跑测试,以及通过 index.json 模式确保远程测试与线上实例精确同步的完整方案。
本文内容以官方文档 docs/writing-tests/integrations/test-runner.mdx 为骨架,代码片段均出自仓库 docs/_snippets 目录下的真实配置示例。
为什么需要指定测试目标地址
Storybook Test Runner 是一个独立的、与框架无关的测试工具,基于 Jest 与 Playwright 构建,在你的 Storybook 之外并行运行。它的工作方式决定了它必须有一个明确的目标实例:
- 对于没有 play function 的 story:验证 story 能否无错误渲染;
- 对于带 play function 的 story:额外校验 play function 执行是否报错、所有断言是否通过。
这些测试在真实浏览器中执行,因此 Test Runner 需要一个可访问的 Storybook 地址。默认情况下,它假定你正在针对本地 6006 端口提供服务的 Storybook 运行(本地运行命令见 test-runner-execute.md)。
一旦你希望测试已部署的 Storybook(例如发布到 Vercel、Netlify 或自建服务器的线上实例),就必须把目标地址告诉 Test Runner。官方为此提供了两种等价方式:--url 命令行参数,以及 TARGET_URL 环境变量。
方式一:使用 --url 命令行参数
--url 参数用于"定义运行测试的 URL,适用于自定义 Storybook URL"。这是最直观的方式,直接在一次命令调用中指定目标地址。
针对不同包管理器,官方在 test-runner-execute-with-url.md 中给出了标准用法:
npm run test-storybook -- --url https://the-storybook-url-here.com
pnpm run test-storybook --url https://the-storybook-url-here.com
yarn test-storybook --url https://the-storybook-url-here.com
注意三种写法中 -- 分隔符的使用差异:npm 的 run 脚本会把 -- 之后的内容透传给底层命令,因此需要显式写出 -- --url ...;而 pnpm 与 yarn 在对应文档示例中直接使用 --url ...。请根据你项目实际使用的包管理器选择对应写法,并将示例地址替换为你自己的线上 Storybook 地址。
方式二:使用 TARGET_URL 环境变量
除了 --url 参数,Test Runner 同样支持通过 TARGET_URL 环境变量指定目标地址。官方文档给出的用法如下:
TARGET_URL=https://the-storybook-url-here.com yarn test-storybook
环境变量方式的最大价值在于解耦"测试命令"与"目标地址":你可以在 package.json 中保持脚本不变,而在不同环境(本地、CI 的不同任务)中注入不同的 TARGET_URL 值。这一特性在 CI 场景中尤为关键——因为 CI 上你往往无法预知部署后的最终 URL,只能通过环境变量在运行时传入。
远程测试的基石:index.json 模式
理解远程测试,必须理解 Test Runner 的两种故事获取机制。官方文档(test-runner.mdx 的 "Index.json mode" 章节)说明:
- 测试本地 Storybook 时,Test Runner 直接把你本地的 story 文件转换成测试;
- 测试远程 Storybook 时,它读取该实例生成的
index.json(旧称stories.json)——这是线上所有 story 的静态索引——来运行测试。
为什么远程场景依赖 index.json?官方给出的理由是:当本地代码与远程部署出现不同步,或者你根本没有代码访问权限时,index.json 文件是你正在测试的那个已部署 Storybook 最准确的表现形式。换言之,--url / TARGET_URL 解决的是"访问哪个实例",index.json 解决的是"测哪些 story、以什么状态为准",两者配合才能保证远程测试的可靠性。
如果你希望在测试本地 Storybook 时也强制使用该模式,可以显式传入 --index-json 标志(参考 test-runner-with-index-json.md):
npm run test-storybook -- --index-json
pnpm run test-storybook --index-json
yarn test-storybook --index-json
对应的关闭标志为 --no-index-json。需要特别留意的是:index.json 模式与 watch 模式不兼容。在本地运行 --index-json 时,Test Runner 会自动检测目标实例是否支持该模式。
如何确认线上 Storybook 支持 index.json 模式
在浏览器中打开你的已部署 Storybook 地址并访问 https://your-storybook-url-here.com/index.json。如果返回的 JSON 以 "v": 3 开头,且紧接着是一个名为 stories 的键(值为 story ID 到 JSON 对象的映射),则说明该实例支持 index.json 模式,可以放心地通过 --url 或 TARGET_URL 对它执行远程测试。
CI 实战一:针对已部署 Storybook 运行测试
将远程测试接入 CI 的官方推荐方案,是利用部署平台(如 Vercel、Netlify)在 GitHub Actions 中触发的 deployment_status 事件。这些服务在部署完成时会发出该事件,其中携带 target_url 字段,正好可以作为 TARGET_URL 注入测试任务。完整工作流见 test-runner-with-deploy-event-workflow.md:
name: Storybook Tests
on: deployment_status
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
if: github.event.deployment_status.state == 'success'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Install dependencies
run: yarn
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run Storybook tests
run: yarn test-storybook
env:
TARGET_URL: '${{ github.event.deployment_status.target_url }}'
该工作流的几个关键点:
- 触发时机:
on: deployment_status使每次部署状态变更都触发工作流,配合if: github.event.deployment_status.state == 'success'只在部署成功后才运行测试,避免对失败的部署空跑; - 浏览器依赖:Test Runner 基于 Playwright,因此 CI 中需要执行
npx playwright install --with-deps安装浏览器及其系统依赖; - 地址注入:测试命令本身保持
yarn test-storybook不变,通过env.TARGET_URL注入github.event.deployment_status.target_url,这正是TARGET_URL环境变量方式的核心价值。
适用前提:该方案要求已发布的 Storybook 是公开可访问的。如果线上实例需要认证,官方建议改用下面的"构建后本地测试"方案,或配合 HTTP 头认证配置(见后文)。
CI 实战二:构建并服务 Storybook 后运行测试
当你不希望依赖外部部署(或线上实例需要认证)时,可以在 CI 内自己构建 Storybook、本地启动静态服务,再运行测试。官方基于 concurrently、http-server 与 wait-on 三个第三方库给出了配方,见 test-runner-local-build-workflow.md:
name: 'Storybook Tests'
on: push
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
- name: Install dependencies
run: yarn
- name: Install Playwright
run: npx playwright install --with-deps
- name: Build Storybook
run: yarn build-storybook --quiet
- name: Serve Storybook and run tests
run: |
npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
"npx http-server storybook-static --port 6006 --silent" \
"npx wait-on tcp:127.0.0.1:6006 && yarn test-storybook"
理解这个配方的执行链条:
yarn build-storybook --quiet将 Storybook 构建为静态应用;concurrently同时启动两条命令:http-server在 6006 端口托管storybook-static目录,wait-on轮询tcp:127.0.0.1:6006直到端口就绪后才执行yarn test-storybook;-k保证其中一条命令退出时杀掉另一条,-s first以最先退出的命令的退出码作为整体结果。
注意:默认情况下 Storybook 将构建产物输出到 storybook-static 目录(参见 docs/writing-tests/integrations/test-runner.mdx 中对应的说明)。如果你配置了不同的构建输出目录,需要相应调整 http-server 的路径参数。
与 URL 相关的 CLI 选项与配置细节
在"针对远程实例测试"的场景中,以下几个 CLI 选项(完整清单见 test-runner.mdx 的 "CLI Options" 表格)值得配套掌握:
| 选项 | 说明 |
|---|---|
-s, --index-json |
以 index.json 模式运行,兼容的 Storybook 会自动检测;远程测试的核心支撑 |
--no-index-json |
关闭 index.json 模式 |
--browsers |
指定测试浏览器,可选 chromium、firefox、webkit 中的一种或多种,如 test-storybook --browsers firefox chromium |
--maxWorkers [amount] |
限制并行 worker 数量,如 test-storybook --maxWorkers=2;story 数量庞大或 CI 内存吃紧时用于缓解超时 |
--testTimeout [amount] |
单个测试的最长运行毫秒数,超时自动判失败,如 test-storybook --testTimeout=60000 |
--failOnConsole |
浏览器 console 报错即判测试失败 |
--ci |
不再自动保存新快照,而是判失败并要求用 --updateSnapshot 显式更新 |
远程实例需要认证怎么办
如果托管平台要求认证,Test Runner 探测实例状态与故事索引依赖 fetch 请求和 Playwright 页面访问,此时需要为这些请求附加 HTTP 头。官方方案是在 Test Runner 配置文件中实现 getHttpHeaders 函数:它接收 fetch 调用与页面访问的 URL 作为输入,返回需要设置的请求头对象。这样即便线上 Storybook 有访问控制,--url / TARGET_URL 指向的远程测试依然可以正常执行。
常见问题与排查
- 测试频繁超时:若出现
Timeout - Async callback was not invoked within the 15000 ms timeout specified by jest.setTimeout,通常是 Playwright 并发处理大量 story 时资源不足(story 数量多,或 CI 内存配置低)。可通过降低并行度缓解,例如在package.json中配置"test-storybook:ci": "yarn test-storybook --maxWorkers=2"。 - CLI 错误输出太短:Test Runner 默认将错误输出截断为 1000 字符,完整输出可在浏览器中直接查看 Storybook。若需调整,可设置
DEBUG_PRINT_LIMIT环境变量,例如DEBUG_PRINT_LIMIT=5000 yarn test-storybook。 - 远程与本地不同步:优先使用
--index-json模式,以线上实例的index.json为唯一测试依据,可避免本地代码与部署实例不一致导致的误判。 - Yarn PnP 兼容性:较新版本 Yarn 启用 Plug'n'Play 时,Test Runner 底层使用的
jest-playwright-preset可能无法找到 Playwright 包(报错PlaywrightError: jest-playwright-preset: Cannot find playwright package to use chromium)。可将nodeLinker切换为node-modules,或把 Playwright 安装为项目的直接依赖并执行其浏览器安装命令。
总结
针对已部署 Storybook 运行测试,是 Storybook Test Runner 从"本地开发辅助"走向"线上质量守门"的关键一步。核心要点可归纳为三条:
- 两种注入方式等价:
--url适合单次临时指定目标地址,TARGET_URL环境变量适合把地址与命令解耦、在 CI 中动态注入; - 远程测试依赖 index.json 模式:先访问
你的地址/index.json确认返回"v": 3结构,再用--url或TARGET_URL指向该实例,即可保证测试与线上内容精确同步; - CI 落地有两套官方配方:面向已部署实例的
deployment_status+TARGET_URL方案(要求实例公开可访问),以及构建后本地http-server+wait-on方案(适用于需要认证或不便依赖外部部署的场景)。
更多细节(完整的 CLI 选项表、快照测试、覆盖率、Hook API、tags 过滤测试等)可继续阅读 docs/writing-tests/integrations/test-runner.mdx 及其配套的 docs/_snippets 目录下的示例片段。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0632
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00