返回博客

Storybook 8.2

迈向无妥协的组件测试

loading
Michael Shilman
@mshilman
最后更新

Storybook 是世界顶级设计系统背后的组件工作室(如 CarbonPolarisFluentLightning 等)。因此,它通常与构建和记录可重用原子组件相关联。

但是 UI 组件的大小和形状各不相同。

对于 Faire、Yoobic 和 Monday.com 的团队来说,Storybook 是构建“产品 UI”的首选工具,例如购物车、仪表板、聊天小部件、日历和完整的页面。这些是复杂、有状态的组件,高质量的测试让团队能够自信地进行构建和迭代。

这就是为什么我们要加强 Storybook 中的测试。我很高兴地宣布 Storybook 8.2,这是我们迈向无妥协组件测试之旅的下一站。

  • 🪝 新的测试钩子,与其他流行的测试工具保持一致
  • 🧳 可移植的故事,用于在其他测试和文档工具中重用
  • 📦 包整合,以减少依赖冲突
  • 🛼 简化的入门流程,帮助新用户快速上手
  • ✨ 全新改进的网站,提供更好的框架文档
  • 💯 数百项更多改进

新的测试钩子

现代测试工具,如 Jest/Vitest/Playwright/Cypress,都使用 *Jasmine* 测试构造。每种工具的语法略有不同,但它们都归结为以下测试钩子:before/afterAllbefore/afterEachdescribetest

Storybook 有自己的故事语法:组件故事格式 (CSF)。CSF 是捕获组件各种状态示例的最佳方式。在 Storybook 6.4 中,我们添加了 play 函数,使其能够编写交互和断言脚本。

// ToolbarMenu.stories.js
import { fn, expect } from '@storybook/test';
import { ToolbarMenu } from './ToolbarMenu';

export default { component: ToolbarMenu };
export const Disabled = {
  args: { disabled: true, onSelected: fn() },
  play: async ({ canvas, args }) => {
    await userEvent.click(canvas.getByRole('button'));
    expect(args.onSelected).not.toHaveBeenCalled();
  },
};

使用 play 函数,已经在 Storybook 中编写了许多类 Jasmine 风格的测试。但并非所有场景都适用。如果您来自其他测试工具,那么将测试转换为 CSF 需要一个学习过程。

现在不用了。在 Storybook 8.2 中,我们引入了 before 钩子(可以返回清理函数,用作 after 钩子)以及 play 的可选 mount 参数(用于 React、Vue 3 和 Svelte)。现在,您可以使用与 Jasmine 风格工具相同的控制流来编写组件测试,能够在一个 play 函数中“排列、执行和断言”所有内容。

// ToolbarMenu.stories.jsx
import { fn, expect } from '@storybook/test';
import { ToolbarMenu } from './ToolbarMenu';

export default {
  component: ToolbarMenu,
};

export const Disabled = {
  args: { disabled: true, onSelected: fn() },
  play: async ({ mount, args }) => {
    // Arrange
    const items = await loadItems(10);
    const canvas = await mount(<ToolbarMenu items={items} />);
    
    // Act
    await userEvent.click(canvas.getByRole('button'));
    
    // Assert
    expect(canvas.getAllByRole('button').length).toBe(items.length);
    expect(args.onSelected).not.toHaveBeenCalled();
  },
};

这是一个非破坏性更改,因此您所有现有的故事将继续按原样工作。并且编写故事的推荐方法(使用*隐式*挂载)也没有改变。但是,当您需要额外功能时,新的测试钩子将为您提供支持。

“第一次使用 @storybookjs play 测试。天哪! 🥰 从未写过这么快的测试!!”
@brechtilliet

请查看文档,并请继续关注在接下来的几周内发布完整的特性公告和更多钩子示例!

可移植的故事

Storybook 是迭代构建、记录和测试组件的最佳工具。但是,JS 生态系统中还有许多其他优秀的工具,我们希望您能根据需要将您的故事用于这些工具。

在 8.1 中,我们为Playwright 组件测试发布了有限形式的“可移植故事”。现在在 8.2 中,我很高兴地为 React 和 Vue 3 推出可移植故事,并提供实验性的 Svelte 支持。这使您能够以符合人体工程学的方式将故事转换为框架的“原生”组件,并附带一些额外代码来运行故事可能拥有的任何测试钩子。

// Button.test.js
import { test, expect } from 'vitest';
import { screen } from '@testing-library/react';
import { composeStories } from '@storybook/react';
 
// Import all stories and the component annotations from the stories file
import * as stories from './Button.stories';
 
// Every component that is returned maps 1:1 with the stories,
// but they already contain all annotations from story, meta, and project levels
const { Primary, Secondary } = composeStories(stories);
 
test('renders primary button with default args', async () => {
  /**
   * Runs through story lifecycle:
   * 1. loaders
   * 2. beforeEach
   * 3. render w/ decorators (and other annotations)
   * 4. play fn (including mount, when used)
   * 5. cleanup (from beforeEach, hooks)
   */
  await Primary.run();
});

