⚠️ 重要提示
您好!我想感谢您使用 @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();
});