【アーキテクチャ】TDD(テスト駆動開発) - j-komatsu/myCheatSheet GitHub Wiki
TDD(テスト駆動開発)
読み方
TDD(Test-Driven Development / テスト駆動開発)
概要
TDD(テスト駆動開発)とは、ソフトウェア開発手法の一つで、テストを先に書いてから実装を行う方式です。
テストが通る最小限のコードを書き、リファクタリングを繰り返すことで、堅牢でメンテナブルなコードを実現できます。
TDDの特徴
特徴 | 初学者向けの説明 | 専門者向けの説明 |
---|---|---|
テストファースト | コードを書く前にテストを作る | 開発の指針としてテストを先行させることで、仕様の明確化とバグの抑制が可能 |
短い開発サイクル | 失敗するテスト → コード実装 → テスト成功 を繰り返す | Red-Green-Refactorのサイクルにより、早期にバグを発見し修正できる |
リファクタリング | 動作するコードをきれいにする | テストがあることでリファクタリング時の影響範囲をコントロールしやすい |
TDDのサイクル(Red-Green-Refactor)
graph TD;
A[テストを書く (RED)] -->|失敗する| B[実装を行う (GREEN)]
B -->|成功する| C[リファクタリング]
C -->|整理完了| A
TDDの利点と欠点
利点
- バグを早期に発見できる
- コードの品質が向上する
- 仕様変更に強い設計ができる
- リファクタリングが容易になる
欠点
- 初期コストが高い(テストを書く時間が必要)
- 小規模プロジェクトではオーバーヘッドになることがある
- 実装がテスト駆動に縛られ、柔軟性が失われる場合がある
TDDの具体的な手順
- 失敗するテストを作成(RED)
- テストが通る最低限のコードを実装(GREEN)
- コードを整理(リファクタリング)(REFACTOR)
- 再度テストを実行して正常に動作することを確認
TDDの実装例(Python)
import unittest
def add(x, y):
return x + y
class TestMath(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(-1, 1), 0)
if __name__ == "__main__":
unittest.main()
解説
unittest
を使い、add
関数のテストを先に作成。add(2, 3) == 5
などのテストを定義。- これを実行し、テストが失敗することを確認(RED)。
add
関数を実装し、テストが通るように修正(GREEN)。- さらにリファクタリングを行い、最適化(REFACTOR)。
設定内容(開発環境の準備)
PythonでTDDを行う場合
# unittestを使用する場合(標準ライブラリ)
python -m unittest test_file.py
# pytestを使用する場合(推奨)
pip install pytest
pytest test_file.py
JavaScript(Jest)の場合
npm install --save-dev jest
// add.js
function add(a, b) {
return a + b;
}
module.exports = add;
// add.test.js
const add = require('./add');
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
npx jest
TDDのたとえ話
TDDは「レシピを先に作る料理」と似ています。
- まずレシピを考える(テストを書く) → どんな料理を作るか明確になる
- レシピ通りに調理する(コードを書く) → 目的の料理ができる
- 味見して調整(リファクタリング) → もっとおいしく仕上げる
このように、TDDでは 「ゴールを決めてから作る」 ことで、ブレのない開発が可能になります。
まとめ
TDDは、テストを先に書くことで品質を向上させる開発手法です。最初は手間がかかりますが、長期的には バグの削減・仕様変更への耐性 などのメリットを得られます。
初心者は、小さな関数のテストから始めて、徐々にTDDの流れに慣れていくとよいでしょう。