除了 API,我们还为如何在 VitestJest 中重用您的故事准备了额外的文档。请查看文档,我们稍后会发布完整的特性公告。

整合依赖管理

在对 20,000 多名开发者的调查中,《State of JS》调查是 JS 生态系统的脉搏。在 2022 年有所下降后,我们改进 Storybook 的辛勤工作在 2023 年取得了辉煌的成绩。这次最大的抱怨是依赖管理不善:臃肿、安装占用空间大和版本冲突。

在 8.2 中,我们开始解决这个问题。我们将 18 个包合并到一个核心包 storybook 中,以及一组用于构建器/渲染器/插件的卫星包。这是一个非破坏性更改,遵循 Vite 的包结构。此外,我们还捆绑了许多 Storybook 的依赖项,以消除版本冲突。

我们还与James GarbuttEcosystem Performance (e18e) 项目的负责人)合作,将我们的实用库升级到更小/更快/更现代的版本(再见 doctrine!👋)。

这项工作仍处于早期阶段,但到目前为止,我们已设法将安装大小/时间减少了约 20%。新的整合结构为我们未来的优化奠定了基础,因此请留意 8.3 及更高版本中更大的下降。

简化的入门流程

我们关注的另一个领域是入门体验。每周都有成千上万的开发人员尝试 Storybook,但从安装到成为一名成功的用户,这条道路充满陷阱。在 Storybook 8.2 中,我们刷新了入门体验,并将其从 React 扩展到 Vue 3 和 Angular,以帮助用户找到正确的方向。

0:00
/0:24

请继续关注,我们将在 8.x 版本中扩展此体验,使 Storybook 在您的项目中更容易配置。

新版改进的文档网站

Storybook 有一个全新的文档网站!它包括:

  • ✨ 新主页,带有新的、完全响应式的动画,更好地说明了 Storybook 的众多功能。
  • 📚 新文档主页,为每个框架提供专门的登陆页面(Next.jsSvelteKit 等)。
  • 🌙 文档的浅色/深色模式,以匹配您的系统设置。
  • 🧱 基础工作,以便更快地进行进一步改进和迭代。
Screenshot of new docs site, half in light mode, half in dark

数百项改进

除了上述功能外,每一次 Storybook 发布都包含数千项各级别的改进和 bug 修复。一些亮点:

  • ✅ Webpack5/Vite:修复sourcemaps - #27171,感谢 @valentinpalkovic
  • ✅ Angular:允许配置源预览格式 - #28305,感谢 @64BitAsura
  • ✅ CLI:为 init 添加 --no-dev 选项 - #26918,感谢 @fastfrwrd
  • ✅ CLI:在新项目中包含 @storybook/addon-svelte-csf#27070,感谢 @benmccann
  • ✅ Core:修复由 watchStorySpecifiers 引起的启动挂起 - #27016,感谢 @heyimalex
  • ✅ Vue3:启用新的 hydration 不匹配编译时标志 - #27192,感谢 @Cherry

立即尝试!

Storybook 8.2 已于今日发布。在新建项目中尝试一下。

npx storybook@latest init

或升级现有项目

npx storybook@latest upgrade

如果你从 7.x 升级,我们有一个指南可以帮助你。我们还有一个从旧版本迁移的指南

下一步

我们正在为 8.3 准备大量内容。

  1. 与 Vitest 集成,实现闪电般快速的组件测试。
  2. 为我们的 Next.js 框架添加 Vite 支持,以实现 Vitest 兼容性和更好的 DX。
  3. 故事标签,提供交互式侧边栏过滤的 UI。
  4. 进一步减小安装大小(尝试 8.3-alpha,它比以前小 40%!)。
  5. Story globals,一种更干净的方式来编写针对特定视口、主题和区域设置的故事。

要了解我们正在处理和考虑的内容的最新信息,请查看 Storybook 的新路线图

鸣谢

非常感谢 39 位贡献者为 Storybook 8.2 贡献了 PR!

@43081j @64bitasura @alexatvista @alirezaebrahimkhani @benmccann @cdedreuille @cherry @cosielq @dario-baumberger @deiga @dexofthewild @edoardocavazza @ghengeveld @girgetto @jonniebigodes @jreinhold @kasperpeulen @kevinfoerster @kongallis @kylegach @mnigh @ndelangen @pl12133 @rocktakey @seanparmelee @shilman @simenb @sinnedh @sni-j @superhermione @tmeasday @tobiasdiez @tony19 @valentinpalkovic @vanessayuenn @yannbf @yk-kd @yuheiy

加入 Storybook 邮件列表

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

7,468开发者及更多

我们正在招聘!

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

查看职位

热门帖子

Storybook 中的组件测试

UI 测试的未来
loading
Michael Shilman

Storybook 8.3

超快的组件测试
loading
Michael Shilman

State of JS 2023:从急转直下的局面中奋起直追

Storybook 如何利用调查来指导开发
loading
Michael Shilman
加入社区
7,468开发者及更多
原因为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与进来博客
展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI