俺ってばスゲー、TDDもスゲーと思ってから、はい、TDDの壁にはぶつかりました。「テスト駆動でできるところと、できないところがあると認識しなければならないところ」ですね。簡単に言うと、GUIを伴うテスト、画面を伴うテストっていうのは、すごく難しい。というより、割りに合わない感じが強いんですね。これは今でもそうです。
「テスト熱中症」「テスト厨」
テスト駆動開発をマスターするきっかけをつかんで、これはイケる! これは素敵だ!と思った人が次に出会うのは、「テスト熱中症」「テスト厨」時代です。テストがすごく好きになり、テストに熱中する時期がやってくるんですね。
テスト熱中症(test infected)と言ったり、テスト厨って言ったりしてるんですけど、とにかくテストが書きたくなるんです。「何に対してもテストが書けるんじゃないだろうか、これもテスト書きたい! あれもテスト書きたい!」というような具合で、開発を進めるためのテストというよりも、「これに対するテストはどう書けるかな」というような視点で熱中するような時期です。
この時期には、何にでもテストを書くべきなのではないか(原理主義的)とか、こういう状況だったらどうテストできるか(手段の目的化)とか、そういった視点でテストを書いてしまいがちです。このテストは割りに合うか合わないかとか、資産価値が高いか高くないかっていう視点がまだ得られていないんです(注)。
テストが大好きになって、なんに対してもテストを書いている時代は幸せですが、ほどなく壁にぶつかることになります。その壁は、たとえばGUI、たとえばデータベースに対するテストです。
データベースに対するテスト
データベースに対するテストでは、テストを動かすたびにデータベースの中身が変わってしまって、あるときグリーンだったテストが、次の実行時にはレッドになってしまうなど、うまく書かないと運用できないテストというものが出てきます。テスト同士が暗黙の依存関係を持ってしまう確率が増えるのです。
そういった壁にぶつかったときには、これまでのテストの進め方から一歩引いて、ツールを探し始めてみるのはどうでしょうか。
たとえばデータベースのテストでしたら、テストが始まる時点で毎回全部新しくデータを洗い変えてからテストを実行するツールがあります。毎回同じデータに対してテストするのですから、他のテストの実行に左右されず、絶対にグリーンバーになりますよね。
他にも、テストが開始される時点でトランザクションを始めて、テストが終わったら全部ロールバックさせるツールもあります。テストをトランザクションで包むので、中で何をしても自由というわけです。
テストデータベースをキレイにすることで、テストが何回動いても同じように成功するためのしくみが、すでにいろんなところに存在しているわけですね。有名なところでは、Javaの世界ではDBUnitですとか、Seasarのテストのしくみなどがあります。
そういったしくみとかテストフレームワークを新たに学んでいくことによって、実行の難しかったテストを、だんだんともう少し気軽に行えるようになってきます。
GUIのテスト
GUIの話で言えば、要するにGUIをテストすべきなのかどうなのか、本当にGUIをテストしなければならないのか、という話になります。
GUIのテストには次のような問題があります。
- そもそも画面仕様は変わりやすいため、テストの資産価値が低い
- GUIのコードは複雑になりやすく、テストしにくい
- そもそもユーザビリティや画面のデザインは、テストできないか、できるとしても非常に難しく、テストにかけたコストに見合わないことが考えられる
まとめると「GUIコードの自動テストは難しく、コストがかかる割には資産価値が低い」ということです。
ではテストしなければならないところ、たとえばロジック部分はもっと画面から分離して単独でテストできるようにして、画面は目視でテストすればいいのではないか、と考えてみます。
GUIのコード部分はテストしなければならないロジック部分を極力薄くし、自動テスト(機械)はロジックのテストを、人間は人間でないとテストできないこと、つまり使いやすさ、色合い、レイアウト、反応性などをテストすればいいのではないか、と考えます。
テストコードを書くことが割りに合わない部分は人間が行い、割りに合う部分、テストの資産価値がある部分のテストコードを書いていけばいいという視点が得られるようになってきて、ようやく、また一つ壁を越えられたんです。
割りに合うかどうか、資産になるかどうかの視点を持つことで、「すべてをテストしなきゃいけないという強迫観念」から、だんだんと自由になっていくことができると思います。