レガシーコードからの脱却 まとめ – 11.1 – 11.4

11.1 レッド/グリーン/リファクタリング

内容

テストファースト開発には3つのことなるフェーズがある。

レッド/グリーン/リファクタリング

だ。ユニットテストフレームワークの視覚効果が由来する。

  • レッド
    テストを失敗「させる」(コンパイルエラーも含まれる)。
    コンパイルエラーが起きたら「スタブアウト」を作り、テストを失敗させる。
  • グリーン
    すべてのテストを成功させる。
  • リファクタリング
    コードからリファクタリングし、テストをリファクタリングする

一つのユニットテストを作る中で、この3つのフェーズを繰り返し行っていく。
一つのユニットテストというのは、1アサートという意味ではなく、1つのインターフェースに対してかかっている。
1インターフェース:複数アサートはあり得る。

11.2 テストコードの例

Parsonという名前と年齢を持つクラスのテストを例にしてテストを解説している。

  1. レッドのフェーズ。クラスが一つも無いところからハッピーパスのテストを書き始める。内容は、Personクラスのコンストラクタに渡した名前と年齢の値がPersonクラスの getName() と getAge() で取得した値と同じかどうかをテストする。クラスは無いのでコンパイルエラーが発生する。
  2. コンパイルエラーのみ解消するために、Personクラスをスタブとしてとして作成してコンパイルエラーの部分を解消。
    スタブはクイックフィックス機能で作成し、メソッド返却値はダミーのままにすること。
    テストはコンパイルエラーが解消するので実行すると、返却値がダミーなのでエラーとなる。
    最初の目的はテストを失敗させることなのでOK。
  3. グリーンのフェーズ。テストが通るようにプロダクトコードを修正する。コンストラクタの引数をメソッドで返すように実装する。

11.3 制約を導入する

Personクラスの年齢に負の数を入れると年齢としてはおかしくなるので、そういった不備をなくすために制約を入れる。そういう場合の解説。
ここでもテストファーストで書きながら説明している。

  1. Personクラスに最大と最小の定数のテストを書く
    1. レッドフェーズ。
      1. Personクラスに最大と最小の定数を記述しコンパイルエラーを出す。
      2. コンパイルエラーをクイックフィックスを使い解消
      3. 実行すると失敗するのでレッド完了。
    2. グリーンフェーズ。
      1. Personクラスの最大値、最小値の値を適切に設定して実行。OKとなりグリーン完了。
  2. 次にコンストラクタの引数・年齢に最小値より小さい値を入れたらエラーとなるテスト
    1. レッドフェーズ
      1. 投げられるとOKとなる例外クラスをテストに書いてコンパイルエラーを起こす。
      2. コンパイルエラーの例外クラスはクイックフィックスで作成し、コンパイルエラーを解消。
      3. 実行すると失敗するのでレッド完了。
    2. グリーンフェーズ
      1. Personクラスのコンストラクタ内で最小値より小さい場合に例外を投げる処理を追加して実行。OKとなりグリーン完了。
  3. 次にコンストラクタの引数・年齢に最大値より大きい値を入れたらエラーとなるテスト
    1. 最小値のテストと同じ要領で最大値のテストを追加してグリーンまで完了させる。
    2. リファクタリング
      1. 最小値と最大値で違う例外を投げるようにしたが、範囲外を表す1つのクラスにした方が使い勝手が良さそうなため、そちらを使うようにする。

11.4 作ったもの

11.2 – 11.3 で作ったものを通しての要点は
「テストは仕様であり、テストは不要に重複しないように作る」
のがポイントと言っている。

学び

  • テストメソッド名に関する名前重要。
    何をテストしているかが分かれば、冗長でも構わない。
    何をテストしているかと仕様がわかることが重要。
  • コンパイルエラーの解消はクイックフィックスで解消していくことで、コードのタイプミスを減らせる。
  • レッドのフェーズは、コンパイルエラーからテストを実行して失敗させること。
  • 最大値、最小値などの値よりも定数の名前が重要。境界値は時代の変化に合わせて変わるかもしれないが、重要なのは簡単に変えられるようにしておくこと。
  • 例外をテストする方法。
  • レッド/グリーン/リファクタリングの3つのフェーズの基本。
  • テストコードは「失敗をさせ、正しいコードにすることで保証されたものとなる」で、このためにレッド/グリーンのフェーズがある。
  • テストは仕様である。
  • テストは不要に重複しないように作る。

学びを活かすアイディア・行動

  • ユニットテストのコーディング規約づくり
  • テストの目的をまとめる
  • 現場のテストコードのコーディング規約づくり(ドキュメント性)

kiyoshi.saito@tttsunagari.jp

アプリ開発をメインにWebアプリ開発をやってるフリーランスエンジニアです。

Leave a Reply

Your email address will not be published. Required fields are marked *