
适用于 Playwright 组件测试的便携式故事/示例
通过最少的设置在 Playwright CT 中测试你的故事/示例。

Storybook 是构建、文档化和测试 UI 组件的行业标准工作坊。它被 Shopify、Gov.UK 和 NASA 等组织的领先开发团队使用。
在 Storybook 中开发的最大好处之一是你可以免费获得测试。每个独立的组件示例——或者说“story”——都是一个 UI 测试。如果你想测试数据获取和用户交互,Storybook 也提供了相应的工具!
为了将你的 stories 作为测试执行,Storybook 包含一个基于 Playwright 的 测试运行器。虽然成千上万的团队很高兴地使用它来功能性测试他们的组件,但也有其他团队希望在其他测试工具和环境中重用他们的 stories,例如 Playwright CT(组件测试)。
这就是为什么我很兴奋地宣布一个新的实验性便携式 Stories API
- ✍️ 使用组件故事格式(CSF)编写 stories,专为组件开发量身定制
- 🧪 在 Playwright CT 中测试这些 stories,重用 props/样式/组件设置
- 🥳 在 Storybook 8.1 中可用,支持 React 18+ 和 Vue 3
继续阅读,了解如何在你的项目中使用便携式 stories 和 Playwright CT。
便携式 stories
要在隔离的环境(应用之外)中渲染一个组件,你需要为其提供必要的上下文,包括 props、providers、wrappers 和 mocks。这对在 Vitest、Cypress CT 和 Playwright CT 等工具中测试组件来说是一个挑战。
Storybook 创建了一种在隔离环境中开发 UI 组件的格式,该格式经过优化,可用于提供这些输入。组件故事格式(CSF)是快速编目组件所有关键变体的最佳方式。

