允許您在單元測試中重複使用 Story 的測試工具

在 Github 上檢視

⚠️ 重要注意事項

您好!我想感謝您使用 @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 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 的方式。

基本上,如果您的 Story 看起來類似這樣,那就沒問題了!

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

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

全域設定

這是一個可選的步驟。如果您沒有全域裝飾器,則無需執行此操作。但是,如果您有,這是應用全域裝飾器的必要步驟。

如果您有全域裝飾器/參數等,並希望在測試時將它們應用於您的 Story,您首先需要進行此設定。您可以透過新增或建立 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 將處理您指定的元件中的所有 Story,將所有 Story 中的參數/裝飾器組合在一起,並返回一個包含組合 Story 的物件。

如果您使用組合的 Story(例如,PrimaryButton),則元件將使用 Story 中傳遞的參數來呈現。但是,您可以隨意在元件之上傳遞任何 props,這些 props 將覆蓋 Story 參數中傳遞的預設值。

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
標籤