⚠️ 重要提示
您好!感谢您使用 @storybook/testing-vue3
!
@storybook/testing-vue3
已在 Storybook 8 中升级为一流的 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 多仓库中报告。
感谢您一路相伴!
⚠️ 此库适用于 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 的组件故事格式 (CSF) 和提升的 CSF 注释,这是自 Storybook 7 以来编写故事的推荐方法。
基本上,如果您的故事看起来类似于此,那么您就可以开始了!
// CSF: default export (meta) + named exports (stories)
export default {
title: 'Example/Button',
component: Button,
};
export const Primary = {
template: '<Button v-bind="args" />',
};
全局配置
这是一个可选步骤。如果您没有全局装饰器,则无需执行此操作。但是,如果您有,则这是应用全局装饰器的必要步骤。
如果您有全局装饰器/参数/等,并且希望在测试它们时将它们应用于您的故事,则首先需要进行设置。您可以通过添加或创建 jest 设置文件来完成此操作
// 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);
要让设置文件生效,您需要在测试命令中将其作为选项传递给 jest
// package.json
{
"test": "jest --setupFiles ./setupFile.js"
}
用法
composeStories
composeStories
将处理您指定的组件中的所有故事,在所有故事中组合 args/装饰器,并返回一个包含已组合故事的对象。
如果您使用已组合的故事(例如 PrimaryButton),则该组件将使用故事中传递的 args 进行渲染。但是,您可以随意在组件之上传递任何道具,这些道具将覆盖故事 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
如果您希望将它应用于所有故事中的单个故事,而不是所有故事,可以使用 composeStory
。您需要传递元数据(默认导出)。
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();
});