テスト駆動開発の基礎知識。
TDDとは
汚いコードとは
以下が含まれていると「汚いコード」になる。
- 密結合
- 多重ネスト
- 巨大なクラス
- 多すぎる引数
- 多すぎる責務
TDDは分割統治
「動作するきれなコード」を目指して次の2つに分けて近づけていく。
- きれいなコード
- 動作するコード
TDDの目的
素早いフィードバックの確保
- 動作チェックの高速化
- プログラミングミスの早期発見
- 「順調に進んでいる」という安心感
設計改善効果
ユニットテストの確保
TDDに必要なこと
- 問題を小さく分割する
- 開発の歩幅を調整する
- テスト → 仮実装 -> 三角測量 -> 実装
- テスト → 仮実装 -> 実装
- テスト → 明白な実装
- テストの構造化
- リファクタリング力
- テスト作成、テスト実行、実装を素早くテンポよく繰り返す
TDD三大原則
- 失敗するてユニットテストより先にプロダクションコードを書かない
- テストケースが適切に失敗するまで次のテストケースを書かない
- 全てのテストケースが成功するまで次のプロダクションコードを書かない
TDDのサイクル
- 目標を考える
- テキストで目標を書き出す
- テスト容易性の高いもの、低いもので目標を分ける
- 目標の中から書くテストをを決める(テスト容易性が低いものを基準に選択)
- 目標を示すテストを書く
- テストを実行して失敗させる(Red)
- テスティングフレームワークが正しく動作していることを最初に確認する
- 最初のテストは設計要素が多いので作業が重い
- 目的を達成する最低限のコードを書く
- コピペでも良いのでとにかく動作させる
- テストを成功させる(Green)
- テストコードのテストは最初に行う(仮実装)
- テストが通るまでリファクタリングを行う(Refactor)
- テストが成功したままで中身を改善する
- プロダクション、テストどちらのコードも行う
- 1-6を繰り返す
- 繰り返す回数は事前に決める
TDDが苦手なところ
- DBやUIがテスト実行に制約があるコンポーネントのテスト
- プロトタイピング等で抜本的な変更が頻繁に行われるコード
- 処理に時間がかかるコードのテスト
テストのアンチパターン
- assertは縦に並べない
- どのテストが失敗しているか分かりにくい
- テストが失敗すると実行されないテストが発生する
- 「アサーションルーレット」と呼ばれる
- テスト同士に依存性を持たせない
- 並列分散実行できなくなる
ドキュメントとしてテストを機能させるには
- テスト名を抽象化しない
- テスト名を具体性の高いものにする
- テスト項目をTodoリストと同じような階層構造にする
- 無意味な重複したテストは削除する
- 三角測量用のテスト
- テストの不安を解消するためのテスト