TDDの効果の研究をまとめた研究

TDDに関連する論文をいろいろ探し回っていたのですが、今年(2013年)に書かれた、既存のTDD研究をまとめて全体像を描こうとしている研究を見つけ、しかも無料で公開されているので、紹介したいと思います。

以下のように書いてあるので、学会(?)発表用のものであって、雑誌に載ったわけではないのかな(アカデミックな話はよくわからない。査読があるかどうかが重要なんだっけ)。

This is the author's version of the work. The definite version was published in Proceedings of the 6th International Conference Software Quality Days (SWQD 2014), Vienna, Austria, January 14-16, 2014

"Effects of Test-Driven Development: A Comparative Analysis of Empirical Studies" Simo Makinen and Jurgen Munch

論文はこちらで公開されていて、PDF版を読めます。

内容について誤解や勘違いをしている部分もあるかもしれません。ご了承ください。

今回はいきなり研究の結論から。アブストラクトの抜粋と、結果のグラフを出してみます。

  • 既存の実証研究を調査し、10の内部・外部品質評価項目で、各研究の結論を整理した
  • TDDは欠陥の作り込み(introduced defects)を減らし、メンテナンスしやすいコードを産む
  • TDDで実装されたコードは、部分的に、サイズが小さく、複雑度が低い場合がある
  • メンテナンスがしやすくなるものの、初期開発では時間がかかる


10項目について、TDDの効果を結論づけている研究の数を、良い効果、悪い効果、効果なし・結論できないの3つにわけて表示しています。示されているのはあくまで研究の数であって、効果の大きさではないので気をつけてください。また対象の研究は幅広いコンテキストがあり、このグラフは単純な合計でしかない点にも注意してください。

単に良い効果と悪い効果を比べるだけでなく、効果なしの数にも着目すると、たとえばサイズは良い効果がでているようですが、ほとんどの研究で効果なしとされていることもわかります。

以下では、この結果をどうやって出したか、どう評価しているかをまとめていきます。また特に注目すべき発見もいくつか紹介しています。

先行研究

