TDD-アウトサイドインとインサイドアウト


53

アプリケーションをOutside Inで構築することとTDDを使用してInside Outで構築することの違いは何ですか?

これらはTDDとユニットテストについて読んだ本です:
テスト駆動開発:例による
テスト駆動開発:実用ガイド:実用ガイドMicrosoftでの
高品質PHPフレームワークとアプリケーションの開発のための実世界ソリューション
NET
xUnitテストパターン:テストコード
リファクタリングユニットテストの技術:.Net
Growing Object-Oriented Softwareでの例、テストによるガイド ---> JAVAは私の主要言語ではないため、これを理解するのは非常に困難でした:)

それらのほぼすべてがTDDの基本と単体テストを一般的に説明しましたが、アプリケーションを構築するさまざまな方法についてはほとんど言及しませんでした。

もう1つ気づいたのは、これらの書籍のほとんど(すべてではないにしても)が、アプリケーションの作成時に設計段階を無視していることです。彼らは、テストケースを迅速に記述し、設計を単独で出現させることに重点を置いています。

しかし、私は人々がTDDにアプローチする方法を議論したxUnitテストパターンのパラグラフに出会いました。Outside InInside Outの 2つの学校があります。

悲しいことに、この本はこの点について詳しく説明していません。これら2つのケースの主な違いは何かを知りたいです。
それらのそれぞれをいつ使用する必要がありますか?
握りやすいTDD初心者には?
各方法の欠点は何ですか?
このトピックを具体的に説明している資料はありますか?


2つのアプローチはxUnitのテストパターンサイトに記載されている:xunitpatterns.com/Philosophy%20Of%20Test%20Automation.html。彼らが本に載っていないのは奇妙だ。
-guillaume31

回答:


45

インサイドアウトとアウトサイドインはかなりまれな用語で、クラシックスクールロンドンスクールについてよく耳にします。

  • インサイドアウト(クラシックスクール、ボトムアップ):コンポーネント/クラスレベル(インサイド)で開始し、要件にテストを追加します。(リファクタリングにより)コードが進化すると、新しいコラボレーター、インタラクション、およびその他のコンポーネントが表示されます。TDDは設計を完全にガイドします。

  • アウトサイドイン(ロンドンの学校、トップダウン、または「モックストTDD」と呼ばれるMartin Fowler):相互作用と共同作業者(特にトップレベルの)を前もって知っており、そこから始め(トップレベル)、必要な依存関係をあざけります。完成したすべてのコンポーネントを使用して、以前にモックされたコラボレーターに移動し、そこでTDDを再び使用して、実際の実装を作成します(使用されていても、抽象化のおかげで以前は必要ありませんでした)。外部からのアプローチは、YAGNIの原則とうまく合うことに注意してください。

どちらのアプローチも唯一のものでありません。彼らはあなたが何をするかに応じて両方の場所を持っています。大規模なエンタープライズソリューションでは、設計の一部がアーキテクトに由来する(または前もって存在する)場合、「ロンドンスタイル」アプローチから始めることができます。一方、コードがどのように見えるべきか(またはシステムの他の部分にどのように適合するべきか)がわからない状況に直面した場合、ローエンドコンポーネントから始めて、それを許可する方が簡単かもしれません。より多くのテスト、リファクタリング、要件が導入されるにつれて進化します。

どちらを使用する場合でも、多くの場合、状況に応じて異なります。

さらに読むには、この区別がどのように生じたのか、なぜロンドンが最も適切な名前ではないのかについて、かなり興味深い議論をしたGoogleグループの投稿があります。


2
面白い。TDDの外部は「モック主義者」TDDであるという結論に達しましたか?私は、Outside-Inの考え方と設計、したがってテスト(softwareonastring.com/2015/01/10/…を参照)を非常に好んでいます。モック主義者は常にアウトサイドインのアプローチを使用するかもしれませんが、それを好転させて、アウトサイドインの設計とテストモックストTDDであると言うことはできません。アウトサイドインは、古典主義者のTDD-ersでも可能であり、非常に実践されています。
マルジャンヴェネ

@jimmy_keen-アウトサイドインでは、より高いレベルのテストのモックを、後で作成された実際の実装に置き換えますか?または、それらをモックされた依存関係として残し、統合テストとして本番コード全体を実行しますか?
thehowler

1
Classic / MockistとInside-Out / Outside-Inが関連していることに同意しません。それらは直交しています。Inside-Out / Outside-Inはどちらでも使用できます。
ダニエルカプラン

ダニエルに同意します。異なる2つの分類法を例えています。アウトサイドイン開発は、多くの場合ロンドン(モック主義者)学校に関連していますが、常にそうであるとは限りません。
-guillaume31

これはアウトサイドインプロセスの正しい説明ではないと思います。それは、可能な限り内部に結合せずに、パブリックインターフェイスからテストすることです。
mcintyre321

15

短い答え:いつものように、コーディングの好みとチームのアプローチに依存します。

裏返しあなたが常に働いて何かを持っているので、コーディングは素晴らしいです。欠点は、必ずしも根本的に異なる場所に行くのに役立つとは限らないことです。この方法でコースをチャート化することは困難です。同様に、外部でコードを書くことは、必ずしも迅速な反復開発の恩恵を享受できず、必ずしもコードの構造の深部から生じる可能性のあるすべての機会とパターンを見ることができないという欠点があります。

