Red-Green-Refactor

よく「ほんとに最初にRedにするんですか?毎回必ず絶対に?」と聞かれます。ひとことで答えるなら、

すみませんたまに飛ばしちゃいます

三ことぐらいですかね。だけど、ほとんど毎回Redを経由するようにしているのも、本当です。

なぜ最初にRedにするのか。理由はわりとくだらなくて、書いたテストがちゃんと実行されないと困るからです。JUnitなら@Testアノテーションを忘れるとか、Pythonならテストメソッド名を重複させて上書きしてしまっているとか。昔々はTestSuiteに追加し忘れとかもあったな。実は最近のツール群であればもうそんなこと起きないのかもしれませんが、昔はよくはまった(ほんとによくはまったなあ)ので、自分の規律として(ないし条件付けられて?)まずはRedを見るようにしています。

Redが必要な理由はこれだけでも十分なんですが、他にもメリットはあると感じます。Redにせず最初からGreenに持って行くとしたら、どうでしょうね。けっこうコード書いちゃいませんかね。Redにするなら、テストコード1行書くだけでいいのに、Greenにするには、ターゲットのクラスがあって、メソッドがあって、ということはメソッドのシグネチャも考えてあって、たぶんreturn文もなにかしら書く。どうせ簡単な実装なんだから、中身だってちゃんと書いちゃえ。

そんなに先まで一気に進むのは、不安です。テストの内容をちゃんと考えたか、不安です。仕様について、外部から見た振る舞いについて時間をかけて考えているか、時期尚早に実装に踏み込んでしまっていないか不安です。よりよい設計を導くテストになっているか不安です。不安を取り除くためにTDDを使うのに、そこで不安を感じては本末転倒です。

そもそもコードを書いて、Greenになると嬉しいじゃないですか。「Greenになる」とはつまり、前提としてRedが必要です。GreenがゴールならRedは最初の一歩、その先の一歩一歩もまたRedです。歩き始めなくてはゴールに着かない、だから最初はRedにする。自明です。当然です。自然の摂理です。

Redはまた、プロダクトコードの様子を確かめるいちばん簡単な方法です。昔、TDDを知らない頃は、コードを書きながら途中にprint文を入れて(そうですprintデバッグです)、要所要所で期待通りに動いているか確認していました。今は、中途半端なプロダクトコードでテストを実行して、想定通りの結果になるか確認できます。想定通りの結果とは、nullが返ってくるとか、IndexOutOfBoundsExceptionが起きるとか、通信エラーになるとか、そういうRedです。TDDのサイクルよりさらに小さなマイクロステップで、正しいコードが書けているか確認していることになります。(うーん、そう考えるとこのやりかたは邪道な気もしてきたぞ。)

手すさびとしてのRedってのも、ある気がしますね。ロジックについて考え込んでるとき、半分無意識にポチ、ポチとクリックして、テストを実行する。ペンを回したり鉛筆で落書きしたりマインスイーパやったりするのと同じ感じです。クリックすると画面が反応して動くという簡潔なフィードバックが思考のリズムを整えてくれるのです。たぶん。

なんだか発散してきた気がするのでまとめます。なぜ最初にRedにするのか、その理由です。

  • テストが実行されるか確認する
  • 仕様・外部インターフェースを考える段階と、設計・実装を考える段階をはっきり意識する
  • Greenに「なる」までのステップを細かく刻む