プログラマーテストの原則 by Kent Beck

以下は、Kent Beckによる「Programmer Test Principles」の翻訳です。本人の許可を得て掲載します。
チョコレート対バニラ

TDD対BDD。このテストツール対あのテストツール。テストビフォー対テストアフター対これは動くから俺を信じろ。ある時期から、こうした詳細に関する議論には飽きてしまった。もっと原則について議論したい。

詳細に関する議論はなかなか結論に至らずに、話が行ったり来たりする。チョコレート対バニラ。チョコレート。バニラ。チョコレート。バニラ。

詳細の議論に負けを認めさせられるようなことがあっても、その譲歩は絶対的なものではない。私の状況がチョコレートを勧めているのに、私にバニラを食べさせてくれと言えるだろうか? これでは埒が明かない。

原則

一方、原則は議論を生み出す基盤になる。原則には賛成しても状況が違っているのなら、答えは違ってくるかもしれないが、そこで論争になることはない。原則が、異なる状況における異なる答えを生み出したのである。

詳細で論争するよりも、原則で論争したほうが生産的だ。私が完全性よりも速度を優先していると主張しても、あなたは速度よりも完全性を優先していると主張することができる。両者がそれぞれの状況において「正しい」。つまり、それぞれのニーズを満たす最高の決断をしているのだ。それと同時に、こうしたレベルで原則について議論することで、お互いの違いをうまく理解できるようになる。

プログラマーテスト

テストは神託である。「嗚呼、大いなる神託よ、これをデプロイしたら何が起きるというのか?」「我が子よ、大惨事が発生するだろう」。このように、テストはデプロイの結果を予言してくれる。

プログラマーテストは神託であり、コーディングと意思決定を繰り返すことによるフィードバックを提供してくれる。また、プログラマーテストは、難しい制約の組み合わせの影響を受けることになる。

プログラマーのテストは高速でなければいけない。フィードバックはプログラミングの流れを妨害してはいけない。スローテストはコーディングの意思決定をバッチ化してしまう。後続のテストの失敗はデバッグが困難である。これは、意思決定の1? 意思決定の2? それとも2つの組み合わせ?

どれだけ速ければ速いのか? 1秒未満が境界のように思える。目を離す間もないくらい、待ち時間が短いからだ。これが10秒だと椅子に深く腰掛けて目を離すことになるだろうが、新しいことを始めるほどの時間ではない。1分はコンテキストスイッチだ。デバッグのコストが高まり、実行するテストの数を減らしたくなる。

プログラマーテストは確定的でなければいけない。よく見かける「当てにならない(flaky)」テストは除外にするにしても、この主張が物議を醸すことになろうとは思ってもいなかった。確定的ではないテストは即削除する、というFacebookの方針が私は好きだった。カバレッジを下げたくなければ、テストができるように設計を変更して、テストを改めて書けばいい。

プログラマーテストは予言するものでなければいけない。神託が「デプロイしろ」と言ったのに、デプロイが失敗したのなら、神託を信じることをやめるだろう。

プログラマーのテストは、振る舞いの変化に敏感であり、構造の変化に鈍感でなければいけない。つまり、プログラムの振る舞いが安定しているように見えるなら、テストを変えるべきではない。

構造を変えないテストには、特定のスタイルの設計だけでなく、特定のスタイルのプログラミングと設計の両方が求められる。「このオブジェクトがこのメッセージをこれらのパラメータを持つオブジェクトに送信してから、あのメッセージをあのオブジェクトに送信すること」のようにアサートしているテストをよく見かける。だが、このようなアサーションは、世界で最も醜いプログラミング言語の構文だ。オペレーションの順序を気にしなければいけないとしたら、それはシステムの設計が間違っている。

プログラマーテストは安価に記述できなければいけない。テストを書くことに給与が支払われるわけではない。「a) きちんと動作」する「b) 変更できる」コードに対して給与が支払われるのだ。テストがそれを支援することもあるだろうが、他の条件が同じであれば、テストにかける労力は少ないほうがよい。

プログラマーテストは安価に読めなければいけない。テストは(コードと同様に)書くよりも読むことのほうが多い。

プログラマーテストは安価に変更できなければいけない。ひとつの振る舞いを変更したことで、テストがいくつもレッドになることがある。テストは個別に検討および変更できるようにすべきだ。そうすれば、テストが変更の非常ブレーキになる。

まとめると、プログラマーテストは、

  • プログラマの待ち時間を最小限にする。
  • 信頼して実行できる。
  • デプロイ可能かどうかを予言できる。
  • 振る舞いの変化に反応する。
  • 構造の変化に反応しない。
  • 安価に書ける。
  • 安価に読める。
  • 安価に変更できる。

なんとも解決が難しい制約の組み合わせである。なかには矛盾しているものもある。どれが最も重要で、どうすればそれを最大限に満たすことができるかを見つけよう。そして、それがあなたの仕事である。

領域

私がプログラマをコーチするときに懸念しているのは、彼らがテストの領域を探索したことがないことだ。テストに1分以上かかっているが仕方ない。テストを非確定的にするしかない。コードの構造を変えたときにもテストを変更せざるを得ない。そんなことはない。

上記の原則を考えてみよう。原則に違反しているテストを見つけよう。同様のテストで原則を守っているものを想像してみよう。そのようなテストが書けなければ、テスト対象のソフトウェアの設計を、プログラマーテストの原則を満たすテストが書けるようなものにしてみよう。

--

--

角 征典 (@kdmsnr)
ワイクル株式会社:ブログ

ワイクル株式会社 代表取締役 / 東京工業大学 特任講師 / 翻訳『リーダブルコード』『Running Lean』『Team Geek』『エクストリームプログラミング』他多数