测试运行器
Storybook 测试运行器将你的所有故事变成可执行测试。它由 Jest 和 Playwright 提供支持。
¥Storybook test runner turns all of your stories into executable tests. It is powered by Jest and Playwright.
-
对于那些 没有播放函数:它验证故事是否无错误渲染。
¥For those without a play function: it verifies whether the story renders without any errors.
-
对于那些 带有播放函数:它还检查播放函数中的错误以及所有断言是否通过。
¥For those with a play function: it also checks for errors in the play function and that all assertions passed.
这些测试在实时浏览器中运行,可以通过 命令行 或你的 CI 服务器 执行。
¥These tests run in a live browser and can be executed via the command line or your CI server.
设置
¥Setup
测试运行器是一个独立的、与框架无关的实用程序,与你的 Storybook 并行运行。你需要采取一些额外步骤来正确设置它。下面详细介绍了我们对配置和执行它的建议。
¥The test-runner is a standalone, framework-agnostic utility that runs parallel to your Storybook. You will need to take some additional steps to set it up properly. Detailed below is our recommendation to configure and execute it.
运行以下命令来安装它。
¥Run the following command to install it.
npm install @storybook/test-runner --save-dev
更新你的 package.json
脚本并启用测试运行器。
¥Update your package.json
scripts and enable the test runner.
{
"scripts": {
"test-storybook": "test-storybook"
}
}
使用以下方式启动 Storybook:
¥Start your Storybook with:
npm run storybook
Storybook 的测试运行器需要本地运行的 Storybook 实例或已发布的 Storybook 来运行所有现有测试。
¥Storybook's test runner requires either a locally running Storybook instance or a published Storybook to run all the existing tests.
最后,打开一个新的终端窗口并运行测试运行器:
¥Finally, open a new terminal window and run the test-runner with:
npm run test-storybook
配置
¥Configure
测试运行器为 Storybook 提供零配置支持。但是,你可以运行 test-storybook --eject
进行更细粒度的控制。它会在项目的根目录生成一个 test-runner-jest.config.js
文件,你可以对其进行修改。此外,你可以扩展生成的配置文件并提供 testEnvironmentOptions,因为测试运行器也在后台使用 jest-playwright。
¥Test runner offers zero-config support for Storybook. However, you can run test-storybook --eject
for more fine-grained control. It generates a test-runner-jest.config.js
file at the root of your project, which you can modify. Additionally, you can extend the generated configuration file and provide testEnvironmentOptions as the test runner also uses jest-playwright under the hood.
CLI 选项
¥CLI Options
测试运行器由 Jest 提供支持,并接受其 CLI 选项 的子集(例如 --watch
、--maxWorkers
)。如果你已经在项目中使用了任何这些标志,你应该能够将它们迁移到 Storybook 的测试运行器中而不会出现任何问题。下面列出了所有可用的标志及其使用示例。
¥The test-runner is powered by Jest and accepts a subset of its CLI options (for example, --watch
, --maxWorkers
).
If you're already using any of those flags in your project, you should be able to migrate them into Storybook's test-runner without any issues. Listed below are all the available flags and examples of using them.
选项 | 描述 |
---|---|
--help | 输出使用信息 test-storybook --help |
-s , --index-json | 在索引 json 模式下运行。自动检测(需要兼容的 Storybook)test-storybook --index-json |
--no-index-json | 禁用索引 json 模式 test-storybook --no-index-json |
-c , --config-dir [dir-name] | 从哪里加载 Storybook 配置的目录 test-storybook -c .storybook |
--watch | 在监视模式 test-storybook --watch 下运行 |
--watchAll | 监视文件更改并在发生更改时重新运行所有测试。test-storybook --watchAll |
--coverage | 在你的故事和组件 test-storybook --coverage 上运行 覆盖测试 |
--coverageDirectory | 写入覆盖率报告输出的目录 test-storybook --coverage --coverageDirectory coverage/ui/storybook |
--url | 定义要在其中运行测试的 URL。适用于自定义 Storybook URL test-storybook --url http://the-storybook-url-here.com |
--browsers | 定义要在其中运行测试的浏览器。一个或多个:chromium、firefox、webkit test-storybook --browsers firefox chromium |
--maxWorkers [amount] | 指定工作池将为运行测试 test-storybook --maxWorkers=2 生成的最大工作器数量 |
--testTimeout [amount] | 定义测试在自动标记为失败之前可以运行的最长时间(以毫秒为单位)。适用于长时间运行的测试 test-storybook --testTimeout=60000 |
--no-cache | 禁用缓存 test-storybook --no-cache |
--clearCache | 删除 Jest 缓存目录,然后退出而不运行测试 test-storybook --clearCache |
--verbose | 使用测试套件层次结构显示单个测试结果 test-storybook --verbose |
-u , --updateSnapshot | 使用此标志重新记录此测试运行期间失败的每个快照 test-storybook -u |
--eject | 创建一个本地配置文件以覆盖测试运行器 test-storybook --eject 的默认值 |
--json | 以 JSON 格式打印测试结果。此模式将把所有其他测试输出和用户消息发送到 stderr。test-storybook --json |
--outputFile | 当还指定 --json 选项时,将测试结果写入文件。test-storybook --json --outputFile results.json |
--junit | 表示应在 junit 文件中报告测试信息。test-storybook --**junit** |
--ci | 与自动存储新快照的常规行为不同,它将无法通过测试并需要使用 --updateSnapshot 运行 Jest。test-storybook --ci |
--shard [index/count] | 需要 CI。将测试套件执行拆分为多台机器 test-storybook --shard=1/8 |
--failOnConsole | 使测试在浏览器控制台错误 test-storybook --failOnConsole 上失败 |
--includeTags | 实验性功能 定义要测试的故事子集(如果它们与启用的 tags 匹配)。 test-storybook --includeTags="test-only, pages" |
--excludeTags | 实验性功能 如果故事与提供的 tags 匹配,则阻止测试它们。 test-storybook --excludeTags="no-tests, tokens" |
--skipTags | 实验性功能 配置测试运行器以跳过与提供的 tags 匹配的故事的运行测试。 test-storybook --skipTags="skip-test, layout" |
npm run test-storybook -- --watch
测试构建速度提高 2-4 倍
¥Run tests against a deployed Storybook
默认情况下,测试运行器假定你正在针对端口 6006
上的本地服务 Storybook 运行它。如果你想定义针对已部署的 Storybook 运行的目标 URL,你可以使用 --url
标志:
¥By default, the test-runner assumes that you're running it against a locally served Storybook on port 6006
. If you want to define a target URL to run against deployed Storybooks, you can use the --url
flag:
npm run test-storybook -- --url https://the-storybook-url-here.com
或者,你可以设置 TARGET_URL
环境变量并运行测试运行器:
¥Alternatively, you can set the TARGET_URL
environment variable and run the test-runner:
TARGET_URL=https://the-storybook-url-here.com yarn test-storybook
设置 CI 以运行测试
¥Set up CI to run tests
你还可以配置测试运行器以在 CI 环境中运行测试。下面记录了一些帮助你入门的秘诀。
¥You can also configure the test-runner to run tests on a CI environment. Documented below are some recipes to help you get started.
通过 Github Actions 部署针对已部署的 Storybooks 运行
¥Run against deployed Storybooks via Github Actions deployment
如果你使用 Vercel 或 Netlify 等服务发布 Storybook,它们会在 GitHub Actions 中发出 deployment_status
事件。你可以使用它并将 deployment_status.target_url
设置为 TARGET_URL
环境变量。操作方法如下:
¥If you're publishing your Storybook with services such as Vercel or Netlify, they emit a deployment_status
event in GitHub Actions. You can use it and set the deployment_status.target_url
as the TARGET_URL
environment variable. Here's how:
# .github/workflows/storybook-tests.yml
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 }}'
针对运行未部署的 Storybook
¥Run against non-deployed Storybooks
你可以使用你的 CI 提供程序(例如,GitHub Actions、GitLab 管道、CircleCI)来针对你构建的 Storybook 构建和运行测试运行器。这是一个依赖第三方库的秘诀,也就是说,concurrently、http-server 和 wait-on 来构建 Storybook 并使用测试运行器运行测试。
¥You can use your CI provider (for example, GitHub Actions, GitLab Pipelines, CircleCI) to build and run the test runner against your built Storybook. Here's a recipe that relies on third-party libraries, that is to say, concurrently, http-server, and wait-on to build Storybook and run tests with the test-runner.
# .github/workflows/storybook-tests.yml
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"
Chromatic 和 Test runner 有什么区别?
¥What's the difference between Chromatic and Test runner?
测试运行器是一种通用测试工具,可以在本地或 CI 上运行,并可配置或扩展以运行各种测试。
¥The test-runner is a generic testing tool that can run locally or on CI and be configured or extended to run all kinds of tests.
Chromatic 是一项基于云的服务,无需设置测试运行器即可运行 visual 和 组件测试(以及即将推出的可访问性测试)。它还与你的 git 提供程序同步并管理私有项目的访问控制。
¥Chromatic is a cloud-based service that runs visual and component tests (and soon accessibility tests) without setting up the test runner. It also syncs with your git provider and manages access control for private projects.
但是,在某些情况下,你可能希望将测试运行器和 Chromatic 配对。
¥However, you might want to pair the test runner and Chromatic in some cases.
-
在本地使用它并在你的 CI 上使用 Chromatic。
¥Use it locally and Chromatic on your CI.
-
使用 Chromatic 进行视觉和组件测试,并使用测试运行器运行其他自定义测试。
¥Use Chromatic for visual and component tests and run other custom tests using the test runner.
高级配置
¥Advanced configuration
测试钩子 API
¥Test hook API
测试运行器渲染故事并执行其 播放函数(如果存在)。但是,某些行为无法通过在浏览器中执行的播放函数实现。例如,如果你希望测试运行器为你拍摄视觉快照,这可以通过 Playwright/Jest 实现,但必须在 Node 中执行。
¥The test-runner renders a story and executes its play function if one exists. However, certain behaviors are impossible to achieve via the play function, which executes in the browser. For example, if you want the test-runner to take visual snapshots for you, this is possible via Playwright/Jest but must be executed in Node.
测试运行器导出可以全局覆盖的测试钩子,以启用可视化或 DOM 快照等用例。这些钩子使你可以在故事渲染之前和之后访问测试生命周期。下面列出了可用的钩子及其使用方法概述。
¥The test-runner exports test hooks that can be overridden globally to enable use cases like visual or DOM snapshots. These hooks give you access to the test lifecycle before and after the story is rendered. Listed below are the available hooks and an overview of how to use them.
钩子 | 描述 |
---|---|
prepare | 为测试准备浏览器 async prepare({ page, browserContext, testRunnerConfig }) {} |
setup | 在所有测试运行之前执行一次 setup() {} |
preVisit | 在首次访问故事并在浏览器中渲染之前执行 async preVisit(page, context) {} |
postVisit | 在访问故事并完全渲染后执行 async postVisit(page, context) {} |
这些测试钩子是实验性的,可能会发生重大变化。我们鼓励你在故事的 播放函数 中尽可能多地进行测试。
¥These test hooks are experimental and may be subject to breaking changes. We encourage you to test as much as possible within the story's play function.
要启用 hooks API,你需要在 Storybook 目录中添加一个新的配置文件并按如下方式设置它们:
¥To enable the hooks API, you'll need to add a new configuration file inside your Storybook directory and set them up as follows:
import type { TestRunnerConfig } from '@storybook/test-runner';
const config: TestRunnerConfig = {
// Hook that is executed before the test runner starts running tests
setup() {
// Add your configuration here.
},
/* Hook to execute before a story is initially visited before being rendered in the browser.
* The page argument is the Playwright's page object for the story.
* The context argument is a Storybook object containing the story's id, title, and name.
*/
async preVisit(page, context) {
// Add your configuration here.
},
/* Hook to execute after a story is visited and fully rendered.
* The page argument is the Playwright's page object for the story
* The context argument is a Storybook object containing the story's id, title, and name.
*/
async postVisit(page, context) {
// Add your configuration here.
},
};
export default config;
除了 setup
函数之外,所有其他函数都异步运行。preVisit
和 postVisit
函数都包含两个附加参数,Playwright 页面 和上下文对象,其中包含故事的 id
、title
和 name
。
¥Except for the setup
function, all other functions run asynchronously. Both preVisit
and postVisit
functions include two additional arguments, a Playwright page and a context object which contains the id
, title
, and the name
of the story.
当测试运行器执行时,你现有的测试将经历以下生命周期:
¥When the test-runner executes, your existing tests will go through the following lifecycle:
-
setup
函数在所有测试运行之前执行。¥The
setup
function is executed before all the tests run. -
生成包含所需信息的上下文对象。
¥The context object is generated containing the required information.
-
Playwright 导航到故事页面。
¥Playwright navigates to the story's page.
-
preVisit
函数已执行。¥The
preVisit
function is executed. -
故事被渲染,并且任何现有的
play
函数都被执行。¥The story is rendered, and any existing
play
functions are executed. -
postVisit
函数已执行。¥The
postVisit
function is executed.
(实验性)过滤测试
¥(Experimental) Filter tests
当你在 Storybook 上运行测试运行器时,它会默认测试每个故事。但是,如果你想过滤测试,则可以使用 tags
配置选项。Storybook 最初引入此功能是为了为故事生成 自动文档。但可以进一步扩展以配置测试运行器,使用类似的配置选项或通过 CLI 标志(例如 --includeTags
、--excludeTags
、--skipTags
)根据提供的标签运行测试,仅适用于最新稳定版本(0.15
或更高版本)。下面列出了可用的选项及其使用方法概述。
¥When you run the test-runner on Storybook, it tests every story by default. However, if you want to filter the tests, you can use the tags
configuration option. Storybook originally introduced this feature to generate automatic documentation for stories. But it can be further extended to configure the test-runner to run tests according to the provided tags using a similar configuration option or via CLI flags (e.g., --includeTags
, --excludeTags
, --skipTags
), only available with the latest stable release (0.15
or higher). Listed below are the available options and an overview of how to use them.
选项 | 描述 |
---|---|
exclude | 防止故事与提供的标签匹配而被测试。 |
include | 定义仅当故事子集与启用的标签匹配时才进行测试。 |
skip | 如果故事与提供的标签匹配,则跳过对故事的测试。 |
import type { TestRunnerConfig } from '@storybook/test-runner';
const config: TestRunnerConfig = {
tags: {
include: ['test-only', 'pages'],
exclude: ['no-tests', 'tokens'],
skip: ['skip-test', 'layout'],
},
};
export default config;
使用 CLI 标志运行测试优先于配置文件中提供的选项,并将覆盖配置文件中的可用选项。
¥Running tests with the CLI flags takes precedence over the options provided in the configuration file and will override the available options in the configuration file.
禁用测试
¥Disabling tests
如果你想阻止测试运行器测试特定的故事,你可以使用自定义标签配置你的故事,将其启用到测试运行器配置文件中,或者使用 --excludeTags
CLI 标志运行测试运行器并将其排除在测试之外。当你想要排除尚未准备好进行测试或与你的测试无关的故事时,这很有用。例如:
¥If you want to prevent specific stories from being tested by the test-runner, you can configure your story with a custom tag, enable it to the test-runner configuration file or run the test-runner with the --excludeTags
CLI flag and exclude them from testing. This is helpful when you want to exclude stories that are not yet ready for testing or are irrelevant to your tests. For example:
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
import { MyComponent } from './MyComponent';
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['no-tests'], // 👈 Provides the `no-tests` tag to all stories in this file
};
export default meta;
type Story = StoryObj<typeof MyComponent>;
export const ExcludeStory: Story = {
//👇 Adds the `no-tests` tag to this story to exclude it from the tests when enabled in the test-runner configuration
tags: ['no-tests'],
};
(选项
¥Run tests for a subset of stories
要允许测试运行器仅对特定故事或故事子集运行测试,你可以使用自定义标签配置故事,在测试运行器配置文件中启用它,或使用 --includeTags
CLI 标志运行测试运行器并将它们包含在测试中。例如,如果你想基于 test-only
标签运行测试,你可以按如下方式调整配置:
¥To allow the test-runner only to run tests on a specific story or subset of stories, you can configure the story with a custom tag, enable it in the test-runner configuration file or run the test-runner with the --includeTags
CLI flag and include them in your tests. For example, if you wanted to run tests based on the test-only
tag, you can adjust your configuration as follows:
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
import { MyComponent } from './MyComponent';
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['test-only'], // 👈 Provides the `test-only` tag to all stories in this file
};
export default meta;
type Story = StoryObj<typeof MyComponent>;
export const IncludeStory: Story = {
//👇 Adds the `test-only` tag to this story to be included in the tests when enabled in the test-runner configuration
tags: ['test-only'],
};
为组件的故事应用标签应该在组件级别(使用 meta
)或故事级别完成。Storybook 不支持跨故事导入标签,并且无法按预期工作。
¥Applying tags for the component's stories should either be done at the component level (using meta
) or at the story level. Importing tags across stories is not supported in Storybook and won't work as intended.
跳过测试
¥Skip tests
如果你想跳过对特定故事或故事子集运行测试,你可以使用自定义标签配置你的故事,在测试运行器配置文件中启用它,或者使用 --skipTags
CLI 标志运行测试运行器。使用此选项运行测试将导致测试运行器忽略并在测试结果中相应地标记它们,表明测试被暂时禁用。例如:
¥If you want to skip running tests on a particular story or subset of stories, you can configure your story with a custom tag, enable it in the test-runner configuration file, or run the test-runner with the --skipTags
CLI flag. Running tests with this option will cause the test-runner to ignore and flag them accordingly in the test results, indicating that the tests are temporarily disabled. For example:
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
import { MyComponent } from './MyComponent';
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['skip-test'], // 👈 Provides the `skip-test` tag to all stories in this file
};
export default meta;
type Story = StoryObj<typeof MyComponent>;
export const SkipStory: Story = {
//👇 Adds the `skip-test` tag to this story to allow it to be skipped in the tests when enabled in the test-runner configuration
tags: ['skip-test'],
};
已部署 Storybooks 的身份验证
¥Authentication for deployed Storybooks
如果你使用需要身份验证来托管 Storybook 的安全托管提供商,则可能需要设置 HTTP 标头。这主要是因为测试运行器如何通过获取请求和 Playwright 检查实例的状态及其故事的索引。为此,你可以修改测试运行器配置文件以包含 getHttpHeaders
函数。此函数将获取调用和页面访问的 URL 作为输入,并返回包含需要设置的标头的对象。
¥If you use a secure hosting provider that requires authentication to host your Storybook, you may need to set HTTP headers. This is mainly because of how the test runner checks the status of the instance and the index of its stories through fetch requests and Playwright. To do this, you can modify the test-runner configuration file to include the getHttpHeaders
function. This function takes the URL of the fetch calls and page visits as input and returns an object containing the headers that need to be set.
import type { TestRunnerConfig } from '@storybook/test-runner';
const config: TestRunnerConfig = {
getHttpHeaders: async (url) => {
const token = url.includes('prod') ? 'prod-token' : 'dev-token';
return {
Authorization: `Bearer ${token}`,
};
},
};
export default config;
助手
¥Helpers
测试运行器导出一些辅助程序,这些辅助程序可用于通过访问 Storybook 的内部结构(例如 args
、parameters
)使你的测试更具可读性和可维护性。下面列出了可用的辅助程序及其使用方法概述。
¥The test-runner exports a few helpers that can be used to make your tests more readable and maintainable by accessing Storybook's internals (e.g., args
, parameters
). Listed below are the available helpers and an overview of how to use them.
import type { TestRunnerConfig } from '@storybook/test-runner';
import { getStoryContext, waitForPageReady } from '@storybook/test-runner';
const config: TestRunnerConfig = {
// Hook that is executed before the test runner starts running tests
setup() {
// Add your configuration here.
},
/* Hook to execute before a story is initially visited before being rendered in the browser.
* The page argument is the Playwright's page object for the story.
* The context argument is a Storybook object containing the story's id, title, and name.
*/
async preVisit(page, context) {
// Add your configuration here.
},
/* Hook to execute after a story is visited and fully rendered.
* The page argument is the Playwright's page object for the story
* The context argument is a Storybook object containing the story's id, title, and name.
*/
async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);
// This utility function is designed for image snapshot testing. It will wait for the page to be fully loaded, including all the async items (e.g., images, fonts, etc.).
await waitForPageReady(page);
// Add your configuration here.
},
};
export default config;
使用测试运行器访问故事信息
¥Accessing story information with the test-runner
如果你需要访问有关故事的信息(例如其参数),测试运行器包含一个名为 getStoryContext
的辅助函数,你可以使用它来检索它。然后,你可以根据需要使用它来进一步自定义测试。例如,如果你需要配置 Playwright 的页面 视口大小 以使用故事参数中定义的视口大小,你可以按如下方式操作:
¥If you need to access information about the story, such as its parameters, the test-runner includes a helper function named getStoryContext
that you can use to retrieve it. You can then use it to customize your tests further as needed. For example, if you need to configure Playwright's page viewport size to use the viewport size defined in the story's parameters, you can do so as follows:
import type { TestRunnerConfig } from '@storybook/test-runner';
import { getStoryContext } from '@storybook/test-runner';
const { MINIMAL_VIEWPORTS } = require('@storybook/addon-viewport');
const DEFAULT_VIEWPORT_SIZE = { width: 1280, height: 720 };
const config: TestRunnerConfig = {
async preVisit(page, story) {
// Accesses the story's parameters and retrieves the viewport used to render it
const context = await getStoryContext(page, story);
const viewportName = context.parameters?.viewport?.defaultViewport;
const viewportParameter = MINIMAL_VIEWPORTS[viewportName];
if (viewportParameter) {
const viewportSize = Object.entries(viewportParameter.styles).reduce(
(acc, [screen, size]) => ({
...acc,
// Converts the viewport size from percentages to numbers
[screen]: parseInt(size),
}),
{},
);
// Configures the Playwright page to use the viewport size
page.setViewportSize(viewportSize);
} else {
page.setViewportSize(DEFAULT_VIEWPORT_SIZE);
}
},
};
export default config;
使用资源
¥Working with assets
如果你正在运行一组特定的测试(例如,图片快照测试),测试运行器会提供一个名为 waitForPageReady
的辅助函数,你可以使用它来确保页面在运行测试之前已完全加载并准备就绪。例如:
¥If you're running a specific set of tests (e.g., image snapshot testing), the test-runner provides a helper function named waitForPageReady
that you can use to ensure the page is fully loaded and ready before running the test. For example:
import type { TestRunnerConfig } from '@storybook/test-runner';
import { waitForPageReady } from '@storybook/test-runner';
import { toMatchImageSnapshot } from 'jest-image-snapshot';
const customSnapshotsDir = `${process.cwd()}/__snapshots__`;
const config: TestRunnerConfig = {
setup() {
expect.extend({ toMatchImageSnapshot });
},
async postVisit(page, context) {
// Awaits for the page to be loaded and available including assets (e.g., fonts)
await waitForPageReady(page);
// Generates a snapshot file based on the story identifier
const image = await page.screenshot();
expect(image).toMatchImageSnapshot({
customSnapshotsDir,
customSnapshotIdentifier: context.id,
});
},
};
export default config;
Index.json 模式
¥Index.json mode
测试运行器在测试本地 Storybook 时将你的故事文件转换为测试。对于远程 Storybook,它使用 Storybook 的 index.json(以前称为 stories.json
)文件(所有故事的静态索引)来运行测试。
¥The test-runner transforms your story files into tests when testing a local Storybook. For a remote Storybook, it uses the Storybook's index.json (formerly stories.json
) file (a static index of all the stories) to run the tests.
为什么?
¥Why?
假设你遇到本地和远程 Storybook 不同步的情况,或者你甚至可能无法访问代码。在这种情况下,index.json
文件保证是你正在测试的已部署 Storybook 的最准确表示。要使用此功能测试本地 Storybook,请使用 --index-json
标志,如下所示:
¥Suppose you run into a situation where the local and remote Storybooks appear out of sync, or you might not even have access to the code. In that case, the index.json
file is guaranteed to be the most accurate representation of the deployed Storybook you are testing. To test a local Storybook using this feature, use the --index-json
flag as follows:
npm run test-storybook -- --index-json
index.json
模式与 watch 模式不兼容。
¥The index.json
mode is not compatible with the watch mode.
如果你需要禁用它,请使用 --no-index-json
标志:
¥If you need to disable it, use the --no-index-json
flag:
npm run test-storybook -- --no-index-json
如何检查我的 Storybook 是否有 index.json
文件?
¥How do I check if my Storybook has a index.json
file?
Index.json 模式需要 index.json
文件。打开浏览器窗口并导航到你部署的 Storybook 实例(例如,https://your-storybook-url-here.com/index.json
)。你应该看到一个以 "v": 3
键开头的 JSON 文件,紧接着是另一个名为 "stories" 的键,其中包含故事 ID 到 JSON 对象的映射。如果是这种情况,你的 Storybook 支持 index.json 模式。
¥Index.json mode requires a index.json
file. Open a browser window and navigate to your deployed Storybook instance (for example, https://your-storybook-url-here.com/index.json
). You should see a JSON file that starts with a "v": 3
key, immediately followed by another key called "stories", which contains a map of story IDs to JSON objects. If that is the case, your Storybook supports index.json mode.
故障排除
¥Troubleshooting
测试构建速度提高 2-4 倍
¥The test runner seems flaky and keeps timing out
如果你的测试超时并显示以下消息:
¥If your tests time out with the following message:
Timeout - Async callback was not invoked within the 15000 ms timeout specified by jest.setTimeout
可能是 Playwright 无法处理测试你项目中的故事数量。也许你有大量的故事,或者你的 CI 环境的 RAM 配置真的很低。在这种情况下,你应该通过调整命令来限制并行运行的工作程序数量,如下所示:
¥It might be that Playwright couldn't handle testing the number of stories you have in your project. Perhaps you have a large number of stories, or your CI environment has a really low RAM configuration. In such cases, you should limit the number of workers that run in parallel by adjusting your command as follows:
{
"scripts": {
"test-storybook:ci": "yarn test-storybook --maxWorkers=2"
}
}
CLI 中的错误输出太短
¥The error output in the CLI is too short
默认情况下,测试运行器会在 1000 个字符处截断错误输出,你可以在浏览器中的 Storybook 中直接检查完整输出。但是,如果你想更改该限制,你可以通过将 DEBUG_PRINT_LIMIT
环境变量设置为你选择的数字来实现,例如 DEBUG_PRINT_LIMIT=5000 yarn test-storybook
。
¥By default, the test runner truncates error outputs at 1000 characters, and you can check the full output directly in Storybook in the browser. However, if you want to change that limit, you can do so by setting the DEBUG_PRINT_LIMIT
environment variable to a number of your choosing, for example, DEBUG_PRINT_LIMIT=5000 yarn test-storybook
.
在其他 CI 环境中运行测试运行器
¥Run the test runner in other CI environments
由于测试运行器基于 Playwright,你可能需要根据你的 CI 设置使用特定的 docker 镜像或其他配置。在这种情况下,你可以参考 Playwright CI 文档 了解更多信息。
¥As the test runner is based on Playwright, you might need to use specific docker images or other configurations depending on your CI setup. In that case, you can refer to the Playwright CI docs for more information.
按标签过滤的测试执行不正确
¥Tests filtered by tags are incorrectly executed
如果你已启用使用标签过滤测试并为 include
和 exclude
列表提供了类似的标签,则测试运行器将根据 exclude
列表执行测试并忽略 include
列表。为了避免这种情况,请确保提供给 include
和 exclude
列表的标签不同。
¥If you've enabled filtering tests with tags and provided similar tags to the include
and exclude
lists, the test-runner will execute the tests based on the exclude
list and ignore the include
list. To avoid this, make sure the tags provided to the include
and exclude
lists differ.
测试运行器不支持开箱即用的 Yarn PnP
¥The test runner doesn't support Yarn PnP out of the box
如果你在运行较新版本的 Yarn 且启用了 Plug'n'Play (PnP) 的项目中启用了测试运行器,则测试运行器可能无法按预期工作,并且在运行测试时可能会生成以下错误:
¥If you've enabled the test-runner in a project running on a newer version of Yarn with Plug'n'Play (PnP) enabled, the test-runner might not work as expected and may generate the following error when running tests:
PlaywrightError: jest-playwright-preset: Cannot find playwright package to use chromium
这是因为测试运行器使用社区维护的包 jest-playwright-preset,它仍然需要支持此功能。要解决此问题,你可以将 nodeLinker
设置切换为 node-modules
或将 Playwright 安装为项目中的直接依赖,然后通过 install
命令添加浏览器二进制文件。
¥This is due to the test-runner using the community-maintained package jest-playwright-preset that still needs to support this feature. To solve this, you can either switch the nodeLinker
setting to node-modules
or install Playwright as a direct dependency in your project, followed by adding the browser binaries via the install
command.
了解其他 UI 测试
¥Learn about other UI tests
-
组件测试 提供有关用户行为模拟
¥Component tests for user behavior simulation
-
视觉测试 用于外观
¥Visual tests for appearance
-
可访问性测试 用于可访问性
¥Accessibility tests for accessibility
-
快照测试 提供有关渲染错误和警告
¥Snapshot tests for rendering errors and warnings
-
用于自动化测试执行的测试运行器
¥Test runner to automate test execution
-
测试覆盖率 用于测量代码覆盖率
¥Test coverage for measuring code coverage
-
端到端测试 提供有关模拟真实用户场景
¥End-to-end tests for simulating real user scenarios
-
单元测试 用于功能性
¥Unit tests for functionality