TDD
TDDにおける「テスト」はテストではない
これは否定的な意味ではなく、従来的な意味での「テスト」といった低次元のものではなく、より高次元のものである(らしい)。
Michael Feathers氏の言
まずは以下を読んでもらいたい。
http://www.hyuki.com/yukiwiki/wiki.cgi?FlawedTheoryBehindUnitTesting
「単体テストは単体レベルのエラーを捕捉するだけで品質に寄与しているわけではない。統合テストは統合レベルのエラーを捕捉するだけで品質に寄与しているわけではない。真実はもっと繊細なところにある。品質は思考と内省の賜物だ ... 緻密な思考と、慎重な内省の。ここに魔法の力がある。常にその規律を強いる技術が、品質を高めてくれるのだ。 」(結城浩氏訳)
私自身の経験から
「プログラムはわかりやすく書け」とは一般的に言われることである。しかし、何をもって「わかりやすい」のかは曖昧であり、人それぞれと言わざるをえない。それどころか忙しい時には、ついつい自分でも訳のわからないプログラムを記述してしまう。人間は怠惰なものなので、何らかの制約条件を課されなければそれを実行しようとはしないものである。
結局、何らかの外部的な圧力を受けなければならないのだが、それは(ペアプログラミングやレビューでも無い限り)基本的に個人的作業であるプログラミングには入り込む余地はない。
そこに、TDDを導入すると何が起こるか。TDDなどという大袈裟な言葉ではなく、あるいはテストファーストなどという手順でもなく、単に「プログラムと同時にテストを書かなければならない」という制約を課されるとどのようなことが起こるか。
テストを書くのは非常に面倒なのである。ただでさえ忙しいのにテストを書いている暇などあるものか。しかし、その状況であえてテストを書かねばならないのである。テストコードを短くしたいと思うのが人情だ。そして、そのためにはできる限り単純なテストコードで済ませることのできるプログラムを書かざるをえなくなるのである。
ここにTDDの本質があるように思う。人間が怠惰であるという事実を利用して品質を高めるためのモチベーションを提供するのがTDDである(ように思う)。
なぜテストコードが短くて済むような単純なプログラムなら品質が高いと言えるのだろうか?今のところ明確な説明はできないのだが、経験によると(自ら記述したプログラムを振り返れば)この効果は抜群のように思える。
特に、PHP等のいわゆるスクリプト言語ではテストカバレッジ100%近くでなければ怖くて使うことなどできないものだが、これも経験によればTDDの効果は絶大に思える。
プログラミングという作業とは何か
「テスト」という言葉には、プログラミングという作業がいかなるものであるかというとらえ方も関ってくる。従来的な意味での「テスト」には、プログラミングが「単なる製造工程である」ことを含意していると思われる。つまり、プログラマは単に製品を「製造」するのであり、テスターはそれを単に「試験」するだけなのである。よくある「ブラックボックス」だの「ホワイトボックス」だのは、このような意味でしか語られていない。
しかし、このように製造者と試験者が分離されていれば、そもそもプログラム自体の「設計」がよくなるはずはない。このような状況で「わかりやすいプログラムを書け」と言われても製造者には何のモチベーションも無いのである。テストは試験者に任せてしまうのであり、自らのつくり出した構造がどうであれ知ったことではないのである。
そうではなく、プログラミングとは設計作業であると捉えることである。そして、その設計を良くせざるをえない圧力がTDDなのである。