慣れたころが危ないユニットテスト - 次のステップへ
「慣れてきたころが危ない」とよく言う。自動車の運転では、3ヶ月目と3年目が危ないのだそうだ。僕がかかわっているプロジェクトで、ボクが周囲を押し切ってRSpecを導入して約3ヶ月。繰り返し、書きましょう書きましょうと訴えているだけあって、だんだんとその有効性を認識してもらえつつある。しかし、だからこそ危ないところなのかもしれない。
というわけで、今日は、「慣れたころが危ないユニットテスト」というわけで、ユニットテスト導入からしばらく経ったころの落とし穴と対策をまとめてみたい。
ところで、ユニットテストの弊害について書かれたWebの情報はあまり無いのだけど、テストファーストの弊害が参考になる。
ユニットテストを通り越してテストファーストの話なのでちょっと違うことに注意しつつ読むと、
- 計画性のないテストによって、テストの品質が下がる
- 単体テストが行われず、バグが見逃される
- 効果的でないテストで工数を浪費する
- 読みづらいドキュメントが、修正を妨げる
ということだそうだ。
これを踏まえて、「慣れたころが危ないユニットテスト」の本編に突入。
何が罠か
ボクが思うに、ユニットテストの罠は以下のようなものだ
- テストは「手軽」になるが、「簡単」になったわけではない。そこを勘違いしてしまう。
- カバレッジを優先し、結果・データの検証がおろそかになる
- テストコードが汚くなる(テストコードをきれいに書くという努力をしない)
- 無駄・過剰なテストによって、実行時間がどんどん長くなる
というところだ。
(1)テストは「手軽」になるが、「簡単」になったわけではない
4つ書いたが、結局は(1)が全てを言い表している。ユニットテストをテストとしてきちんと機能させるには、同値分割・境界値分析・表(ディ氏ジョンテーブル・直交表)といったテストの基本的な技術を活用して効率的に質の良いテストコードを記述する必要があるのだ。
もちろん、あまり堅苦しく考えすぎてもユニットテストのよさが失われてしまうが、せめて基礎知識としては欲しいところ。その上で、品質管理の担当者(いれば)が、ユニットテストも含めてレビューすべきでしょう。
(2)結果・データの検証をどこまでやるか?
Webアプリケーションの場合、処理のステータスコードが200であることをチェックして満足してしまうというケースがある(いや、普通は無いのかも知れないけど、不覚にしてうちのプロジェクトには存在するのです)。
また、Webアプリケーションは処理の結果がチェックしづらい(HTMLだから)ので、なおさら効率的なテストを書くことが重要になる。
- 結果に何が含まれていれば十分といえるのか?
- タグの構造までチェックする必要はあるか?
RSpec的に言い換えれば、have_text(/.../)
で済ますか、have_tag("セレクタ")
を使うか、といったところかも知れない。
(3)テストコードが汚くなる
さらに、テストコードなので、本体ほどにコードの美しさに気を使わない、という傾向もある。最悪の場合ソースをコピペしてデータチェックの部分を書き換えて延々と長いテストを生産する、ということにもなりかねない。テストコードといえども、それは本体のコードを映す鏡であり表裏一体なのだ。同じように気を使ってエレガントなコードを書こう。