“test && commit || revert” by Kent Beck
以下は、Kent Beckによる「test && commit || revert」の翻訳です。本人の許可を得て掲載します。
「Limbo on the Cheap」のなかで、新しいプログラミングワークフローを考案しました。テストが成功するたびにコードをコミットする「test && commit」というものです。Oddmund Strømme(私が最初に出会った、私と同じく対称性に取り憑かれたプログラマ)が、テストが失敗したらコードをリバートすべきだと提案してくれました。私はこのアイデアが大嫌いだったので、とりあえず試してみることにしました。
そのコマンドは「test && commit || revert」になります。テストが失敗したら、コードはテストが最後にパスしたときの状態に戻るのです。
私は「test && commit || revert」に賛同はしていませんし、そのトレードオフについて説明するつもりもありません。動作はするでしょうけど、あんまりうまくいかないんじゃないかと思います。まあ、みなさんも試してみてはいかがでしょうか(新しいプログラミングワークフローなら何でも試してみたい人向け)。
とは言ってみたものの
「test && commit || revert」はうまくいかない、そんなふうに考えていた時期が私にもありました。常にテストを動かさなければならないとしたら、どうやって進捗するのだろう。ときどきミスをするんじゃないの?コードを大量に書いたあとで、それが全部消えたらどうなるだろう。絶対イライラするでしょ?
その驚くべき答えは、いずれも「はい」になります。あなたは以下のようにコードを書くこともできるのです。
ときどきミスをするんじゃないの?
はい、ときどきミスをするでしょうけど(埋没コストの誤りをしなければ)間違ったコードがすぐに削除されるのはよいことです。大量のコードを消されたくないなら、グリーンとグリーンのあいだに大量のコードを書かなければいいでしょう。
絶対イライラするでしょ?
はい、コードが消えたらイライラするでしょうけど、同じことをもっとうまく、もっと確実に、もっとインクリメンタルにやれる方法が見つかるはずです。
インクリメント
Limboは、小さな変更を即座に伝えることで、技術的なコラボレーションを拡大させるものです。TDDはLimboでは機能しないでしょう。プログラマが10万人いたとして、1つのテストの失敗で他のすべてのプログラマに負担をかけることなどできないからです。テストが大量に失敗していたら、誰も何が起きているのかを把握できないでしょう。変更を反映するには、すべてのテストをパスさせる必要があります。
一方、「test && commit || revert」は、すべてのテストをグリーンに保ちます。ですが、大きな問題を小さなステップで一気に解決することなどできません。では、「test && commit || revert」を使うときの「ステップ」とは何でしょうか?
- テストを追加してパスさせる。ここでのゴールは、アイデアと何らかの方法でテストをパスさせるまでの時間を短くすることです。実際にテストを書かなくても大丈夫です。ここではチートも推奨します。ただし、そこで手を止めてしまってはいけません。
- テストをうまくパスさせる。テストがパスしたら、フェイクの実装をリアルな実装に置き換えます。必要に応じて、少しずつ置き換えましょう。
- 難しい変更を簡単にする。たとえば、4か所を変更するのではなく、ヘルパー関数を導入して(もちろん少しずつ)、1か所の変更で済むようにします。
これらの戦略に違反すると変更が即座にリバートされるため、わざわざ差分を小さくするために悩む必要がありません。
試してみよう
「test && commit || revert」のほうが現状よりも優れているからという理由で、みなさんに試してもらいたいわけではありません。私が提案しているのは、以下の理由からです。
- 安上がりだから
- 何かを学ぶことになるから
まずは小さなプロジェクトを選択しましょう。フィボナッチ数を扱うようなものでも構いません。そこから開発を始めてください。変更がどれだけ小さくできるかを確認しましょう。そのなかのいくつかは失敗するでしょう。さらに小さくできるかを確認しましょう。あなたが頻繁に使っているワークフローの小さな部分に注目してください。そのなかで「リアルな」仕事に適用できるものを確認しましょう。
このCode CampをスポンサーをしてくれたIterate社と、TCRについて深堀り、考え、試し、話してくれた、Oddmund Strømme、Lars Barlindhaug、Ole Johannessenに改めて感謝します。