テスト駆動開発
「動作するきれいなコード」が TDD のゴール
ルール
コードを書く前に、失敗する自動テストコードを必ず書く
重複を除去する
1. レッド
2. グリーン
3. リファクタリング
サイクル
1. 小さいテストを1つ書く
2. すべてのテストを実行し、1つ失敗することを確認する
3. 小さい変更を行う
4. 再びテストを実行し、すべて成功することを確認する
5. リファクタリングを行い、重複を除去する
仮実装
まずベタ書きの値を使い、実装を進めるに従って徐々に変数に置き換えていく
明白な実装
頭の中の実装をすぐにコードに落とす
予期しないレッドバーを目にしたら、すぐに仮実装モードにシフト
三角測量
設計のアイデアが浮かばないときやどうリファクタリングしたらよいか全くわからないときに使える
TODO リストを作って一つずつ取り組む
書くべきテストを思いついたときには TODO リストに追加する
テスト不足に気づいたら
あればよかったと思うテストを書く
リファクタリングの前にテストが必要
テストを書くときには読者のことを考えるのが何よりも大切
パフォーマンス
独立性
テスト間に依存関係を作ってはならない
潜在的な問題に気づいたときは、すぐに対処するのではなく TODO リストに加えるに留める
テストとは
「評価する」という意味の動詞
「合格か不合格かを判定する手順」を意味する名詞
テストの独立性
テストは他のテストの結果に絶対に影響されるべきではない
実行順序に依存しない
テストを意識的に小さく分割し、独立させる
TODO リストを作る
着手する前に、必要になりそうなテストをリストに書き出しておく
「すべて頭に入れておく」のはかなり難しい
やるべきかもしれないことに気がつき、いまやっていることを見失う
テストファースト
テスト対象のコードを書く前にテストを書く
最初にアサーションを書く
読みやすく理解しやすいテストデータを使う
本物に近いデータを使う
何か思いついたときは TODO リストに加えるだけにして脇道に逸れないようにする
回帰テスト
不具合を再現させる最小のテストケースを書く
疲れたら休憩する
手詰まりで途方に暮れてしまったときは
コードを捨ててやり直そう
Mock Object パターン
決められた結果を返す、偽物のオブジェクトを代わりに作成する
コーディングをやめるときは、テストが失敗する状態にしておく
そのとき何を考えていたか思い出しやすい
「きれいなコード」と「動くコード」を一度に満たすのは難しい
まずは「動く」→ その後ゆっくりと「きれい」にしていく
フィクスチャー
共通する前準備のコードを SetUp メソッドに抽出する方法もある
リファクタリング
よく似ているコードを共通化するには
コードの内容をだんだん近づけていって、完全に一致したところで一つにする
まず変更すべき箇所を独立させる
データ構造の変更
1. 新構造のためのインスタンス変数を定義する
2. 旧構造でデータが設定されている部分をその変数に置き換える
3. 旧構造のデータを使っている部分をその変数に置き換える
4. 旧構造のコードを消す
5. 外部インターフェースに新構造を反映する
API 側からやる場合
1. 新構造のパラメータを追加する
2. 新構造のパラメータを内部で旧構造に変換する
3. 旧構造のパラメータを削除する
4. 旧構造を使っている部分を新構造に置き換えていく
5. 旧構造のコードを削除する
メソッドの抽出
1. メソッドの中から、新しいメソッドとして切り出す意味のある部分を探す。ループの中身やループ全体、条件分岐の各分岐などがよくある抽出対象
2. 抽出する範囲の外で一時変数への代入が行われていないことを確認する
3. 旧メソッドから該当範囲のコードをコピーし、コンパイルする
4. 旧メソッドの一時変数やパラメータの中で新メソッドから使うものを、新メソッドのパラメータに追加する
5. 旧メソッドの中から新メソッドを呼び出す
メソッドのインライン化
メソッド呼び出し部分にそのメソッド本文をペーストする
変更をいろいろ試せる
インターフェースの抽出
メソッドの移動
他のオブジェクトに対して1つ以上のメッセージ通信(メソッド呼び出し)を行なっているのは、移動のサイン
メソッドオブジェクト
複数のパラメータやローカル変数を必要とする込み入ったメソッドは、オブジェクトとして切り出す
パラメータの追加
メソッドからコンストラクタへのパラメータの移動
複数のメソッドに対して同じパラメータを渡している場合、インスタンス変数にすることで重複を排除できる
リファクタリングを行うときは、小さいステップに分割することを心がける
不安が退屈に変わるまでテストを書く
将来のことを考えずにコードを書くことが、将来そのコードが状況に適応する可能性を広げる
テストの削除
自信とコミュニケーションの両面で重複があるのであれば、役に立たない方を消す
テストのことを考えずに書かれたコードは、テストが書きにくい
途中から TDD に乗り換えるときは、システムに変更を加えるときに影響のある部分だけ、少しずつやる
テストを書くだけでは質は上がらない
質を上げるのはプログラミング
TDD によって、核心となるタスクを見分け、それだけに集中することができる