Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

Vol. 06 Storybook v9のVitest統合機能を活用した開発者体験の改善

この記事は、Bill One開発Unit ブログリレー2025、およびSansan Advent Calendar 2025 、6日目の記事です。

技術本部 Bill One Engineering Unit Core Business UMグループの川原です。

VitestとStorybookの統合機能を導入してみたので、記事を書きます。

【導入】なぜStorybookのテストは実行されないのか?

フロントエンド開発において、Storybookは欠かせないツールとなりました。特にplay関数を使ったインタラクションテストは強力です。フォームの入力、ボタンのクリック、バリデーションエラーの表示など、ユーザーが実際に操作するフローをコードで記述し、自動化できる機能です。

Bill OneでもStorybookのplay関数を活用したインタラクションテストを導入していました。しかし、play関数を実行するにはブラウザでStorybookを立ち上げ、コンポーネントを1つずつ手動で開き、サイドパネルの実行結果を確認する必要がありました。

「複数のplay関数を一括で実行できない」 「テスト結果を確認するために毎回ブラウザを行き来しなければならない」

こうした制約から開発者体験(DX)は決して良いとは言えず、結果としてテスト実行の頻度が下がってしまうという課題を抱えていました。

そこで、Bill Oneで行われている「Enhance Week」を活用し、この課題を解決することにしました。Enhance Weekとは開発者が通常の機能開発から離れ、技術的な負債の解消や開発環境の改善に集中できる1週間のことです。詳しくは次の記事をご覧ください。

Bill One開発文化のおかげでOSSにコントリビュートできた話

【解決策】Vitest統合でテスト実行のハードルをゼロに

そんな中、Storybook v9から Vitestの統合機能が発表されたのを知って、これを解決できないかと導入を試してみました。

これまではStorybook上(ブラウザ)でしか動かせなかったplay関数などのストーリー定義を、Vitestという高速なテストランナーを使って実行できるようになりました。

これにより、開発体験が次のように向上しました。

  • VS Codeから直接実行できる。エディタの拡張機能(Vitest Explorerなど)を使えば、コードを書いているその場でテストを実行できる
  • 既存のテストフローを壊さない。ユニットテストなど既存のVitest環境に段階的に統合できるため、無理なく導入できる
  • 一括確認を実現できる。コンポーネント単位などでテスト実行できるため、複数のストーリーがある場合でも1つ1つ手動で開いて確認する手間がなくなった

特に最も開発者体験の向上を感じたのは、VS Codeから直接実行できるようになり、Storybookを書いた後にリファクタリングした時の動作確認がかなり楽になったことです。

【実装】導入で押さえておくポイント

ここが一番のポイントですが、Vitestの「Workspace(プロジェクト)」機能を使って、既存のユニットテストとStorybookテストを分離することをお勧めします。 vitest.config.ts で通常のテスト用と storybook 用の設定を分けることで、それぞれ独立して実行でき、設定の競合も防げます。

例えばStorybook側ではPlaywright(ブラウザ実行)が必要ですが、既存のユニットテストは jsdom のみで十分です。 これを1つの設定にまとめると、次のような問題が起きやすくなります。

  • どちらの環境で動かしているかわかりにくくなる
  • CI で誤ってStorybookテストが走り、遅くなる

また、このようにプロジェクトを分けておくことで、例えば「CI環境では通常のユニットテストだけを実行し、Storybookテストは実行しない」といった柔軟な制御が可能になります。まずはローカル環境だけで小さく始め、安定してからCIに組み込むといった段階的な導入がしやすくなるため、最初から分離しておくことを強くおすすめします。

以下は実際の vitest.config.ts を簡略化した設定例です。projects 配列を使って、通常のユニットテスト(main)とStorybookテスト(storybook)の設定を明確に分けています。

import { storybookTest } from "@storybook/addon-vitest/vitest-plugin"
import { defineConfig, mergeConfig } from "vitest/config"
import viteConfig from "./vite.config"

export default mergeConfig(
  viteConfig,
  defineConfig({
    test: {
      globals: true,
      // ...カバレッジ等の共通設定

      projects: [
        {
          // 1. 通常のユニットテスト(jsdom環境など)
          extends: true,
          test: {
            name: "main",
            include: ["src/**/*.{test,spec}.{ts,tsx}"],
            environment: "jsdom",
            setupFiles: ["./src/setupTests.ts"],
          },
        },
        {
          // 2. Storybookのテスト(ブラウザ環境/Playwright)
          extends: true,
          plugins: [
            // Storybookプラグインを適用
            storybookTest({
              configDir: ".storybook",
            }),
          ],
          test: {
            name: "storybook",
            browser: {
              enabled: true,
              headless: true,
              provider: "playwright",
              instances: [{ browser: "chromium" }],
            },
            setupFiles: [".storybook/vitest.setup.ts"],
          },
        },
      ],
    },
  }),
)

【所感】実際に導入してみて

実際にプロジェクトへ導入してみた結果、最初に挙げたメリットは十分に享受できました。

  • 一括実行により、リファクタリング時の動作確認が劇的に楽になった
  • VS Code上でStorybookのテストを実行したいときにエディタだけで完結するようになった

一方で、CI環境への導入については見送る判断をしました。

なぜCIへの導入を見送ったのか

最大の理由は実行速度です。

VitestとStorybookの統合ではヘッドレスブラウザを使用することで高速な実行を実現していますが、それでも実際にコンポーネントをレンダリングするコストは発生します。 ローカル環境で検証したところ、純粋なユニットテスト(jsdom環境など)と比較して実行時間がかなり長くなってしまうことが分かりました。

CIの実行時間が長引くことは開発サイクル全体の遅延につながるため、現時点では「ローカル開発時のDX向上」にスコープを絞り、CIでの自動実行までは行わない方針としました。

新しい技術を無条件で採用するのではなく、プロダクト全体への影響を踏まえたうえで最適な構成を選ぶ。 Bill One開発チームのこうした文化とも調和した判断だったと感じています。

【まとめ】テストを"身近"にすることの価値

今回の導入で一番良かったことは、 「Storybookをわざわざ開かなくてもテストできるようになった」 という点に尽きます。

これまで「ブラウザを開くのが面倒」という理由で後回しになりがちだった動作確認が、VS Code上でサクッと終わらせられるようになりました。地味な変化に見えるかもしれませんが、日々の開発における「ちょっとしたストレス」を解消することは、気持ちよく開発を続ける上でとても大切だと改めて感じました。

Storybookのテスト実行が面倒だと感じている方は、ぜひ一度試してみてください。開発体験がぐっと良くなるはずです。

Bill Oneのチームでは、こんなふうに日々の開発体験を少しずつ良くする取り組みに継続的にチャレンジしています。 UIテストやStorybook、Vitest周りの改善に興味がある方とは、ぜひ一度お話してみたいです。

Sansan技術本部ではカジュアル面談を実施しています

技術本部では中途・新卒採用向けにカジュアル面談を実施しています。Sansan技術本部での働き方、仕事の魅力について、現役エンジニアの視点からお話しします。「実際に働く人の話を直接聞きたい」「どんな人が働いているのかを事前に知っておきたい」とお考えの方は、ぜひエントリーをご検討ください。

© Sansan, Inc.