シリーズ構成(全12章)
Ch.1 プロローグ(本章) / Ch.2 TDDとは何か / Ch.3 最初のRed-Green-Refactor / Ch.4 テストリストの技法 / Ch.5 状態を持つオブジェクトのTDD / Ch.6 リファクタリング / Ch.7 外部依存を断ち切る / Ch.8 副作用をイベントに切り出す / Ch.9 アンチパターン・カタログ / Ch.10 TDDの限界と「使わない判断」 / Ch.11 AI時代のTDD / Ch.12 エピローグ
この記事が解決する「状態」
テスト駆動開発(TDD)に対して、こんな感覚を持っていないだろうか。
・Red-Green-Refactor のサイクルは知っている。概念は理解した。
・でも実装しようとすると、「テストを先に書く」の一歩目が出ない。
・書き始めたテストが、実装の詳細に引きずられてすぐ壊れる。
・テストを書いている間に「これ、先にコード書いた方が速いのでは」と思ってしまう。
・気がつくと「テストは後で書こう」と言い続けている。
この状態を終わりにする。
本記事は、TDDを**「知っている」から「回せている」** に移行するための実践ガイドだ。理論の説明で終わる入門記事とは違う。SaaS課金管理システムという実務規模の題材を一貫して使い、12章かけてTDDの全サイクルを追体験する。
そしてもう一つ。2026年、AIがコードを書く時代になった。GitHub Copilot、Claude Code、Cursor──これらのツールが実装を肩代わりしてくれる今、「テストを先に書く」という行為の意味が根本から変わっている。この変化を Ch.11 で正面から扱う。
この記事で得られるもの
読み終えると、あなたは:
1. Red-Green-Refactor の「思考プロセス」を手順として持てる
2. 「テストを先に書けない」原因を特定し、対処できる
3. 実務コードでTDDを回すための具体的な技法を身につけている
4. TDDアンチパターンを症状から逆引きして脱出できる
5. TDDが有効な場面と、使わない方がいい場面を判断できる
6. AI時代におけるTDDの新しい位置づけを理解している
対象読者
対象:テストは書くが「テストファースト」ができていないエンジニア
TDDを試したが定着しなかった方
AI時代にTDDの意義を問い直したい方
難易度:★★★☆☆
読了時間:約3時間
前提知識:TypeScriptの基礎的な読解力
テストフレームワーク(Jest / Vitest)の基本的な使い方
「Red-Green-Refactor」という言葉を聞いたことがある
概念を初めて学ぶ人向けではない。「知っているが、やれていない」人向けに書いている。
通し事例:SaaS課金管理システム
本記事全体を通じて、SaaS課金管理システム を題材にする。FizzBuzz や TODO アプリではなく、この題材を選んだ理由は3つある。
- 実務に近い:金額計算、状態遷移、通知──テスト対象として豊富なバリエーションがある
- テストの価値が直感的:「金額のバグ」は誰もが怖い。テストを書く動機が自然に生まれる
- 設計が自然に育つ:テストで駆動していくと、コードの構造が段階的に整理されていく。この過程を体験してほしい
扱う主な機能は以下の4つだ。
| 機能 | 責務 | TDDで扱う章 |
|---|---|---|
| 金額計算(Money) | 通貨付き金額の演算・検証 | Ch.3, Ch.4 |
| 契約管理(Subscription) | 顧客のプラン契約と状態遷移 | Ch.5, Ch.6 |
| 契約の永続化 | 契約データの保存・取得 | Ch.7 |
| 通知(Notification) | 契約変更時のメール・Slack通知 | Ch.8 |
graph LR
Money[金額計算<br/>Money]
Subscription[契約管理<br/>Subscription]
Storage[永続化]
Notification[通知<br/>Notification]
Money -->|金額をSubscriptionが利用| Subscription
Subscription -->|保存・取得| Storage
Subscription -->|契約変更を通知| Notification
最初は「金額を正しく計算するテスト」という最小の問題から始め、章を追うごとにスコープを広げていく。各章で新しいTDDの技法を学びながら、システムが育っていく過程を追体験してほしい。
テスト環境
コード例はすべて TypeScript + Vitest で書かれている。Vitest を選んだ理由は、2026年時点で最も高速かつ TypeScript ネイティブなテストランナーだからだ。ただし、本記事で扱うTDDの技法はフレームワークに依存しない。Jest でも Bun でも同じ原則が適用できる。
# 本記事のコード例を試す最小環境
npm init -y
npm install -D typescript vitest @types/node
npx vitest --watch
vitest --watch を起動したまま開発する。ファイルを保存するたびにテストが走り、Red か Green かが即座にわかる。このフィードバックの速さが、TDDのリズムの核心だ。
本記事の読み方
本記事は前から順に読む設計になっている。各章は前章のコードと知識を引き継ぐ。
Ch.2 TDDの思考法を理解する
↓
Ch.3-4 最初のTDDサイクルを回す(金額計算)
↓
Ch.5-6 状態を持つコードのTDDを学ぶ(契約管理)
↓
Ch.7-8 外部依存・副作用のテスト技法を学ぶ
↓
Ch.9-10 アンチパターンと限界を知る
↓
Ch.11 AI時代のTDDを知る
↓
Ch.12 全体を振り返る
各章には必ずコード例がある。読むだけでも学べるが、手を動かして vitest --watch の Red → Green を体験すると、理解の深さが段違いになる。
筆者の立場表明
公平を期すため、本記事を書く筆者の立場を先に明かす。
・TDDは「正しく使えば開発速度を上げる」と考えている。
ただし「正しく」の定義が難しく、多くの人が挫折する原因もそこにある。
・テストカバレッジ100%を目指すべきとは考えていない。
テストの価値はカバレッジではなく「変更への自信」で測るべきだ。
・TDDが向かない場面は確実にある。
プロトタイプ、UI探索、未知のAPIとの格闘──これらでTDDを強制するのは逆効果だ。
・AI時代にTDDの価値は下がるどころか上がっている、と考えている。
ただし、その理由は多くの人が想像するものとは少し違う。
この立場は本記事の基調をなす。異なる立場の読者は、その差分を持ち帰って自分の判断に活用してほしい。
ここから始まる
次章では、TDDの本質に迫る。「テストを先に書く手法」という表面的な理解から一歩踏み込み、Red-Green-Refactor がなぜ機能するのかを解き明かす。
では、始めよう。