TDDはシンプルな原則やルールで構成されます。運用では実践者の裁量に依存する部分が多いですし、応用の余地も小さくありません。そのためTDDが普及するに従って、TDDをよりよく活用するための工夫やノウハウが蓄積されていきました。
今回は、その工夫やノウハウの一つとして、ユーザー価値や上位設計とTDDをつなげる手法を紹介します。
プログラミング手法としてのTDDでは、クラスや関数といったコンポーネント単位の粒度でテストファーストのサイクルを回していくスタイルが一般的です。そのスタイルでは、以下のようなアプローチがしばしば採られることになります(このアプローチは、後述するアウトサイドインTDDと対比して、「インサイドアウトTDD」と呼ばれます)。
このTDDでありがちなインサイドアウトのアプローチについては、Mockオブジェクトの使用の手間が省ける、プログラマー主体の柔軟な設計の作り込みに対応できるといったメリットを持っています。
ただ一方で、これに対して主に2つの批判がなされています。1つはアーキテクチャ設計やコンポーネントセットの設計といった、より大きな設計の全体整合を保証しにくくなること、もう1つはユーザー要求やアーキテクチャ設計といった上位のインプットと、TDDのプログラミングが断絶することです。
こうした問題は、設計品質の問題で開発の手戻りコストや保守コストを悪化させる、またユーザーへの価値の実現というテストファーストの当初の目的を欠落させるといった課題を発生させてきました。
そこでTDDのアプローチとして以下を行う手法が確立されました。
このアプローチは包括的な外側の「振る舞い」をテストで記述した後、内側の個々のコンポーネントを実装していくという方向性から、「アウトサイドインTDD」と呼ばれます(プログラミングのドメインに限った場合、人によってはアウトサイドインTDDを「モック派」と呼び、前述のインサイドアウトTDDを「古典派」と呼ぶ場合もあります)。
アウトサイドインTDDが重視するのは、「良いソフトウェアを作るために、TDDでの実装対象はどのような振る舞いをするべきか」という要求を明確化することと、それをテストで記述し、そのテストで開発を駆動させていくことです。この実践で、TDDにおいて全体整合の取れた設計を実現する他、不適切なテストで不適切に開発が駆動される流れを防止します。
注意として、アウトサイドインTDDはメリットだけではなく、対応すべき課題を持っています。
例えば、アウトサイドインTDDではモックを多用するため、TDDのテンポを阻害しない軽快さでモックやエクスペクテーションを記述できるモックライブラリや開発環境を必要とします。
また変化に対応でき、品質の高い設計を実現する技量がないと、アウトサイドインは厳格に要求仕様化を行い、厳格に基本設計・詳細設計を行って、詳細仕様の通りにTDDを進めるというウォーターフォール的なアプローチになりがちです。そうなってしまうと、アジャイルやTDDのメリットを目減りさせることになります。
なお2000年代後半に、「JMock」の開発者であるSteve Freeman氏が、変化に対応するためのオブジェクト指向設計のノウハウを基礎にアウトサイドインTDDを展開するアプローチを書籍『Growing Object-Oriented Software Guided by Tests』(邦題『実践テスト駆動開発〜テストに導かれてオブジェクト指向ソフトウェアを育てる』翔泳社刊)にまとめています。
この本は国内のTDDコミュニティで、『Test Driven Development By Example』に続く「TDDの第2のバイブル」と位置付けられています。
またアウトサイドインTDDでカバーできないさらに上位のテストレベルとのつながりを明確化するために、「テストファーストのダブルループ」というアプローチが考案されました(参考『Growing Object-Oriented Software Guided by Tests』)。
これは「End-To-Endテスト」(システムテスト)の自動化環境と、単体テストの自動化環境を構築し、両方でテストファーストを回していくアプローチです。具体的には、以下の手順を採ります。
これはアウトサイドインTDDと相性が良いアプローチです。End-To-Endテストのテストファーストでユーザーの要求レベルからアーキテクチャ設計レベルまでのブレークダウンをサポートします。アウトサイドインTDDでアーキテクチャ設計レベルから、コンポーネント設計レベルまで仕様・振る舞いをブレークダウンすることを可能にすることで、ユーザーの要求から実装までをテストファーストで駆動できるようになります。
TDDの普及は、他のテストファースト手法にも影響を与えています。例えば、TDDにおいて明確にされたテストファーストのメリットや問題対策を他領域に展開しようとする動き、TDDの運用を通じて整備が進んだテスト自動化環境の活用などです。
次ページでは、TDDが影響を与えた開発手法の代表例である、BDDを紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.