自動テストと実行可能な仕様は、テスト可能なアーキテクチャを持つソフトウェアでのみ機能します。テスト可能なアーキテクチャは、記述、実行、および保守が容易な、高速で信頼性の高いテストを可能にします。

迅速なフィードバック

高速なテストにより、開発者はテストを頻繁に実行して、フォーカスやフローを失うことなく、構築しているものに関する迅速なフィードバックを得ることができます。

テスト容易性

テスト容易性を考慮した設計を行う場合は、製品とサービスが疎結合で適切にカプセル化されたコンポーネントまたはモジュールで構成されていることを確認してください。

ビジネスロジックをインフラストラクチャ (多くの場合、低速で脆弱なコンポーネント) から分離することで、さまざまなレベルで最大限の信頼性と最小限のコストでテストすることが可能になります。

  • ユーザーインターフェース (UI) を介さずにテストを実行できることを確認してください。UIテストは、低速で、脆く、高価で、修正が困難です。UIテストのみに依存しないでください。
  • データベースに対してテストを実行すると、テストが遅くなります。テストの動作に一貫性を持たせるためには、各テストの前にデータベースが予期される状態にあることを確認する必要があります。これにより、テストが互いに干渉することなく、任意の順序で実行できるようになります。

ほとんどのテストでは、実際のデータベースではなく、何らかのインメモリスタブ実装を使用することをお勧めします。ドメインロジックの観点からは、動作はまったく同じに見えます。スタブが実際の動作と同じように動作することを確認するために、信頼性が必要です。これは、コントラクトテストを使用して得ることができます。

ポートとアダプター

データベースとスタブは、**ポート**に接続できる2つのものと考えることができます。ビジネスロジックを含むアプリケーションは、スタブと通信しているのか、実際のデータベースと通信しているのかを知る必要はありません。これは、このポートと通信してデータを保存および取得しているためです。スタブと実際の実装の両方を使用してテストを実行できます。これにより、スタブが実際の動作と同じように動作するという自信が得られます。

ビジネスロジックはアプリケーションの中核にあり、外部デバイスやサービスから完全に分離されています。データベース、メッセージキュー、またはWebサービスについては何も知りません。これは、これらのポートを介して分離されているためです。多くの場合、これらのポートは、実際の実装と対話するアダプターに接続されています。データベース用アダプター、キュー用アダプター、Webサービス用アダプターがあります。ユーザーインターフェイスは、システムとどのように対話できるかを定義します。また、ブラウザにUIを表示するためにポートに接続するWebサーバーなど、アダプターも備えています。すべてのIOは、これらのポートの外部で行われる傾向があります。ポートを介してコアビジネスロジックを直接テストすることにより、多くの低速で脆弱なIOを排除できます。

このアーキテクチャパターンは、**ポートとアダプターパターン** (またはヘキサゴナルアーキテクチャ) と呼ばれます。これにより、シナリオと単体テストをより低いレベルで接続でき、コントラクトテストにより、それを実行する自信が得られます。

フルスタック

完全な自信を得るために、スタック全体を網羅する*いくつかの*テストを実行したいと思うでしょう。フルスタックのエンドツーエンドテストで問題がどこにあるかを診断することは非常に困難です。これは、問題がどこでも発生する可能性があるためです。これらのテストは、1つの変更ですべてが壊れる可能性があるため、脆弱です。また、ブラウザ、Webサービス、またはデータベースを介する場合にIOが関係するため、低速でもあります。

テストピラミッド

さまざまな種類のテストに焦点を当てます。多数の単体テスト、重いインフラストラクチャコンポーネントをすべて通過しない少数のテスト、およびUIを通過する少数のテストです。これは、テストピラミッドと呼ばれます。

詳細情報

高速テストを実装する方法の例 (node.js) については、GitHubのsubsecondtddを参照してください。

または、AslakのDevlin 2017での講演、またはこの主題に関するスライドをご覧ください。

このドキュメントの改善にご協力ください。このページを編集する