TDD グリーンバーにするための 3 つの戦略
はじめに
ソフトウェア開発の設計手法として広く認知されている TDD ですが、きちんと勉強したことがなかったので、TDD の原典とも言えるテスト駆動開発を読みました。
「テストを先に書くもの」くらいの浅い認識しかなかったので、とても学びになりました。
この記事では、先にテストを書いてレッドバーにしたあと、それをグリーンバーにするための戦略についてシンプルなコードを使って書いてみます。
お題
今回のサンプルでは、正の整数を表現する PositiveInt
クラスがすでに実装されており、それに偶数判定をするメソッドを追加するケースを考えてみます。
3 つの戦略
グリーンバーにするためには 3 つの戦略があるとされています。
- 仮実装: ベタ書きの実装。とりあえずグリーンバーにする。
- 三角測量: 2 つ以上のテストケースから実装を導き出す。
- 明白な実装: 仮実装を通さず、頭の中の実装をコードに落とす。
仮実装
テストは PositiveInt
のオブジェクトが偶数の時に成功するケースにしました。この時点ではテストは通りません。
class PositiveIntTest {
@Test
public void testIsEven() {
PositiveInt two = new PositiveInt(2);
assertTrue(two.isEven());
}
}
仮実装は素早くグリーンバーにするための戦略です。isEven()
からは固定で true
を返すようにし、テスト結果をグリーンにします。
public class PositiveInt {
private final int value;
PositiveInt(final int value) {
if (value < 0) {
throw new IllegalArgumentException();
}
this.value = value;
}
boolean isEven() {
return true;
}
}
三角測量
先ほどのテストコードに、もうひとつ以上のテストを書くことでプロダクションコードを導き出します。
以下では PositiveInt
のコンストラクタに 1
を渡して生成したオブジェクトが奇数であることを確認するケースを追加しました。これでまたテスト結果がレッドになります。
class PositiveIntTest {
@Test
public void testIsEven() {
PositiveInt two = new PositiveInt(2);
assertTrue(two.isEven());
// 追加したテストケース
PositiveInt one = new PositiveInt(1);
assertFalse(one.isEven());
}
}
ここから導き出せる実装をコードにし、テスト結果をグリーンにします。
public class PositiveInt {
private final int value;
PositiveInt(final int value) {
if (value < 0) {
throw new IllegalArgumentException();
}
this.value = value;
}
boolean isEven() {
return (value % 2 == 0);
}
}
明白な実装
書くべきコードがわかっているときに、仮実装や三角測量をしないで、それを直接コードに落とすことです。今回のサンプルで言うと、仮実装の時のテストコードに対して、三角測量で導き出したプロダクションコードを最初から書くことになるかと思います。繰り返しになってしまいますが、あえてコードをあげるとこうなります。
class PositiveIntTest {
@Test
public void testIsEven() {
PositiveInt two = new PositiveInt(2);
assertTrue(two.isEven());
}
}
public class PositiveInt {
private final int value;
PositiveInt(final int value) {
if (value < 0) {
throw new IllegalArgumentException();
}
this.value = value;
}
boolean isEven() {
return (value % 2 == 0);
}
}
おわりに
仮実装という考えが自分には新鮮でしたー。
そして当然これ以外にも多くのことを学びました。たとえば p. 266 の「不安が退屈に変わるまでテストを書く」というのは、TDD としてのテストををどこまで書くのか?という疑問に対する分かりやすく良い指針だと感じました。
まだ読んだことがない方にぜひおすすめしたい本でした。
Discussion