既存コードにテストコードを書くなら、どこから始めるのが効率的か?
"Prioritizing Unit Test Creation for Test-Driven Maintenance of Legacy
Systems"というタイトルの論文。10th International Conference on Quality SoftwareでEmad Shihab, Zhen Ming Jiang, Bram Adams, Ahmed E. Hassan , Robert Bowermanにより発表された論文の内容。以前に意見交換したときにShihab氏に教えてもらったのだが、発表が済み、公開されたのでエントリにした。
論文のPDFがここで公開されている。
テストコードがない既存のソースコードにテストコードを追加する際に、どこからテストコードを書いていくのが効率的かを長期にわたってメンテナンスされている商用ソフトウェアを対象としてシミュレーションしている。テストコードを書くという点ではTDD(Test Driven Development)に似ているため、彼らはTDM(Test Driven Maintenance)と呼んでいる。プラクティカルな内容といえる。
対象ソースコードは、5年以上保守され、1万モジュール、5万回の修正、数百万行のコード。実際にテストコードを書いたわけではなく、開発半年後以降のある時点で仮にテストコードを書いていたとして、以降、同じ部分から不具合が検出されていれば、そのテストコードに価値があったと判断する。これをUsefulnesという評価尺度として定義している。また、ある時点から収集しているデータの範囲内の未来において、全てのバグがどこから検出されるかがわかっている場合と比較した場合の的中率を、percentage of optimal performanceとして定義している。
シミュレーションには、次の方法で10個のメソッド/関数を選び、テストコードを書いたとして、上述の評価尺度を算出している。いずれもランダムに選ぶよりも高い値が出ている。
- 変更頻度の高い順
- 変更時期が近い順
- 過去の発見不具合が多い順
- 不具合の発見時期が近い順
- 変更規模が大きい順
- 不具合修正による変更規模が大きい順
- これまでの不具合修正による修正規模(コード行数)の割合が大きい順(対象モジュールのみ)
- 7と同じだが、割合の算出に対象モジュールではなく、修正により変更した全行数を使っている。
ご自身の開発にあてはめてみると、どれがもっとも効率的になりそうだろうか?
シミュレーションと論文でのデータでは、usefulness, percentage of optimal performanceとも6, 5, 3, 1の順でシミュレーション結果がよくなっている。ランダムに選んでテストコードを書いた場合、usefulnessが27.7%、percentage of optimal performanceが1.7%であるのに対して、上述4つはいずれもusefulnessが80%以上、percentage of optimal performanceが20%以上となっている。(評価尺度は複数のシミュレーションの中央値)
ここ(本ブログの過去エントリ)でも書いたが、この結果で重要なのは、6, 5, 3, 1という順番ではなく、ランダムに選んだ場合よりも、非常に効率が高くなる可能性があることだ。過去のデータがあれば、これくらいの精度で予測ができる可能性があることを認識すべきだ。論文には、対象ソフトウェアの特徴等は詳しく書かれていないので、ご自身のソースコードでも同様にモデルを作るほうが予測精度は高まるだろう。
論文の著者のShihab氏やHassan氏は去年、今年に奈良先端科学技術大学院大学ソフトウェア工学講座を訪問し、意見交換している。私は今年の冬にこの論文の話を聞かせてもらい、非常に興味深いと感じた。