UIコンポーネントのカタログツールStorybookを使い、コンポーネントをセットアップする方法もある。StorybookはStories
というファイルに「どのようなコンポーネントをStorybookに描画するか」を記載する。props
に応じて描画内容を出し分けることもできる1。
このStories
は次のように記載する。
import type { Meta, StoryObj } from "@storybook/react"; import BlogList from "./BlogList"; // Story自体の設定 const meta: Meta<typeof BlogList> = { title: "Table/BlogList", // Storyの区分け / Story名 component: BlogList, // 使うコンポーネント名 parameters: { layout: "centered", // 真ん中に配置 }, tags: ["autodocs"], // ドキュメンテーションあり }; export default meta; type Story = StoryObj<typeof BlogList>; // DefaultがStory名 export const Default: Story = { args: { // 与えたいprops userList: [ { id: 1, name: "user1", }, ] } }
ポイントはargs
の部分である2。このargs
はStory
(UIコンポーネントを状態に応じてレンダリング仕分けたもの)ごとに「どのようなprops
」を設定するか?記載する。
Storyで場面に応じたprops
を設定しているのだから、Storyを直接インポートしてテストを書けば二度手間にならずに済む。
また、開発初期段階でUIコンポーネントから先に準備したいときにも役立つ。テストが失敗した場合、Storybookを使えばUIコンポーネントの見た目や動作を実際確認できるためである。これはページを作る前にUIコンポーネントだけテストできるので、「残りはページのみ」という気持ちで取り組みやすくなる。
Testing Library側のインポート方法
StorybookはバージョンアップでダイナミックにAPIが変わる。そのため最新の情報は常にStorybookの公式ドキュメントを参照いただきたい。ここではStorybook 8.xのインポート方法を載せる。
StorybookのAPIcomposeStories()
3を使うとStorybookからStoryをインポートできる。
// Reactのインポート import React from "react"; // render関数のインポート import { render } from "@testing-library/react"; // StoryをレンダリングするcomposeStories APIのインポート import { composeStories } from '@storybook/react'; // StorybookのStoriesファイルからStoryを全部インポート import * as Stories from './BlogList.stories'; // DefaultというStoryをデストラクチャリングで取り出して使えるようにする const { Default } = composeStories(Stories); it("Storyをインポートしてテストを動かす例", () => { // itブロック外でインポートしたStoryでレンダリングする const content = render(<Default />); // テキストが存在するか確認 expect(content.getByText("記事ID")).toBeInTheDocument(); });
まず初めに、テスト対象のStoriesファイルからStoryをインポートする。インポート方法はいくつかあるが、本格的にテストを書く場合は全てインポートする方法が使いやすい。パターン分けしている分は何かしらテストを書いた方が良い場合がほとんどだからである。
インポートした後、composeStories
APIを使い、Storyを取り出す。すると、Testing Libraryがテストランナー上でコンポーネントをレンダリングする際Storyを指定できるようになる。propsはStoryのargs
で設定しているため、その内容を使ってテストが動く。
Storyを状態に応じて分割しておくと、テストとStory名でどのような場面のどんな内容を検証したいのかを伝えやすくなる。デバッグもしやすい。
メリットが多いので基本的にはStoryを使って状態を表現しておきたい。ただ、StorybookのバージョンアップでAPIの破壊的な変更が入ることも多い。npx storybook migrate
である程度機械的に作業すること・GitHub Copilotなども駆使して移植作業は半自動化してやると少しは楽になる。スケジュールが佳境な時にはバージョンアップしない方が良い。
また、過度に依存するとバージョンアップで疲弊するため、Storybook上で動作するテストは書かないようにしている。