メインコンテンツにスキップ

🧪 テスト駆動開発(TDD)

📖 定義

TDD(Test-Driven Development、テスト駆動開発)は、テストを先に書いてからそのテストを通過するコードを書く開発手法です。Red-Green-Refactorサイクルを繰り返し、コード品質を高め、バグを減らし、リファクタリングを安全にします。単体テストは個別の関数やコンポーネントを独立して検証するテストです。

🎯 簡単な比喩

設計図を先に描く

従来の開発
1. 家を建て始める
2. 完成後に点検
3. 問題発見 → 大きな修正が必要
4. コスト増加

TDD
1. 設計図を描く(テスト作成)
2. 設計図通りに建てる(コード作成)
3. 検証(テスト実行)
4. 改善(リファクタリング)
5. 安全で正確

⚙️ 動作原理

TDDサイクル (Red-Green-Refactor)

🔴 Red(失敗)
└─ テスト作成 → 失敗(コードなし)

🟢 Green(成功)
└─ 最小限のコード作成 → テスト成功

🔵 Refactor(改善)
└─ コード改善 → テスト依然成功

繰り返し → 段階的改善

💡 主な例

基本的なTDD例

// ========== 1. Red: テスト作成(失敗) ==========
test('add関数は2つの数値を足す', () => {
expect(add(2, 3)).toBe(5);
});
// FAIL - addが定義されていない

// ========== 2. Green: 最小限のコード(成功) ==========
function add(a, b) {
return a + b;
}
// PASS ✅

// ========== 3. Refactor: 改善(必要な場合) ==========
// コードが単純なので改善不要

Jestで単体テスト

// user.js
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}

isValidEmail() {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(this.email);
}
}

// user.test.js
describe('User', () => {
let user;

beforeEach(() => {
user = new User('田中太郎', 'tanaka@example.com');
});

test('有効なメールアドレスでtrueを返す', () => {
expect(user.isValidEmail()).toBe(true);
});

test('無効なメールアドレスでfalseを返す', () => {
user.email = 'invalid-email';
expect(user.isValidEmail()).toBe(false);
});
});

非同期テスト

test('非同期関数がデータを返す', async () => {
const data = await fetchData();
expect(data).toEqual({ name: 'John' });
});

モック

// 関数モック
const mockCallback = jest.fn(x => x * 2);

[1, 2, 3].forEach(mockCallback);

expect(mockCallback).toHaveBeenCalledTimes(3);

// モジュールモック
jest.mock('axios');

test('fetchUserはユーザーデータを返す', async () => {
axios.get.mockResolvedValue({ data: { id: 1 } });
const user = await fetchUser(1);
expect(user).toEqual({ id: 1 });
});

🤔 FAQ

Q1. TDDの利点は?

A:

利点:
1. バグ減少
2. 安全なリファクタリング
3. コード品質向上
4. ドキュメント化
5. 自信

欠点:
1. 初期時間投資
2. 学習曲線
3. テストメンテナンス

結論: 長期的に利益

Q2. 何をテストすべき?

A:

// ✅ テストすべき
1. ビジネスロジック
2. エッジケース
3. エラー処理
4. 公開API

// ❌ テスト不要
1. 外部ライブラリ
2. 単純なgetter/setter
3. プライベート実装詳細

Q3. テストカバレッジの目標は?

A:

# カバレッジ測定
npm test -- --coverage

# 目標:
80%以上のカバレッジ // 現実的な目標
100%カバレッジ // 理想的だが非現実的

# 覚えておく:
高いカバレッジ ≠ 良いテスト
意味のあるテストが重要!

🎬 まとめ

TDDはソフトウェア品質の基盤:

  • Red-Green-Refactor: TDDの核心サイクル
  • 単体テスト: 高速で隔離
  • テストファースト: テストが設計を導く
  • 継続的改善: リファクタリングの安全網

テストは未来の自分への投資です! 🧪✨