Tetsu23 Tetsu23

Storybookにおけるインタラクションテスト関連

Jun 15

Storybookインタラクションテストについて#

問題提起#

Storybookはバージョン9のメジャーリリースと同時に、@storybook/addon-vitestの正式版をリリースしました。

私がメンテナンスしているプロジェクトでは、すでに@testing-library/reactを使用した単体テストが多数存在しますが、Storybookのインタラクションテストはまだ導入されていません。

では、このインタラクションテストと、筆者がよく知る単体テストやE2E(エンドツーエンド)テストとの違いは何でしょうか?

どのようなテストをインタラクションテストで書くべきで、どのようなテストを単体テストで書くべきなのでしょうか?(E2Eテストの対象は明確で、完全な環境でのユーザー操作をテストするものです)

事前調査#

関連ドキュメント:Storybook - What’s the difference between interaction tests and using Vitest + Testing Library alone?

Storybookの公式ドキュメントでは、最大の違いとして次の一つだけが挙げられています。

インタラクションテストはブラウザ上でテストの実行を確認でき、デバッグが容易である。

JSDOMのエラー修正を何度も経験したことがある方なら、コンソールに出力された大量のDOMを前に途方に暮れた経験があるでしょう。筆者はまだStorybookでのデバッグを実際に試したことはありませんが、この点においてStorybookのインタラクションテストがJSDOMに対して大きな利点を持つことは間違いありません。

では、他に違いはあるのでしょうか?

Geminiによる回答#

各種テストの比較#

特徴コンポーネントテスト単体テストE2Eテスト
スコープ単一コンポーネント単一関数/モジュールアプリケーション全体のフロー
焦点ビジュアル、インタラクション、統合ビジネスロジック、アルゴリズム完全なユーザージャーニー
環境ブラウザ(分離)Node.js実際のブラウザ(完全なアプリケーション)
速度やや速い最速最も遅い
主なツールStorybook, Playwright, Testing LibraryJest, VitestPlaywright, Cypress

Storybookテストとtesting-libraryの比較#

特徴testing-library (Jest/Vitestと併用)Storybookテスト (@storybook/addon-vitest)
実行環境JSDOM: Node.js内でJavaScriptによってシミュレートされたブラウザ環境。(実際のブラウザでも使用可能)実際のブラウザ: PlaywrightやCypressを使用して、実際のブラウザ(Chrome、Firefoxなど)を操作します。
「ビジュアル」テストの意味計算後のスタイル(getComputedStyle)やDOMの属性をチェックします。例:expect(element).toHaveStyle('background-color: red')実際のピクセルレベルでのレンダリング。スタイルのチェックだけでなく、ビジュアルリグレッションテストも可能で、スクリーンショットの比較を通じてピクセルレベルの意図しない変更を検出します。
デバッグ体験ターミナルの出力、console.log、またはNode.jsのデバッガに基づきます。コンポーネントが実際にどのように見えるかは確認できません。インタラクティブで視覚的なデバッグ。ブラウザでテストの各ステップをリアルタイムで観察し、一時停止、ステップ実行、そのステップでのDOMの状態を確認できます。これはStorybookの大きな利点です。
焦点「ユーザーが使えれば、それは機能している」。主にARIAロール、テキストコンテンツ、状態に焦点を当て、すべてのユーザー(支援技術を使用するユーザーを含む)にとってコンポーネントが機能的であることを保証します。CSSクラス名や色の値など、具体的な実装の詳細をテストすることは意図的に避けます。「機能するだけでなく、見た目も正しくなければならない」。同様にインタラクションに焦点を当てますが、視覚的な忠実度を同等に重要な位置に引き上げます。Storybookのストーリー自体が視覚的な基準となります。
ワークフロー1. テストファイル内でコンポーネントをrenderする。<br>2. ユーザーのインタラクション(userEvent)をシミュレートする。<br>3. DOM構造やモック関数に対してアサーションを行う。1. すでに視覚化されたStoryが存在する。<br>2. play関数を記述してインタラクションを定義する。<br>3. インタラクションがStorybookのキャンバス上で自動的に実行される。<br>4. アサーションがブラウザで実行される。
限界実際の視覚的なレイアウトをテストすることはできません。レンダリングエンジンがないため、JSDOMは要素がCSSによって隠されているか、画面外に移動しているか、font-familyが正常に読み込まれたかなどを認識できません。テスト速度が比較的遅い(ブラウザを起動する必要があるため)。

個人的な感想#

testing-library + JSDOMの長所#

Storybookインタラクションテストの長所#

testing-library + JSDOMでのテストに適しているケース#

長所を考慮すると、ユーザー操作後のデータに関心があるテストはtesting-libraryで書くのに適していると個人的に考えます。つまり、testing-libraryはユーザー操作を提供するツールとして利用し、expectによるアサーションはあまり行わないケースです。

Storybookインタラクションテストに適しているケース#

上記の長所に基づき、ほとんどのテストはStorybookインタラクションテストで書くのに適していると、私は大まかに考えています。

特に、ユーザーのインタラクション関連で、操作ステップのUI要素や見た目が重要なテストです。

Storybookインタラクションテストに適していないケース#

結論#

インタラクションテストの作成をまだ試していない段階ですが、筆者の大まかな考えとしては、インタラクションテストは**WYSIWYG(見たままが得られる)**の特性を持つため、可能な限りtesting-library + JSDOMをインタラクションテストで置き換えることは合理的だと考えます。その副作用として生じる実行時間の問題については、まだ実際にテストしていないため、その深刻度は未知数です。実際に試してみてから、また更新したいと思います。

関連リンク: Storybookのスナップショットテストを Chromatic に置き換えて、コンポーネントのテストをより快適にする - Cybozu Inside Out | サイボウズ株式会社のエンジニアブログ


> cd ..