Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails以外の開発一般

テスト駆動開発(TDD)の利点に関する統計と研究(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。画像は元記事の引用です。

テスト駆動開発(TDD)の利点に関する統計と研究(翻訳)

本記事では、テスト駆動開発(以下TDD)に関するいくつかの統計や研究をレビューします。これは「TDDがどのように採用されてきたか」「TDDのメリットは何か」そして「このアプローチによってチームがどのような困難に直面するか」を理解するためです。

伝統的なソフトウェア開発のプロセスは直線的に進行します。しかし、ここ数十年の間にアジャイルシステムの人気がさらに高まり(87%もの開発チームがアジャイルまたはアジャイル的なアプローチを採用しています)、ソフトウェア開発においてプロジェクトの必要条件や特性を考慮したさまざまな手法が取り入れられるようになってきています。

TDDは、アジャイルソフトウェア開発方面で注目を集めている手法のひとつです。

IEEE(Institute of Electrical and Electronics Engineers)が出版した研究論文のひとつで、著者のYahya RafiqueおよびVojislav Misicが「TDDはエクストリームプログラミング(XP)開発プロセスの基礎に組み込まれるプラクティスのひとつである」と述べています(リファレンス)。

TDDという手法を編み出したとされる人物は2003年に「TDDはシンプルな設計を促進し、自信を高める」と主張したと伝えられています(リファレンス)。しかし、TDDの「生産性」や「品質」に関する主張には疑問が残ります。

この主張をテストすべく、私たちは最新のTDD統計情報の収集にしばらく時間をかけました。

本記事では、最初にTDDの概念と、従来のアプローチとの違いについてそれぞれ定義します。続いて、TDDに関する主張を実証または棄却するいくつかの統計情報について調べます。

TDDとは何か

TDDは、ソフトウェア開発者が「最初にテストを作成し」、それに続いて「テストを満たすproduction向けコードを作成する」というアプローチです。この手法の基本的なアイデアは、コードを書く人物が実際に機能するコードを書く前に、設計や要件を検討するための時間を確保できるようにするというものです。

TDDにおけるコードドリブンテストとリファクタリングの比較

TDDのねらいは、コードを書く人物が実際に機能するコードを書く前に、
設計や要件を検討するための時間を確保できるようにすることです

TDDのプロセス

1. テストを書く
TDDで新しい機能を書くときは、まずテストを作成します。プログラマーは、その機能の仕様や要件を理解しなければなりません。そのために、ユーザーストーリー(訳注: 現在はリンク切れ)やユースケースを詳しく調べて、自分たちが開発する新しいコードの目的を理解する必要があります。
2. テストが失敗する
プログラマーがテストを書き終えたら、テストを実行します。この時点では実装するコードが存在していないので、テストは失敗します。それによって自動テストフレームワークが正常に動作していることを確認し、「テストそのものに不備があるためにテストがパスしてしまう」可能性を排除します。
3. コードを書く
この時点で、プログラマーはその機能が設計どおりに動作することを理解しているので、テストにパスするコードを書きます。ここで書いたコードは不完全かもしれませんし、首尾よくテストにパスするかもしれませんが、そこは重要ではありません。開発者は、作成されたテストでチェックされる機能以外に余分なコードを書かないことが期待されます。
4. テストを実行する
機能が設計どおりに動作することが既にわかっているので、プログラマーが新しいコードをリリースするときはいつでもテスト管理ツールでテストを再実行し、直前に追加した機能によってそれ以前の機能が壊れていないことを検証できるようになります。
5. コードをリファクタリングする
TDDでは、コード量が増加したら定期的にコードをきれいにしなければなりません。プログラマーは上述のステージではコードを書くことだけに集中しましたが、このステージでは効率性を担保します。これによって、ソースコードの外部に対する振る舞いを壊さずに、ソースコードの内部構造を改善できるようになります。このステージでは、コードの重複を削除したり、新しい機能を追加したりできます。
6. 繰り返す
上述のステップは、TDDサイクルがすべての機能をカバーできるよう、自動的に繰り返されます。

TDDと従来の開発手法の違い

TDDを理解するには、プログラミングにおける従来の開発手法との違いを見極めるのが適切でしょう。

主な違いは、従来の手法が直線的に進行するのに対し、TDDでは円運動のように繰り返すことで進行する点です。

従来のテスト手法を用いるプログラマーは、まずコードを書き、テストは開発プロセスの最後になってやっと集中的に見ます。一方TDDモデルに沿う開発者は、まずテストを書き、それからテストが通るコードを書きます。このアプローチにおける原則の多くは、ソフトウェアテストにおけるシフトレフトの動向と共通しています。

訳注: シフトレフトとは開発の早い段階からテストを開始する(テストをスケジュールの左にシフトする)ことを指します。
参考: シフトレフトテスト (Shift Left Testing) で高品質なシステムを迅速にリリース - Qiita

従来のアプローチを用いるプログラマーはコードの正しさに注意を払うことはできますが、コードの欠陥の一部を見落してしまうリスクも伴います。TDDを用いるプログラマーの場合は、コードのリファクタリングでコードがテストにパスするまでコードでの作業を繰り返します。この作業はコードが機能要件を満たすまで続けられ、作業結果のバグが少なくなると見込まれます。

TDDは従来の開発手法より遅いか速いか

TDDによってプログラミング作業が短くなる(つまり速くなる)かどうかを検討してみると、さまざまな情報源で互いに食い違う統計が存在しています。

あるケーススタディはMicrosoftおよびIBMのソフトウェアエンジニアチームがTDD手法を用いたときに「開発初期段階において開発時間の15〜35%の増加を経験した」と結論づけています。しかしこの研究には「数値は管理者によって主観的に見積もられたものである」とも記されています(リファレンス)。

「MicrosoftとIBMの研究では品質が改善されたことが示された」という観点で見れば、長期的には問題の修正に必要な時間をTDDで節約可能であると主張できるでしょう。そしてMicrosoftとIBMのチームはこの見解に同意しました(リファレンス)。

経験豊富なプロ開発者がTDDを用いたときの第一印象に着目した研究では「TDDをいつ開始するか、まだ存在しない機能のテストをどうやって書くかを理解するという初期の困難を克服した後では、テストのカバレッジが広くなったおかげで、参加者が新機能を実装したり変更したりするときの自信が強まった」と結論づけています(リファレンス)。ここで示唆されていると思われるのは「時間とともに改善が進む」ということです。

medioum.comというオンライン出版プラットフォーム向けに執筆しているプログラマーのErick Elliot(「Composing Software」や“Programming JavaScript Applications」の著者)は、TDDによって自分の生活がどのように変わったかに着目しています。Elliotは、初期段階では進捗が遅くなる可能性があることは認めつつも、「2年目になったあたりから何か魔法のようなことが起こり始めた。単体テストを書く速さが、TDDなしで書いていた頃に比べて明らかに速くなり始めたのだ」と述べています。(リファレンス

どうやらTDDを採用すると最初のうちは開発が遅くなる可能性もあるようです。しかし長期的に見れば、コードの品質が向上することで節約できる時間で、初期に失われた時間を埋め合わせられそうです。さらに、プログラマーがTDDに慣れるに連れて開発速度が速くなることも期待できます。

品質が向上するまでに要する時間を測定しようとする場合、この他にも多くの要素を考慮する必要があります。これについて詳しくはNiall LynchのQA Leadポッドキャスト「How To Measure Time To Quality (Time To Quality)」をどうぞ。

TDDでバグは減るか?

上述の議論で述べられているTDDの主なメリットは「バグが減る」というものです。しかし統計ではそうなっているのでしょうか?

MicrosoftとIBMのエンジニアリングチームに関連する同じ研究では「リリース前の4つの製品における欠陥の密度は、TDDを用いなかった同様のプロジェクトと比較して40〜90%減少した」と結論づけています。特にIBMのチームは欠陥密度が40%減少したと報告し、Microsoftのチームは60〜90%減少したと報告しています(リファレンス)。

TDDの統計は「TDDで品質が向上する」を裏付けているか?

2007年にフィンランドで最初に開催されたIEEE国際シンポジウムで発表された研究結果によると、Maria SiniaaltoおよびPekka Abrahamssonが「TDDによるコード品質は非TDDで開発されたソフトウェアよりも高いことが示された」と報告しています(リファレンス)。

SiniaaltoとAbrahamssonが同論文で引用した中国による研究では「TDDはプロセストラッキングとタスク見積もりを改善した」と結論づけています。同じ研究では「TDDは一貫したプラクティスやガイドラインの遵守をも強化する」と結論づけています。つまり品質が向上し、欠陥も減少します。また、TDDを用いたチームは欠陥をより短時間に修正できるようになりました(リファレンス)。

平均でキャリア10年程度のプロ開発者を対象に行われたある研究では、TDDを採用したときの開発者の印象を調査し、開発者の感想を引用しています。曰く「TDDは自分のコードの改善に役立ったし、コードも読みやすくなった」。別の参加者は「TDDはメンテナンス性を高める」と述べています(リファレンス)。

TDDは「シンプルな設計」を促進するか?

ノースカロライナ州立大学のコンピューターサイエンス学科に勤務するBoby GeorgeとLaurie Williamsはある実験を行いました。この実験では、24名のプログラマーを「TDDあり」「直線的なアプローチ」の2つのグループに分けました。

GeorgeとWilliamsは、参加者のうち92%の開発者が「TDDで品質の高いコードを生み出せる」、72%の開発者が「TDDはシンプルな設計を促進する」、71%の開発者が「このアプローチは著しく効率的だ」と思ったと報告しています(リファレンス)。

TDDの品質に関するこれらの統計は、TDDが実際に高品質のコードとよりシンプルな設計をもたらすことを強く示しています。

ある研究では、参加者の79%が「TDDによって設計がよりシンプルになった」と考えました。

Guru99.comという無料学習ポータルで出版された記事によると、Kanchan Kulkarniは「TDDはコードをよりシンプルに、より明快にし、開発者がメンテナンスするドキュメント量も少なくて済む」と述べています(リファレンス)。

TDD設計は採用しやすいか?

GeorgeとWilliamsの実験によると、プロ開発者の56%が「TDDのマインドセットを会得するのに困難を感じる」と信じ、23%のプロ開発者が「困難な理由は事前の設計フェーズを欠いていることだ」と述べていました。回答全体のうち40%がTDDの採用は困難だと信じていました(リファレンス)。

TDDの採用に関するこれらの統計情報は、「TDDは採用しにくい」とみなされていることを示しています。

TDDは過大評価されているか?

Medium.comで公開されたある記事では、Tylor Borgeson(自身を「機械学習/AI/インフラ/DevOps/アジャイルに興味のあるフルスタックソフトウェア開発者」と呼んでいます)が「“TDDは過大評価されている”」という見出しを用いています。しかしこの見出しが引用符に囲まれていることから、これが彼の発言ではないことがわかります。

Borgesonはそれに続けて、TDDは過大評価されているし遅いと主張する人々について「そう考える人たちのほとんどは、TDDを十分な期間実践していない」と述べています。同記事の末尾では「今すぐTDDを実践することだ、TDDがつらくなくなるまで」と締めくくっています(リファレンス)。

次に読むもの

The QA Lead podcastでプロのQAアプローチを学びましょう。

QA Leadニュースレターにサインアップして最新のポッドキャストエピソードを取得しましょう。

QA Leadのオンラインコミュニティフォーラムのウェイトリストに参加して、QAのプロやソフトウェアテストのプロのベストプラクティスを共有しましょう。

ではフォーラムで皆さんとお会いできますように!

関連記事

ペアプロを極めて最強の開発チームをつくる(1/4)ペアの組み方(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。