便携式 stories 是一个 API,它将 story 上下文转换为一个可正确渲染的组件。例如,一个 React story 变成一个 React 组件,一个 Vue story 变成一个 Vue 组件,依此类推。
import { composeStories } from '@storybook/react' // or @storybook/vue3
import * as stories from './RestaurantCard.stories'
// Each of these components can be rendered in other environments
const { Default, New, Closed, Loading } = composeStories(stories)
这很有用,因为你可以在任何使用组件的工具中重用所有这些设置(props、样式、路由等)。在组件测试的情况下,这通常可以取代“arrange / act / assert”中的“arrange”步骤。
Storybook 交互测试 vs Playwright CT
Storybook 通过 play function 及其自己的基于 Playwright 的 test-runner 提供内置测试功能。这使你能够验证组件如何响应用户交互,例如点击、输入和鼠标输入。这是我们推荐的组件测试技术栈。
然而,你可能考虑使用 Playwright CT 的原因有很多。它速度快,拥有出色的 VSCode 集成,以及 测试生成器 和 trace viewer 等其他酷炫功能。
Playwright CT for Storybook 用户
如果你是 Storybook 用户但更喜欢使用 Playwright CT,我们希望让你的体验尽可能无缝。从 Storybook 8.1 开始,现在可以在 Playwright CT 中重用你的 React 和 Vue3 Storybook stories。这需要三个步骤
1 - 导入全局注解
在 Storybook 中,你在 .storybook/preview.ts
文件中导入全局样式并定义全局注解(args
、decorators
等)。Playwright CT 在 playwright/index.tsx
下有类似的概念。
第一步是使用 Storybook 的 setProjectAnnotations
API 作为你的 Playwright 设置文件的一部分。这将确保你的便携式 stories 也将全局配置考虑在内。
// playwright/index.tsx
import { setProjectAnnotations } from '@storybook/react' // or @storybook/vue3
import previewAnnotations from '../.storybook/preview'
setProjectAnnotations(previewAnnotations)
2 - 创建一个便携式 stories 文件
Playwright CT 期望一个 “测试 story” 文件用于测试。对于你想要测试的每个组件,在其 stories 文件旁边创建一个新的 *.stories.portable.ts
文件。该文件将使用便携式 stories 的 composeStories
API,该 API 会将文件中的每个 story 转换为一个便携式组件
// RestaurantDetailPage.stories.portable.ts
import { composeStories } from '@storybook/react'
import * as stories from './RestaurantDetailPage.stories'
// Output an object that maps 1:1 to your stories, now in portable components
export default composeStories(stories)
3 - 将便携式 stories 实验性 API 用于 Playwright CT
在你的测试文件中,从刚刚创建的文件中导入便携式 stories,并使用 Storybook 的 createTest
API,它扩展了 Playwright 的基础 test
API。挂载一个 story 后,它的所有 decorators
、loaders
和 play function
都将正确执行。
// RestaurantDetailPage.spec.tsx
// For Vue3, import from '@storybook/vue3/experimental-playwright'
import { createTest } from '@storybook/react/experimental-playwright'
// For Vue3, import from '@playwright/experimental-ct-vue'
import { test as base, expect } from '@playwright/experimental-ct-react'
import stories from './RestaurantDetailPage.stories.portable'
const test = createTest(base)
test('Default', async ({ mount }) => {
// The mount function will execute all the necessary steps in the story,
// such as loaders, render, and play function
await mount(<stories.Default />)
})
test('WithItemsInTheCart', async ({ mount, page }) => {
await mount(<stories.Success />)
await page.getByLabel('menu item').first().click()
await page.getByLabel('increase quantity by one').click()
await page.getByLabel('confirm').click()
await expect(page.getByLabel('food cart')).toContainText('€25.50')
})
就是这样!现在,无论你何时对你的 stories 进行更改,这些更改也将自动成为你的 Playwright 测试的一部分。
这是 Mealdrop 中的一个例子,其中一个复杂页面(样式、状态管理、路由、数据获取等)的 stories 在 Playwright CT 中被重用。这个例子展示了 Playwright 的 VSCode 扩展及其测试生成器
Storybook for Playwright CT 用户
Storybook 也可以补充你现有的 Playwright CT 测试,这将为你的测试套件带来超能力
- 隔离的开发环境:Storybook 提供了一个类似沙盒的环境,你可以在其中独立于应用程序的其余部分构建和测试 UI 组件。它提供了便于为你的组件编写新变体(stories)的功能,从而更容易提高测试覆盖率。
- 移交和协作:Storybook 生成一个静态应用,可以部署和托管在任何地方,允许团队成员在不部署整个应用的情况下查看和讨论修改。这有助于开发者与设计师或利益相关者之间的协作。
- 文档和组件目录:Storybook 自动生成一个你的 UI 组件的活文档。因此,你的团队拥有一个单一的真相来源,确保每个人都理解可用的组件以及应如何使用它们。
- 丰富的附加组件生态系统:Storybook 支持广泛的集成和附加组件,可增强其功能,从可访问性测试到设计工具集成,使其成为满足各种开发需求的便捷工具。
- 可视化回归测试:Storybook 提供了一个 可视化测试附加组件,可确保你的 UI 在发布到生产环境之前在不同设备和浏览器上看起来符合预期。

哪种方法适合我?
Playwright CT 是一个用于在隔离环境中进行浏览器组件测试的强大工具。Storybook 自己的测试运行器、Cypress CT 和 Vitest 也是如此。
在未来的文章中,我们将更批判性地审视这些选项,并分享我们对组件测试最佳实践的看法。与此同时,这些工具不仅各有优缺点,而且它们也是不断发展的目标。今天最好的选择明天很容易被另一种选项所超越。
便携式 stories 通过使你能够将隔离的组件带到最适合你的项目和个人偏好的地方,从而避免了工具锁定。我们鼓励你试一试,将其作为简化和未来化组件开发和测试的一种方式。
立即试用
适用于 Playwright CT 的便携式 stories 在 Storybook 8.1 中可用。在新项目中尝试
npx storybook@latest init
或升级现有项目
npx storybook@latest upgrade
你可以按照文档了解更多入门细节和完整的 API。
未来展望
目前我们在 Playwright CT 中实验性地支持 React 18+ 和 Vue3,但计划后续支持更多渲染器和集成。我们也希望与 Playwright 团队合作,在未来版本中使便携式 stories 更易于设置。
在 @playwrightweb 组件测试中使用 stories 测试你的组件!
— Storybook (@storybookjs) 2024年5月16日
🧳 引入便携式 stories API
✍️ 使用组件故事格式编写 stories
♻️ 在 Playwright CT 中重用这些 stories
🤝 Storybook & Playwright 配合良好
支持 React 18+ 和 Vue 3。
👇 pic.twitter.com/HzHOhDofoC