先行する研究として、Making Software (O'Reilly)に掲載されている "How Effective is Test-Driven Development" では、同様に既存の研究を調査して、TDDの効果を内部品質、外部品質、テスト品質、生産性の4つの評価項目に整理しています。

他にも複数の同様の研究があり、工数(effort)の増加を示すもの、外部品質の改善を示すものがあります。また、実開発(industry)を対象に調査したものと、アカデミックな実験(academic)とで、TDDの効果に大きな差が見られたと報告する研究もあります。

そうした先行する研究を踏まえ、この論文ではTDDの効果を計るため10項目を対象として、既存の実証研究を調べています。

研究の手法

この研究ではintegrative literature reviewの方式で、「test driven development」「test first programming」などを論文データベースで検索し、手作業で絞り込んだ論文を調査対象としています。対象はすべて、TDDとそれ以外の手法を比較した実証研究です。最終的に19の論文を調査しています(論文の一覧は、PDF版のTable1にあります)。

個々の論文が、TDDの効果をどう評価しているか、以下の10項目に分類しています。

  • 欠陥の密度や量 (amount and density of defects)
  • コードカバレッジ (code coverage)
  • コードの複雑度 (code complexity)
  • 結合度 (coupling)
  • 凝集度 (cohesion)
  • サイズ (size)
  • 工数 (effort)
  • 外部品質 (external quality)
  • 生産性 (productivity)
  • メンテナンス性 (maintainability)

論文によっては言及していない項目もあるし、意味ある結果が得られていないとしているものもあります。19論文で合計73の項目ごとの評価をしていますが、そのうち有意な差があるとしているのは21だけです(12の良い効果、9の悪い効果)。

欠陥の密度や量

IBMMicrosoftを対象とした研究では、TDDによって欠陥が減らせる大きな効果があったと報告しています。いっぽう、実開発をともなわない実験では、そこまで大きな効果が見られません。実験の中には、TDDよりコードレビューの方が効果が高いとしたものもあります。

コードカバレッジ

TDDでは高いコードカバレッジが得られます。実装の後にテストを書くアプローチではカバレッジが比較的低くなりがちですが、TDD経験者であれば、テストが後でも比較的高いカバレッジを達成できるという研究もあります。

TDDによってカバレッジが高くても、ミューテーションテスティングの成績はTDDのほうが低く、かならずしも品質が高いとは限らないとしている研究もあります。

コードの複雑度

複雑度はTDDのほうが低い傾向は見られるものの、はっきりした結論が出ていないものもあります。

結合度と凝集度

結合度や凝集度を調査した論文は少なく、結論もTDDが特に優れているとは言えません。結合度はTDDのほうが大きい(悪い)という論文があります。凝集度は良い場合も悪い場合もあるという論文があります。

サイズ

TDDに限らず、ユニットテストを書くと、プロダクトコードとテストコードを合わせた全体のサイズは増えます。プロダクトコードに対するテストコードの量(テストコード行数/プロダクトコード行数)は、TDDでは0.39〜0.89、0.48前後などとされており、TDDを使わないとより低い(テスト行数が少ない)傾向があります。

プロダクトコードのクラスやメソッドの大きさは、TDDでは小さくなる場合も見られますが、はっきりした傾向は見られません。

工数

TDDを使うと開発の工数が増えると、多くの研究が示しています。対象の期間はいろいろで、開発だけを見ているもの、6ヶ月のプロジェクト全体を見ているもの、テスト作業を見ているものもあります。

論文のひとつは、初期開発とリリースの後で、TDDのほうが生産性が良かったと報告しています。6ヶ月の初期開発に対し、9ヶ月のメンテナンス期間を観察し、メンテナンス期間ではTDDを利用したチームの方が開発が容易で時間も短かったものの、観察期間の合計ではまだ数千人時の工数ぶん遅れていました。

外部品質

外部品質は、アンケートやインタビューでデータを集める形で評価しています。顧客にインタビューした研究では、TDDと非TDDで差異は見られませんでした。

開発者にアンケートした研究では、TDDでコードの品質が高まるという結果を得ました。また学生にアンケートした研究では、テストしやすくなるものの、システム全体の設計に自信が持てないという結果を得ました。

生産性

生産性は、同じユーザーストーリーを開発するのにどのくらいの時間がかかるかという観点と、コード1行当たりにかかる時間という観点で評価しています。TDDのほうが生産性が低いという結果も、変わらないという結果もあります。生産性が高い傾向を見せたものもありますが、有意差はありませんでした。

コード1行当たりの時間では、テストコードのほうがプロダクトコードより早く書けている(最大3倍)という研究もあります。

メンテナンス性

メンテナンス性を測定している研究はひとつしかありません。工数の項目で述べたように、初期開発後のメンテナンスではTDDを使ったチームの方が少ない工数で開発できました。

結論

19の研究を調査した結果、欠陥の減少とメンテナンス性の向上がTDDの効果として期待できると言えます。TDDでは全体コードサイズが増えますが、コードカバレッジはよくなります。

今後の研究として、メンテナンス性の効果に着目するという方向性が考えられます。

感想

最近(2003〜2012だけど、半数は2008以降)の論文のサマリを知れました。誰でも納得がいくような結果(欠陥と工数)は揺るぎなく証明できていると言えるように思います。それ以外の項目については、大いにコンテキストに依存している話なので、掘り下げないとわからないようです。

率直に言って、実証研究と統計手法でTDDの効果を証明するのはしんどいですね。これだけ調べて、欠陥は減る、工数は増える、あとは微妙という話しかできないとは。研究ってそんなもんなのかもしれませんけど。

各評価項目が個別の話になっていくので、読んでまとめるのにだいぶ疲れました。面白い発見もあったので、19の論文をぜんぶ読むのに比べれば、その点では良かったです。

そう言えばサイズのところで、テストコード行数÷プロダクトコード行数が、

  • 0.39〜0.89 (Microsoft)
  • 0.48前後 (IBM)
  • 学生を対象とした実験で、1人だけTDDを使わず1.0より大きい

と書いてあって、そんなにテスト行数少ないの?2倍くらい行かない??と思いました。