開発の両方のスタイルが重要であると信じるようになりました。実際、チームでスタイルを混在させることは有益です。アイデアは、裏返しがビルディングブロックの作成に最適であり、思考の外側がフォームの構造と方向性を提供するというものです。

私の推論の一部は、現在、繰り返し開発を促進している非常に人気のある考え方から来ています。これは、インサイドアウト開発と同義です。私は、反復的な開発は偉大であると考えているあなたはあまりにも遠くに行く必要はありませんとき。しかし、純粋に反復的なプロセスとは対照的に、全体像を考えることは、特定のタイプのイノベーションや、それほど明白ではない場所にたどり着くには非常に貴重だと思います。適切に管理され、インサイドアウトとアウトサイドインが非常に効果的な組み合わせになります。


8

そのリストに、C#のアジャイルの原則、パターン、およびプラクティスを追加する必要があります。彼が最後に「C#で」に取り組む理由はわかりません。本はまったく言語ではなく、アマゾンで5つ星を獲得できなかった唯一の理由は、彼の例のC#ネスに失望した人々からです。

著者は、可能な限りコードを外部から記述し、進化的設計に大きく依存するようにすべきだと主張し、私は彼の声明に同意します。彼の推論は、機能を追加すると、デザインは常に進化するということです。機能が追加されたときに低レベルのコンポーネントから始めると、それらのコンポーネントが望んでいることをしていないか、物事を移動する必要があることがわかります。特に、あるクラスから別のクラスに機能を移動するたびに、すべての単体テストプロジェクトで同じ移動を行う必要がある場合、これはかなり高価になる可能性があります。

一方、そもそもアプリケーションの動作を決定する場合は、外部インターフェイス用にコーディングします。機能が追加され、テスト対象コードのサイズが大きくなると、アプリケーションをより多くのクラスにリファクタリングしますが、このリファクタリング作業が進行している間、作成した元の単体テストは有効なままです。したがって、完全に外部から開始し、内部クラスに追加の単体テストを追加しながら、ますます低レベルのクラスにリファクタリングを続けますが、単体テストを移動して書き直す必要はほとんどありません。

ただし、アプリケーションが必要とする特定の低レベルのサブシステムを特定する場合(そしておそらくあなたの会社は他のアプリケーションでそのようなサブシステムを既に必要としている場合)、これは最初に低レベルのビルディングブロックで開始し、次にその上にアプリをビルドします。


7

ご覧のとおり、Outside-in開発の概念は2つのレベルに広がっています。Gerard Meszarosはそれらを「外部インデザイン」および「外部イン/内部アウトコーディング」と簡単に説明しています。

  • 最初のレベルは、組織レベルおよびプロセスレベルです。アウトサイドインデザインは、トップダウン(ウォーターフォール/テイロリスト)およびボトムアップとは対照的です。アウトサイドインアプローチでは、エンドユーザーの視点に焦点を当てます。ストーリーテスト、ATDDまたはBDDテストから始め、技術的なテストとコードを「内向き」に推測します。したがって、通常、外部から内部への設計は、アジャイルコンテキストで行うことです。ダン・ノースは、BDD、トップダウン、ボトムアップ、アウトサイドインのアプローチについて素晴らしい講演をしています。

  • 2番目のレベルは技術的であり、適用可能なレイヤーに関係しています。アウトサイドインコーディングとは、基本的にUIから始まり、中央のレイヤー(通常はビジネス/ドメインレイヤー)に進むことを意味します。これは、中央層から開始して最後に外部層をコーディングするインサイドアウトコーディングとは対照的です。

したがって、アウトサイドインコーディングまたはインサイドアウトコーディングのどちらかを使用したアウトサイドインデザインを作成できます。

Meszarosに反対するのは、インサイドアウトコーディングをインテグレーションテストと関連付け、インサイドアウトのコンテキストで「内側のソフトウェアを隔離して外側のソフトウェアを実際にテストすることはない」と主張するときです。しかし、それを妨げるものは何もないと思います。それらの量産コードが既に存在する場合でも、内側の層オブジェクトをモックアウトすることにより、外側の層オブジェクトをテストすることを完全に選択できます。インターフェースを記述し、それらをモックしてから実装を後で作成するのではなく、既存の具象オブジェクトの上にインターフェースとモックを追加するだけで、アウトサイドインコーディングのようになります。

言い換えれば、モック主義者または古典主義者のスタイルのTDDは、IMOのアウトサイドイン/インサイドアウトのコーディングに対する直交的な関心事です。インサイドアウトのアプローチと共に、モックストスタイルを完全に使用できます。この背後にある理由は、mockist / classicistスタイルはコードの依存関係に関するものであり、outside-in / inside-outコーディングはアプリケーションに関するものであるためです。

もう1つの重要なことは、依存関係はレイヤー間だけでなく、同じレイヤー内のオブジェクト間にも存在するということです。たとえば、中央のビジネスレイヤーの1つのオブジェクト(インサイドアウトアプローチ)で開始し、モックを使用して、通信する他のビジネスレイヤーオブジェクトからオブジェクトを分離することができます。これはIoCで頻繁に発生します。オブジェクトが依存する抽象化は多くの場合同じレイヤーで宣言されますが、具体的な実装は異なるレイヤーで行われます。

Robert "Uncle Bob" Martinは、インサイドアウトコーディングについて簡単に言及し、「Clean Architecture」の記事で、分離されたアーキテクチャと必ずしも競合しないことを説明しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.