テストを書かないと品質はやっぱり下がる

私は今だにxUnitに代表される自動テストツールの効果が今ひとつ腑に落ちていなかったのですが、プロジェクトメンバーがその効果を調査・分析・見える化してくれたおかげですっきりしました。私の中だけに留めておくのはもったいないのでエッセンスを公開します。*1
対象プロジェクトに関する情報は以下の通りです。

  • 業務系
  • 画面数は60程度
  • 帳票数は15程度
  • Java(Seasar2/S2Struts/S2Dao),Web系
  • クラス数は750程度
  • 開発期間は約半年
  • 最終的には総じて高い品質を実現した

テストツールとしては、JUnit/EZmock/S2TestCaseを使っていて、それぞれ対象となるレイヤは、Actionクラス/Serviceクラス/Daoクラスです。画面のテストにはSeleniumも使いましたが、今回の調査の対象外としています。

目的

テストで重要なのは、要はそれぞれの工程で適切な粒度・観点でのテストを終わらせることであり、単体レベルの問題が、ユーザー受け入れテストなどで発生してはよろしくありません。今回の調査の目的は、結合・システム・受け入れテストで発見された問題のうち、単体レベルで発見できたはずのものはどれくらいであり、さらにその数を減らすにはどのような取り組みが効果的かを調べる、ということです。

ほとんどの問題は単体テストで発見できる

問題の内容を精査すると、96%は、単体テスト(xUnit/Selenium/目視)によって発見できる内容でした。また、そのうちxUnitにて発見できたであろう問題は30%程度ありました。
これはプロジェクトの個性によってある程度ブレ幅があるかとは思いますが、テストツールが充実している昨今、かなりの部分は自動テスト可能だということです。

Actionクラスのテストが盲点となりがち

対象としたプロジェクトの開始時点の取り決めとして、「Actionクラスのテストは原則不要」というものがありました。特にS2Strutsを使った開発では、Actionクラスにロジックは持たないことが多いからです。
しかし、プロジェクト終わってみると、なんだかんだでActionにロジックが持ち込まれており、結果的にDao、Serviceレイヤに比べると3倍のバグが発生しました(DaoとServiceは同数)。Actionクラスの振る舞いの確認は目視で行ったのですが、やはり漏れが発生したようです。

カバレッジ率の目標は90%

Serviceレイヤではカバレッジ率に注目しています。次のグラフは、縦軸に分岐網羅率(branch)、横軸に行網羅率(line)を取っており、赤丸が付いたところが問題が発見されたクラスです。

当たり前の話かもしれませんが、カバレッジ率が低いクラスには確実に問題が残ります。今回のプロジェクトでは、最低でもカバレッジ率は90%は欲しかったところです。(もちろん、目標は100%なんですがね)

Daoのテストは苦しくてもがんばる

最後にDaoレイヤです。S2TestCaseはExcelにテストデータを書いてテストできるのですが、全てのパターンのテストを書くのは結構しんどいときがあるそうです。しかし、Daoレイヤでの問題を分析すると、以下の原因によって漏れてしまうことがあったようです。

  1. SQLのWhere節に対して十分なテストがない
  2. 追加したカラムに対するテストがない

SQLの場合カバレッジを計測するのが難しく、上記いずれの場合も根気強くテストを書き続け、きっちりTDDするしかありません。業務系のシステムではデータベース処理がロジックの中心となることが多く、Daoテストの質が全体の品質に影響を与えがちです。

まとめ

テストがないと品質が下がる。当たり前の話ですが、それが数値という目に見える形で改めて実感できました。調査対象が1プロジェクトしかないのですが、今後サンプル数を増やしていけば、組織全体の傾向がよりはっきりしますし、何よりも続けることによって改善が見える化されるのが大きいです。私も次のプロジェクトではActionクラスのテストを書くか、Actionには完全にロジックを持たない、いずれかの作戦でいくつもりです。
プロジェクトが成功に終わっても、そこから学ばないのはもったいないです。事実を集め、そこから課題と教訓を導き出し、次に繋げましょう。

*1:長岡さんありがとう。この場を借りてお礼します。