⚠️ 重要注意事項:這個套件已過時,同時 Storybook 也停止支援 Vue2。如果您沒有升級到 Vue 3 的計畫,您可以繼續使用 Storybook 7。composeStories API 已在 Storybook 8 中升級為一流的 Storybook 功能,現在您可以將其作為 @storybook/vue3 的一部分使用。更多資訊:https://github.com/storybookjs/testing-vue3/issues/16
⚠️ 如果您正在使用 Storybook 與 Vue 3,請查看 @storybook/testing-vue3!
安裝
此函式庫應作為專案的 devDependencies
安裝
透過 npm
npm install --save-dev @storybook/testing-vue
或透過 yarn
yarn add --dev @storybook/testing-vue
設定
Jest 設定
如果您使用 Jest 執行測試,您應該在 jest.config.js
中對應 .vue
檔案,以使用包含其模板編譯器的 Vue 版本
moduleNameMapper: {
'^vue$': 'vue/dist/vue.common.dev.js'
},
Storybook CSF
此函式庫要求您使用 Storybook 的元件 Story 格式 (CSF) 和提升的 CSF 註解,這是 Storybook 6 以來建議的撰寫 Story 的方式。
基本上,如果您的 Story 看起來類似這樣,那就沒問題了!
// CSF: default export (meta) + named exports (stories)
export default {
title: 'Example/Button',
component: Button,
};
export const Primary = () => ({
template: '<my-button primary />',
});
全域設定
這是一個可選步驟。如果您沒有全域裝飾器,則無需執行此操作。但是,如果您有,這是套用全域裝飾器的必要步驟。
如果您有全域裝飾器/參數/等等,並希望在測試時將其應用於您的 Story,您首先需要進行設定。您可以在 jest 設定檔案中新增或建立來完成此操作
// setupFile.js <-- this will run before the tests in jest.
import { setGlobalConfig } from '@storybook/testing-vue';
import * as globalStorybookConfig from './.storybook/preview'; // path of your preview.js file
setGlobalConfig(globalStorybookConfig);
為了讓設定檔案被選取,您需要在測試命令中將其作為選項傳遞給 jest
// package.json
{
"test": "jest --setupFiles ./setupFile.js"
}
用法
composeStories
composeStories
將處理您指定的元件中的所有 Story,組合它們中的 args/裝飾器,並返回一個包含組合 Story 的物件。
如果您使用組合的 Story(例如 PrimaryButton),則該元件將使用 Story 中傳遞的 args 呈現。但是,您可以自由地在元件之上傳遞任何 props,這些 props 將覆蓋 Story 的 args 中傳遞的預設值。
import { render, screen } from '@testing-library/vue';
import { composeStories } from '@storybook/testing-vue';
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-vue';
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();
});