こんにちは。
いよいよ
Reactで学ぶTDD
シリーズの最終回です。
空のフォルダーから始め、
Vite
でプロジェクトを作り、
Counter
を実装し、
MSW
でモックサーバーを立ち上げ、
CI
の自動化まで設定しました。
最初は「テストコードを書くと、余計に時間がかかるのでは?」と思ったかもしれません。
今ではコードを変更するとき、不安よりも
楽しみ
と
自信
を先に感じるようになったのではないでしょうか。
今回は学んだことの要点を整理し、これからどのような開発者を目指すかを考えて、シリーズを締めくくります。
ツールの使い方に加え、
よいソフトウェアを作る姿勢
を学びました。
ツールの理解
実行環境のVitest
と描画を担うReact Testing Library
で、テスト環境を組み立てました。
ユーザーの視点
Stateの名前といった実装の細部より、ユーザーに何が見え、何をクリックするかに注目してテストを書きました。
安全なリファクタリング
テストを安全網にして、コンポーネントの分割やフックの切り出しなど、大きな変更に踏み切れました。
非同期処理とモック
MSW
を導入し、バックエンドAPIが完成する前からフロントエンドを開発できる環境を作りました。
TDDの適用前後で、コードにはどのような違いが生まれたのでしょうか。
適用前 - 絡み合ったコード(Spaghetti Code) 🔗
テストを考えずに書くと、1つのコンポーネントにUI、ビジネスロジック、API呼び出しが絡み合いがちです。「まずは動かそう」と考え、すべてを useEffect に詰め込むことになります。
適用後 - 役割が分かれたコード(Clean Code) 🔗
「これをどうテストするか」と考え始めた瞬間から、構造が改善します。
src/hooks/useUserList.ts // [변화] 로직은 Hook으로 분리되어 독립적으로 테스트 가능해졌습니다.
export function useUserList () {
const [ users , setUsers ] = useState ([]);
// ... 데이터 fetching 로직
return { users };
}
カスタムフック
。ビジネスロジックを分け、再利用性とテストのしやすさを高めました。
Container/Presenter
。データ処理と画面の描画を分け、UIテストを簡単にしました。
3. フロントエンドのテスト戦略(Testing Trophy) 🔗
第13回で
Testing Trophy
の考え方を学びました。すべてを単体テストやE2Eテストだけでまかなう必要はありません。
Static(静的解析)
TypeScript
とESLint
で入力ミスや基本的なエラーを見つけます。費用対効果に優れています。
Unit(単体)
ユーティリティ関数や複雑なフックのロジックを検証します。
Integration(統合)
最も重要な層です。
コンポーネントとユーザーのやり取りをRTL
で検証します。
E2E(エンドツーエンド)
決済やログインなど、重要なシナリオを実際のブラウザで検証します。
シリーズは今回で終わりますが、品質をさらに高めるため、次のテーマにも挑戦できます。
E2Eテスト(Playwright / Cypress) 🔗
これまでは、ブラウザを模したjsdom環境でテストしました。実際のChromeやSafariでスタイルが崩れないか、ページ遷移が動くかを確かめるには、
E2Eツール
が必要です。
この内容は、続く
番外編
で扱う予定です。
視覚的回帰テスト(Storybook / Chromatic) 🔗
機能は動いていても、誤ってボタンの色が変わったらどうでしょうか。これらのツールは、コードで検証しにくいデザインの変化をピクセル単位で比較します。
バックエンドとの協業(Contract Testing) 🔗
フロントエンドのモックデータと実際のバックエンドAPIの仕様がずれると、障害につながります。そこで、APIの仕様(契約)が変わった場合にテストが失敗するようにします。
Terminal git clone https://github.com/PROMLEE/my-tdd-app.git
cd my-tdd-app
TDDは、短期間で習得できる技術ではありません。最初は面倒で、遅く、もどかしく感じるかもしれません。
練習を続けて習慣になると、
バグの少ないコード
に加え、
変更に柔軟なコード
を書けるエンジニアへ成長しているはずです。
👨💻
長いシリーズにお付き合いいただき、ありがとうございました。
皆さんのコードに、いつもグリーンのテスト結果が並びますように!