返回博客

用于 Playwright 组件测试的可移植 Stories

通过最少的设置即可在 Playwright CT 中测试您的 Stories。

loading
Yann Braga
@yannbf
最后更新

Storybook 是构建、文档化和测试 UI 组件的行业标准工作台。Shopify、Gov.UK 和 NASA 等领先的开发团队都在使用它。

在 Storybook 中开发最大的好处之一是,你可以免费获得测试。每个独立的组件示例(或“故事”)都是一个 UI 测试。如果你想测试数据获取和用户交互,Storybook 也有相应的工具!

为了将你的故事作为测试执行,Storybook 包含一个基于 Playwright 的测试运行器。虽然有成千上万的团队乐于使用它来功能性地测试他们的组件,但也有一些团队希望在其他测试工具和环境中重用他们的故事,例如Playwright CT(组件测试)。

这就是为什么我很高兴地宣布一个名为“Portable Stories API”的新的、实验性的 API。

  • ✍️ 使用为组件开发量身定制的组件故事格式 (CSF) 编写故事
  • 🧪 在 Playwright CT 中测试这些故事,重用 props/样式/组件设置
  • 🥳 在 Storybook 8.1 中适用于 React 18+ 和 Vue 3

请继续阅读,了解更多关于如何在你的项目中将可移植故事与 Playwright CT 结合使用的信息。

可移植的故事

要在隔离环境中(你的应用之外)渲染组件,你需要为其提供必要的上下文,包括 props、providers、wrappers 和 mocks。这对在 Vitest、Cypress CT 和 Playwright CT 等工具中测试组件是一个挑战。

Storybook 创建了一个用于隔离开发 UI 组件的格式,该格式经过优化,可以提供这些输入。组件故事格式 (CSF) 是快速编目你组件所有关键变体的最佳方式。

Illustration showing the code for each story and their visual representation.
每个命名导出都是一个故事,它捕获了渲染组件的所有上下文。

可移植故事是一个 API,它将此故事上下文转换为可正确渲染的组件。例如,一个 React 故事变成一个 React 组件,一个 Vue 故事变成一个 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 函数和它自己的基于 Playwright 的测试运行器提供内置的测试功能。这使你能够验证组件如何响应用户交互,例如点击、输入和鼠标输入。这是我们推荐的组件测试栈。

然而,你有很多理由可以考虑使用 Playwright CT。它速度很快,拥有令人难以置信的VSCode 集成,以及其他很酷的功能,例如测试生成器跟踪查看器

嘿 Storybook 社区,我们刚刚发布了视觉测试插件,可以跨多个浏览器和视口自动测试故事。这是找到像素级错误的更快、更安全的方法。

Playwright CT for Storybook 用户

如果你是 Storybook 用户,并且更喜欢使用 Playwright CT,我们希望让你的体验尽可能顺畅。从 Storybook 8.1 开始,现在可以将你的 React 和 Vue3 Storybook 故事重用到 Playwright CT 中。这需要三个步骤:

1 - 导入全局注解

在 Storybook 中,你会在一个 ` .storybook/preview.ts ` 文件中导入全局样式并定义全局注解(`args`、`decorators` 等)。Playwright CT 有一个类似的概念,在 ` playwright/index.tsx ` 下。

第一步是在你的 Playwright 设置文件中使用 Storybook 的 ` setProjectAnnotations ` API。这将确保你的可移植故事也能考虑到全局配置。

// playwright/index.tsx
import { setProjectAnnotations } from '@storybook/react' // or @storybook/vue3
import previewAnnotations from '../.storybook/preview'

setProjectAnnotations(previewAnnotations)

2 - 创建一个可移植故事文件

Playwright CT 期望使用一个“测试故事”文件。对于你想测试的每个组件,在其故事文件旁边创建一个新的 ` *.stories.portable.ts ` 文件。该文件将使用可移植故事的 ` composeStories ` API,该 API 将文件中的每个故事转换为可移植组件。

