サブシステム・レベル・テスト は、各コンポーネントがそれぞれのインターフェース・コントラクトを遵守しているかどうか、および他のコンポーネントときれいに統合されているかどうかを検査することを目的とする非常に重要なテスト・レベルです。 サブシステム・テストは、クラス・レベル・テストとシステム・レベル・テスト間のギャップを埋めるもので、特にスコープとフォーカスの管理に役立ちます。
テスト・スイート全体でクラス・レベル・テストに焦点を当てていると、最後に統合に関する問題が残ることになります。 一方、サブシステム・レベル・テストのみに焦点を当てていると、表面的なテスト範囲しかカバーされません。なぜなら、サブシステム・レベル・テストでは個別クラスを十分には制御できないからです。
サブシステムのテストには、次のような一般的なプロセスを使用します。
理論的には、テストでの労力の大部分をクラス・レベル・テストの実行と、統合して 1 つのサブシステムとしてテスト可能なクラス・グループの識別に費やす必要があります。 サブシステムの内容を定義するには、密接に連携して 1 つのサービスを提供するクラスを識別する必要があります。 この選択は、以下の基準に基づいて行う必要があります。
サブシステムとしてテストするクラスのグループを識別したら、状態ベースの分析を使用して、検査するシナリオのハイレベルな理解に役立ててください。 作業対象がサブシステムなので、集合的振る舞いについて検討する必要があります。 集合的振る舞いに言及するのは、ある特定の状態に達したときには、個々のオブジェクトの多くがその特定の状態にすでに達していることが暗黙的に示されているからです。
例えば、住宅を購入するプロセスを管理する不動産システムを考えてみましょう。 このタイプのシステムには、PreapprovedCustomer、OfferAccepted、HomeInspectionCompleted、 および PurchaseAndSaleSigned などの 幾つかの状態があることが考えられます。
サブシステムを 定義するクラスも複数存在する可能性があります (例えば、Customer、House、Seller、Visit、Offer、Lender、Appraiser、Mortgage、CreditReport、CreditBureau、ApprovalLetter、HomeInspection、PurchaseandSale、LoanApplication、ClosingContract、 および Commission など)。
この例では、次のように、ある特定の状態 (例えば、PurchaseAndSaleSigned 状態) を複数のクラスおよび状態の集合的振る舞いと見なせます。
クラス | 状態 |
---|---|
Customer | UnderAgreement |
House | UnderAgreement |
Seller | UnderAgreement |
Offer | Accepted |
ApprovalLetter | Delivered |
HomeInspection | Completed |
CreditReport | UptoDate |
テスト・シナリオを作成するには、システムを PurchaseAndSaleSigned 状態にするために起こす必要のあるさまざまなアクションを考慮します。 テスト・シナリオでは、不動産の例では次のようになる、個々のアクションを実行する必要があります。
この時点で、テストを作成します。 これを行う最も簡単な方法は、対話する最初のクラスのメソッドに対するテストを生成することです。 このケースでは、 Customer クラスの getCreditReport メソッドを選択します。なぜなら、これがシナリオで最初に呼び出されるメソッドであるからです。 シナリオの作成作業を進めながら、テストに必要なオブジェクトを追加していきます。 サブシステムのすべての状態と遷移を確実にカバーしてください。 完了したら、シナリオ全体を通じて使用される値を定義します。 テスト・シナリオのカバーする範囲が広くなる可能性があるため、典型的な値と限られた数のデータ区分を使用するようにして、テスト・データが常にかなりシンプルであるようにしておくのが最良の策です。
状態図全体の典型的なフローの定義後には、テスト範囲を最大化するために、追加のシナリオを定義してください。 それらのシナリオでは、サブシステムのさまざまな状態と遷移を実際に発生させてみる必要があります。 あるシナリオが、以前に定義した別のシナリオと類似していることが、しばしばあります。 このような場合には、以前に定義したテストを基にして新しいテストを作成します。 それらの新規のテストでは、以前に定義したテスト・ドライバーを呼び出し、新しいテスト・シーケンス図に新規メッセージを追加してフローを完成させます。
このように、以前に定義したフローを再利用して、新規の遷移と状態をカバーするのに必要な若干の変更を加えるだけで、複雑なシナリオを構築できます。