加入直播会话:周四,美国东部时间上午 11 点,Storybook 9 发布及 AMA

测试工具,允许您在单元测试中复用您的 Stories

在 Github 上查看

⚠️ 重要提示

您好!我想感谢您使用 @storybook/testing-vue3

在 Storybook 8 中,@storybook/testing-vue3 已被升级为 Storybook 的一级功能。这意味着您不再需要此包,并且此包将不再维护。相反,您可以从 @storybook/vue3 包中导入相同的工具。

请按以下步骤操作

  • 如果您尚未升级,请升级到 Storybook 8
  • 卸载 @storybook/testing-vue3
  • 将导入语句从 @storybook/testing-vue3 更新为 @storybook/vue3
// Component.test.js
- import { composeStories } from '@storybook/testing-vue3';
+ import { composeStories } from '@storybook/vue3';

// setup-files.js
- import { setProjectAnnotations } from '@storybook/testing-vue3';
+ import { setProjectAnnotations } from '@storybook/vue3';

请注意,即使迁移后仍然遇到问题,也请在Storybook monorepo 中报告。

非常感谢您一路相伴!


⚠️ 此库适用于 Vue 3 项目。如果您正在将 Storybook 用于 Vue 2,请改用 @storybook/testing-vue

安装

此库应作为您项目的 devDependencies 之一安装

通过 npm

npm install --save-dev @storybook/testing-vue3

或通过 yarn

yarn add --dev @storybook/testing-vue3

设置

Storybook CSF

此库要求您使用 Storybook 的组件 Story 格式 (CSF)提升的 CSF 注解,这是 Storybook 7 以来推荐的编写 Story 的方式。

基本上,如果您的 Stories 看起来与此类似,您就可以开始了!

// CSF: default export (meta) + named exports (stories)
export default {
  title: 'Example/Button',
  component: Button,
};

export const Primary = {
  template: '<Button v-bind="args" />',
};

全局配置

这是可选步骤。如果您没有全局 decorators,则无需执行此操作。但是,如果您有,这是应用全局 decorators 的必要步骤。

如果您有全局 decorators/parameters 等,并希望在测试 Story 时应用它们,首先需要进行设置。您可以通过添加或创建 jest setup 文件来完成此操作

// setupFile.js <-- this will run before the tests in jest.
import { setProjectAnnotations } from '@storybook/testing-vue3';
import * as globalStorybookConfig from './.storybook/preview'; // path of your preview.js file

setProjectAnnotations(globalStorybookConfig);

要使 setup 文件被识别,您需要在测试命令中将其作为选项传递给 jest

// package.json
{
  "test": "jest --setupFiles ./setupFile.js"
}

使用方法

composeStories

composeStories 将处理您指定组件中的所有 Story,将 args/decorators 组合到所有 Story 中,并返回一个包含组合后 Stories 的对象。

如果您使用组合后的 Story(例如 PrimaryButton),组件将使用 Story 中传递的 args 进行渲染。但是,您可以自由地在组件之上传递任何 props,这些 props 将覆盖 Story 的 args 中传递的默认值。

import { render, screen } from '@testing-library/vue';
import { composeStories } from '@storybook/testing-vue3';
import * as stories from './Button.stories'; // import all stories from the stories file

// Every component that is returned maps 1:1 with the stories, but they already contain all decorators from story level, meta level and global level.
const { Primary, Secondary } = composeStories(stories);

test('renders primary button with default args', () => {
  render(Primary());
  const buttonElement = screen.getByText(
    /Text coming from args in stories file!/i
  );
  expect(buttonElement).not.toBeNull();
});

test('renders primary button with overriden props', () => {
  render(Secondary({ label: 'Hello world' })); // you can override props and they will get merged with values from the Story's args
  const buttonElement = screen.getByText(/Hello world/i);
  expect(buttonElement).not.toBeNull();
});

composeStory

如果您希望将其应用于单个 Story 而不是所有 Story,则可以使用 composeStory。您还需要传递 meta(默认导出)。

import { render, screen } from '@testing-library/vue';
import { composeStory } from '@storybook/testing-vue3';
import Meta, { Primary as PrimaryStory } from './Button.stories';

// Returns a component that already contain all decorators from story level, meta level and global level.
const Primary = composeStory(PrimaryStory, Meta);

test('onclick handler is called', async () => {
  const onClickSpy = jest.fn();
  render(Primary({ onClick: onClickSpy }));
  const buttonElement = screen.getByRole('button');
  buttonElement.click();
  expect(onClickSpy).toHaveBeenCalled();
});

许可

MIT

由...贡献
  • thafryer
    thafryer
  • shaunlloyd
    shaunlloyd
  • kylegach
    kylegach
  • tooppaaa
    tooppaaa
  • ndelangen
    ndelangen
  • shilman
    shilman
标签