The Test-First Stoplight - XP123を訳してみました。
何をしてるか自分でも分かりません。
Extreme Programmers はプロダクションコードを書く前に、対応するテストを書きます。
"テストファーストプラグラミング" では、小さなテストを書いてから、そのテストを通過するだけのちょうどよいコードを書き、
さらに次のテストを書くことを繰り返していきます。
The Test-First Stoplight
テストファーストプログラミングは信号に似てます。
道路の信号には緑、黄、赤があります。
最初は緑から始まり、黄、そして赤になり、再び緑に戻ります。
ごくまれに違うパターンの点灯をすることもあります。
黄点滅だったり、赤点滅だったり、です。
こういった様子を見かけたら、よく注意しましょう。そしてこう聞いてみましょう。「何が起きてるの?」
Java のユニットテストは、多くのプロジェクトでテスティングフレームワークとして JUnit が使われています。
JUnit では、全てのテストが通過したら、緑の棒が表示されます。この棒は、どれかのテストが失敗していたら赤になります。
この色の変化は、青信号、赤信号のように考えることができます。
コンパイルに失敗するのは黄色信号です。
我々は、普通の信号と同じように、緑、黄、赤、緑、黄、赤、と変化していくことを予想してます。
- 始め! (緑!)
- テスト書く
- テストを実行する。まだ、テストから呼んでるルーチンは書かれてないので、コンパイルエラーになります (黄!)
- 新たなルーチンのスタブを書く
- テストを実行する。スタブは何もしてくれないので、テストは失敗します (赤!)
- スタブのルーチンの本体をちゃんと書く
- テストを実行する。テストは成功します (また緑になった!)
- 繰り返しの最初に戻る
Abnormal Patterns
緑から緑:テストは正しく通過しました。
これは、テストが駄目な場合と、これからテストするコードを先に実装しちゃっている場合に起きます。
テストが失敗することを確認するため、実装をちょっと変えてみることを検討しましょう。
(後述する "リファクタリング" の節を読んでおいてくださいね。)
緑から赤:テストはちゃんと失敗しました。
既存のルーチンに対する新たなテストを追加したなら、OK です。
黄から黄:あー、スタブが構文エラーになってますね。
黄から緑へ:テストはスタブが無いとコンパイルエラーになってしまう
でも、スタブを加えるとテストが通過してしまいます。
すごい怪しい。スタブで何もしてないのにテストを通過してしまうなら、そのテスト間違ってるんじゃないですか?
赤から黄へ:新しいコードがちゃんと動いてないです。
誰にでもよくあることなので、ただただコードを直しましょう。
ただ、これがしょっちゅう起きるようなら、もう少し小さなテストを書いたほうがいいことを示唆しているかもしれません。
(そうすれば新しいコードの変更も小さくなるよね)
Quick Cycle
サイクルはそんなに長い時間かかるものではありません。
- テスト書く、スタブ書く、本体を書く
- コンパイルは 3 回
- テストの実行は 2 回
あなたの開発環境にもよりますが、1 つのサイクルを回すのに 1 分から 5 分くらいしかかからないでしょう。
10 分とか 15 分を越えてしまうようなら、1 サイクルが長すぎるので、テストの対象をもっと小さくしましょう。
Refactoring
リファクタリングするときは、信号が黄から赤になるところを見ることはほとんどありえません。
それは、ドライブしている途中で出くわす信号がいつも緑になってるようなものなのです。
黄とか赤になってしまうことは、文法を見直すべきとか、もっと慎重に変形するべきといったことを意味しています。
コンパイラが何が安全でないかを教えてくれるのです。
いつも緑信号で行きましょう。
Example
person オブジェクトのコード例を見てみましょう。小さいものです。
public class Person {
String name;
int favorite = -1;
public Person(String name,int favorite) {
this.name = name;
this.favorite = favorite;
}
}
あなたがすることは、このオブジェクトを XML 形式にすることです。こんな風に。
the-name
the-name
- 緑から始める
- テストを書く
Person p = new Person("Pop", -1);
assertEquals("Pop ", p.asXml());
- コンパイルすると、文法エラーになります。(黄!) asXml() メソッドが無いからです。
- Person クラスにスタブを追加する
public String asXml() { return null; }
- コンパイルしてテストを実行。テストは失敗した (赤!)
- できるだけ単純に実装する
public String asXml() { return "" + name + " "; }
- コンパイルしてテストを実行。緑キタコレ。1 つのサイクル完了です。
- 2 つめのテストを加える
Person p2 = new Person("Mom", 1);
assertEquals("Mom ", p2.asXml());
- コンパイルしてテストを実行。黄信号を飛ばして赤信号になってしまった。asXml() は存在しているけど、正しい機能を持ってないからです。
- 特別なコードを追加して、信号は再び緑に。
Conclusion
あなたのコードの信号を見えるようにしましょう。
異常パターンがあなたを傷付ける前に。