// 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)
💡
注意:目前,由于 Playwright CT 复杂的 Node 到浏览器架构,你不能在测试文件所在的同一文件中使用 ` composeStories ` API,否则会更简单。Playwright 团队正在积极改进他们的工具,所以希望将来这会变得不必要。

3 - 使用 Playwright CT 的可移植故事实验性 API

在你的测试文件中,从刚刚创建的文件中导入可移植故事,并使用 Storybook 的 ` createTest ` API,它扩展了 Playwright 的基本 ` test ` API。在挂载故事时,其所有的 ` 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')
})

就是这样!现在,每当你更改你的故事时,这些更改也会自动成为你的 Playwright 测试的一部分。

以下是 Mealdrop 中的一个示例,其中一个复杂页面(样式、状态管理、路由、数据获取等)的故事在 Playwright CT 中被重用。这个例子展示了 Playwright 的 VSCode 扩展及其测试生成器。

0:00
/0:26

Storybook for Playwright CT Users

Storybook 还可以补充你现有的 Playwright CT 测试,这将为你的测试套件带来超能力。

  1. 隔离开发环境:Storybook 提供了一个类似沙盒的环境,你可以在其中隔离构建和测试 UI 组件,而无需与其他应用程序集成。它提供了促进新组件变体(故事)创作的功能,从而更容易提高测试覆盖率。
  2. 交接与协作:Storybook 生成一个可以部署和托管在任何地方的静态应用程序,允许团队成员在不必部署整个应用程序的情况下查看和讨论修改。这有助于开发人员与设计师或利益相关者之间的协作。
  3. 文档和组件目录:Storybook 自动生成你的 UI 组件的实时文档。因此,你的团队拥有一个单一的真相来源,确保每个人都理解可用的组件以及如何使用它们。
  4. 广泛的插件生态系统:Storybook 支持各种集成和插件,这些插件可以增强其功能,从可访问性测试到设计工具集成,使其成为各种开发需求的便捷工具。
  5. 视觉回归测试:Storybook 提供了一个视觉测试插件,可确保你的 UI 在生产环境到达之前就能跨不同设备和浏览器按预期显示。

什么适合我?

Playwright CT 是一个用于在浏览器中隔离测试组件的绝佳工具。Storybook 自带的测试运行器、Cypress CT 和 Vitest 也是如此。

在未来的帖子中,我们将更仔细地审查这些选项,并分享我们对组件测试最佳实践的看法。在此期间,这些工具不仅各有优缺点,而且它们也在不断发展。今天的最佳选择很容易被明天的不同选项所取代。

可移植故事通过使你能够将隔离的组件带到最适合你的项目和个人偏好的地方,从而避免了工具锁定。我们鼓励你尝试一下,以简化和未来的组件开发和测试。

立即试用

Playwright CT 的可移植故事在 Storybook 8.1 中可用。在新项目中尝试一下。

npx storybook@latest init

或升级现有项目

npx storybook@latest upgrade

你可以按照文档了解更多关于入门和完整 API 的详细信息。

下一步

我们目前在 Playwright CT 中实验性地支持 React 18+ 和 Vue3,但计划后续支持更多渲染器和集成。我们还希望与 Playwright 团队合作,使在未来版本中设置可移植故事更容易。

加入 Storybook 邮件列表

获取最新消息、更新和发布信息

7,468开发者及更多

我们正在招聘!

加入 Storybook 和 Chromatic 团队。构建被数十万开发人员在生产中使用的工具。远程优先。

查看职位

热门帖子

Storybook 8.1

一个更具生产力、更井然有序、更可预测的 Storybook
loading
Michael Shilman

Storybook 中的类型安全模块模拟

一种新的、基于标准的模拟方法
loading
Jeppe Reinhold

Storybook 8

下一代测试、性能和兼容性
loading
Michael Shilman
加入社区
7,468开发者及更多
原因为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与进来博客
展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI