Next.jsプロジェクトでStorybook v9.1.3を使用してインタラクションテストを実装する際の設定方法とCI/CD統合。MSWではなくファクトリーパターンを採用した実装。
MSWを使用しないことにした背景
各テスト環境の最適化
- Storybook: msw-storybook-addonよりもファクトリーパターンの方がStory単位の独立性を保ちやすい
- Playwright: ネイティブのRoute APIの方が高速で確実
- 開発環境: APIと並行開発のため、実際のAPIを使用
技術的な制約
- SSR環境でのクライアント/サーバー間のモックデータ共有が困難
- 環境ごとに異なるインスタンスになるため、状態の一貫性維持が複雑
Storybook v9.1.3の設定
preview.tsxの設定ポイント
// .storybook/preview.tsx(注意:.tsではなく.tsxが必要)
import { mockDataStore } from '../src/mocks/data'
decorators: [
(Story) => {
mockDataStore.reset() // 各Story実行前にデータリセット
return React.createElement(Story) // JSX構文は使用不可
},
],
インタラクションテストのインポート
// v9では@storybook/testパッケージは存在しない
import { expect, within, userEvent, waitFor } from 'storybook/test'
テスト実行環境の構築
必要なパッケージ
# テストランナーとPlaywright
npm install --save-dev @storybook/test-runner playwright
# CI環境用ユーティリティ
npm install --save-dev concurrently wait-on http-server
ローカル実行時の初期設定
Playwrightブラウザのインストールが必要:
npx playwright install chromium
CI/CD統合(GitHub Actions)
ビルド済みStorybookでのテスト実行
- name: Run Storybook tests
run: |
npx concurrently -k -s first -n "SB,TEST" \
"npx http-server storybook-static --port 6006 --silent" \
"npx wait-on tcp:6006 && npm run test-storybook:ci"
npmスクリプト設定
{
"test-storybook": "test-storybook",
"test-storybook:ci": "test-storybook --maxWorkers=2"
}
テストデータ管理
ファクトリーパターンでのモックデータ
// 各テストで独立したデータを使用
import { createUser, createMemo } from '@/mocks/data'
const testUser = createUser({ name: 'テストユーザー' })
const testMemo = createMemo({ user: testUser })
Storybook内での使用
play: async ({ canvasElement }) => {
// mockDataStoreは自動的にリセット済み(preview.tsxで設定)
const user = mockDataStore.getCurrentUser()
const canvas = within(canvasElement)
// インタラクションテストの実装
}