react-testing について
Testing Library、Vitest、MSW を使った React コンポーネントテストの方法を示すスキルです。実装の詳細ではなくユーザー操作とアクセシビリティを重視し、React 19 の機能と再利用可能な 9 つのテンプレートも扱います。
主な機能
- 01アクセシブルなクエリを優先
- 02userEvent による操作の再現
- 03findBy と waitFor による非同期検証
- 04MSW による API モック
- 05React 19・フック・境界のテスト
- 069 種類のテストテンプレート
活用シーン
- 01コンポーネントの操作動作の検証
- 02非同期の読み込み・エラー・成功状態のテスト
- 03フォームとカスタムフックのテスト
- 04アクセシビリティ監査と API 統合テスト
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ fusengine/ claude-plugins --skill react-testingインストール後、Claude Code で/react-testingを入力して読み込まれたか確認します。
詳細
Testing Library と Vitest を使用して React 19 コンポーネントをテストします。アクセシビリティを優先したユーザー中心のクエリ(まず `getByRole`、最終手段として `getByTestId`)、現実的な操作には `userEvent`(`fireEvent` は使用しません)、非同期アサーションには `findBy`/`waitFor`(`setTimeout` は使用しません)、API のモックには MSW(`fetch` を直接モックしません)を使用します。
React 19 の機能(useActionState、use())、カスタムフック、Suspense 境界、エラー境界、axe-core によるアクセシビリティ監査のテストも扱います。Vitest の設定と、すぐにコピーして使える 9 種類のテストテンプレートを提供します。これは React スキル(react-19、react-state、react-forms)に重ねて使うテスト手法のスキルです。各 API 自体ではなく、それらを使用するコンポーネントのテスト方法を扱います。
React Testing Library
ユーザーの操作に沿って React コンポーネントをテストします。
エージェントのワークフロー(必須)
実装に着手する前に、各 name を指定した Agent 呼び出しを 1 回ずつ行い、3 つのエージェントを並行して起動してください。
- fuse-ai-pilot:explore-codebase - 既存のテストパターンを分析します
- fuse-ai-pilot:research-expert - Context7/Exa を使って Testing Library の最新ドキュメントを確認します
- mcp__context7__query-docs -
userEventとwaitForのパターンを確認します
実装後、検証のために fuse-ai-pilot:sniper を実行してください。
概要
使用する場面
- React コンポーネントの動作をテストする
- ユーザー操作を検証する
- アクセシビリティ要件への準拠を確認する
- MSW で API 呼び出しをモックする
- カスタムフックをテストする
- React 19 の機能(useActionState、use())をテストする
React Testing Library を使う理由
| 特徴 | メリット |
|---|---|
| ユーザー中心 | ユーザーに見えるものをテストします |
| アクセシブルなクエリ | アクセシビリティに配慮したマークアップを促します |
| 実装の詳細に依存しない | リファクタリングに強くなります |
| Vitest との統合 | Jest より 10~20 倍高速です |
重要なルール
- まずロールで検索する -
getByRoleが最もアクセシブルです - fireEvent ではなく userEvent を使う - 現実的な操作を再現します
- 非同期処理には waitFor を使う -
setTimeoutは使用しません - API のモックには MSW を使う -
fetchはモックしません - 実装ではなく動作をテストする - 内部状態はテストしません
リファレンスガイド
概念
| トピック | リファレンス |
|---|---|
| セットアップとインストール | references/installation.md |
| クエリの優先順位 | references/queries.md |
| ユーザー操作 | references/user-events.md |
| 非同期パターン | references/async-testing.md |
| API のモック | references/msw-setup.md |
| React 19 のフック | references/react-19-hooks.md |
| アクセシビリティ | references/accessibility-testing.md |
| カスタムフック | references/hooks-testing.md |
| Vitest の設定 | references/vitest-config.md |
| モックのパターン | references/mocking-patterns.md |
テンプレート
| テンプレート | 用途 |
|---|---|
templates/basic-setup.md | Vitest、RTL、MSW の設定 |
templates/component-basic.md | シンプルなコンポーネントのテスト |
templates/component-async.md | ローディング/エラー/成功 |
templates/form-testing.md | フォームと useActionState |
templates/hook-basic.md | カスタムフックのテスト |
templates/api-integration.md | MSW を使った統合テスト |
templates/suspense-testing.md | Suspense と use() |
templates/error-boundary.md | エラー境界のテスト |
templates/accessibility-audit.md | axe-core によるアクセシビリティ監査 |
禁止パターン
| パターン | 理由 | 代替手段 |
|---|---|---|
fireEvent | 現実的ではありません | userEvent |
setTimeout | 不安定になります | waitFor、findBy |
最初に getByTestId を使う | アクセシビリティに配慮していません | getByRole |
fetch を直接モックする | 保守が困難です | MSW |
空の waitFor | アサーションがありません | expect() を追加する |
クイックスタート
インストール
npm install -D vitest @testing-library/react \
@testing-library/user-event @testing-library/jest-dom \
jsdom msw
→ 完全な設定については templates/basic-setup.md を参照してください
基本的なテスト
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
test('button click works', async () => {
const user = userEvent.setup()
render(<Button onClick={fn}>Click</Button>)
await user.click(screen.getByRole('button'))
expect(fn).toHaveBeenCalled()
})
→ その他の例については templates/component-basic.md を参照してください
ベストプラクティス
クエリの優先順位
getByRole- ボタン、見出し、入力欄getByLabelText- フォームの入力欄getByText- 静的テキストgetByTestId- 最終手段
Async Pattern
// Preferred: findBy
await screen.findByText('Loaded')
// Alternative: waitFor
await waitFor(() => expect(...).toBeInTheDocument())
→ See templates/component-async.md
userEvent Setup
const user = userEvent.setup()
await user.click(button)
await user.type(input, 'text')
→ See references/user-events.md
コメント
Markdown 対応