前回のブログ記事スタートアップの罠は論争のきっかけになった。多くの賛同と支援の声が挙がる中で、猛反対するグループがあった。彼らの挙げた見解の相違について要約するつもりはない。ここ一ヶ月の間に呪いの言葉を使い果たしてしまったからだ。だが、その中には一つだけきちんと反応するべき意見があった。
それは古くからある実用主義と教条主義の対立に関する主張だ。端的に言えば、私が教条主義的に過ぎるというものだった。TDD がうまくはまるケースはあるかもしれないが、そのためのコストが高くつきすぎる場合もある。であるからもっと実用主義的になって賢い選択をするべきなのだ、と。
最初はまったく合理的であるように思える。結局実用主義は良いことなんだ。そうでしょう?何が言いたいのかというと、TDD をやることで締め切りを破ってしまうのが分かっていて、TDD をやらなければ締め切りを守れるというなら、あなたは TDD を捨てるんでしょう。そういうことでしょう?
まったく正しい。反論の余地はない。そして実際にその行為が明らかに正しい選択であることはしょっちゅうある。このブログ記事の目的は、私がTDDのコストが高くつくと思うタイミングを示すことにある。
とはいえその前に論旨を明確にしたい。TDD とはプログラマーにとっての規律であり、それは会計士にとっての複式簿記であり、外科医にとっての滅菌手順であるのだ。会計士が複式簿記を使わない場合があるだろうか?外科医が滅菌手順を踏まない場合があるだろうか?
いずれのケースでも答えは yes だ。むしろ会計士が自分の小切手帳の収支を計算するときやレストランの支払いをするときに複式簿記を使わないことを指摘したい。一つ目のケースにおいて彼らが複式簿記を使わないのは間違いであることを証明できる。私はもう何年もの間自分の小切手帳の収支を計算するときに複式簿記を使っているからだ。だが最終的に労力に釣り合うだけのリスクがあるわけではないと確信するに至った。二つ目のケースについてだが、誰もが同意してくれるだろうがレストランでの支払いに複式簿記を使うのはやりすぎだと思っている。
外科医の行う滅菌手順について言うなら、私は数年前腕にできた脂肪腫を除去したことがある。私の妻が看護師をやっていたので、その手順を観察した。それは医師のオフィスで行われていたのだ。妻から医師の準備ができたと告げられた私は、医者先生に「ぶっちゃけ滅菌手順をやっていないんじゃないの?」と聞いてみた。彼いわくこの程度の手術に見合うだけの "消毒" はしているということだった。妻も私もその説明を受け入れ、医者先生による手術は完了した。
数日後、切開箇所が炎症を起こし痛みを伴うようになった。縫合に使った糸の一部が感染していたのだ。そしてそれを除去するため再び切開しなければならないのだという。私は感染の原因が "消毒" によるものだとは知らなかったが、今では執刀した医者先生が "消毒" していなかったのではないかと主張できる。
それでもこの論点は正当なものだ。TDD のコストが高すぎる場合はあるし、代わりに弱い規律に従うべき場面はあるのだ。私の話を聞いた上で、それがごく稀な場合でしかないと納得してくれることを期待している。そして語用論的なミームは、一見使いづらそうに見えるからといってあなたにとっての規律を台無しにするべきではないのだ。
TDD を実践しなくてもよいのはどんな場合だろうか?
私は getter や setter のテストは書かない。それは愚かなことだからだ。getter や setter は他のメソッドを通じて間接的にテストされるだろう。よってそれを直接テストする理由は無いのだ。
私はメンバ変数のテストを書かない。それらもまた間接的にテストされるからだ。
1行の関数のテストも書かないし、取るに足らない明白な関数のテストも書かない。繰り返すが、間接的にテストされるからだ。
私は GUI のテストを書かない。GUI はいじくりまわす必要がある。フォントサイズを変えたり、RGB 値を指定したり、XY の座標値を指定したり、フィールド幅を指定して、適切な場所に置かれるよう微調整しなければならないのだ。それをテストファーストでやるのは愚かで無駄なことだ。
一般的に私は試行錯誤しながら(いじりながら)適切な位置に配置するためのコードのテストは書かない。だが私は "いじるための" コードとそうでないコード、つまりテストが必要だと確信していて実際にテストを書くことが出来るコードを分離している。
数ヶ月前のことだが、私はテスト無しに全体で100行程度のプログラムを書いた。(ギャッ!)
私は普段はフレームワークやデータベース、Web サーバといったサードパーティソフトウェアが期待通りに動くかどうかのテストを書かない。そういったもろもろはモックして、私のコードをテストするのだ。
このリストは不完全なものだ。私がテストを書かない場面が他にもあることは確実だ。だがこのリストに共通する思いは明らかになったはずだ。TDD を実践するにあたって語用論は言葉遊びでしか無いのだ。ドグマだけではないのだ。
だが私はドグマを尊重している。それだけの理由があるのだ。語用論は時には上書きできるものだが、TDD をやるための最大限の努力をしなければ、私にはどんなものであっても重要な商用コードを書くことは出来ないだろう。