テスト戦略

テスト戦略を定義すると、テスト・リソースをコードの適切な部分に適切な時点で集中させるのに役立ちます。

中規模から大規模のアプリケーションを作成するときに、最初に頭に浮かぶ質問は「どこから始めるか」で、その次は「次に何をするか」です。ガイダンスがメトリックの形式で用意されています。これは、メソッド、クラス、およびテスト対象コンポーネント (CUT: components-under-test) の複雑さと信頼性を分析して戦略を決定するのに役立ちます。

コンポーネント・テストでは、機能テストとは対照的に、個々のソフトウェア・コンポーネント (クラス、メソッド、Enterprise JavaBeans™ (EJB)、および Web サービス・コンポーネント) に焦点が当てられます。コンポーネント・テストのポイントは、コンポーネントが適切に機能することを個別に確認できるように、各コンポーネントを分離することです。必要な場合は、スタブを使用して他のコンポーネントを置き換えて、テスト結果がテスト対象コンポーネントの振る舞いに限定されるように条件付けできます。一度信頼できるテスト・スイートが作成されたら、それを定期的に再実行して、CUT で回帰が発生していないことを確認できます。

以下のエリアに焦点を当てたコンポーネント・テストが可能です。

サブシステム・レベル・テスト

サブシステム・レベル・テスト (統合テストとも呼ばれます) の目的は、なんらかのサービスを提供するために連携する必要のある一連の統合されたクラスのテストです。多層環境では、サブシステムがそれらの層の 1 つである場合があります。サブシステム・レベル・テストでは、テスト対象コンポーネントとその他のサブシステムとの間のインターフェースを検査することに焦点を当てています。これらのテストでは、サブシステムの異なるオブジェクト間の相互作用を実際に行わせてみます。

確かにサブシステム・レベル・テストは実施するテスト全体の中で重大な役割を果たすものですが、サブシステム・レベル・テストを必ずメソッド・レベル・テストとクラス・レベル・テストで補足してください。 サブシステム・レベル・テストのみに焦点を当てていると、表面的なテスト範囲しかカバーされません。なぜなら、サブシステム・レベル・テストでは個別クラスを十分には制御できないからです。

統合テストには、よく知られたタイプがあり、 それらはしばしばトップダウンおよびボトムアップと呼ばれます。
  • トップダウン・テストは、プログラム階層の最上部から開始され、その階層のブランチを下方向にたどって行きます。このテストは、最深レベルまで最短パスを通って行う方法、あるいは階層内の各レベルをテストしてから次のレベルに進むという方法のいずれかで実行されます。このタイプのテストの主な利点は、サブシステムのグローバル・アーキテクチャーを早期に確認およびテストできることです。主な欠点は、下位レベルのコンポーネントが作成されるまではスタブを使用しなければならず、最上位コンポーネントに関しては必ずしも信頼できるテスト結果を得られるとは限らないことです。
  • ボトムアップ・テストは通常、下位レベルのコンポーネントを最初は個別に、次にクラスター単位でテストすることから始まります。これにより、各コンポーネントは確実に、完全にテストされてから呼び出しコンポーネントによって使用されます。この方式には、重要なコンポーネント内のエラーを、開発過程の比較的早い段階で検出できるという利点があります。主な欠点は、作動用のプログラムを提供するには、ほとんどまたは多くのコンポーネントを作成しなければならないということです。オブジェクト指向言語は、ボトムアップ・テストに役立ちます。
  • 3 つ目のオプションは、設計戦略に厳密に従うことです。これは、各コンポーネントをそのビルド時にテストするということを意味します。テスト定義はコンポーネントの設計の一部です。この戦略の一部として、トップダウンまたはボトムアップのいずれかのアプローチを採用できます。

クラス・レベル・テスト

クラス・レベル・テストでは、1 つのクラス内またはクラスの小さなクラスター内のメソッド間で、相互作用を実際に行わせてみます。焦点は、そのクラスが利用者が必要とするユース・ケースをすべてサポートしており、予期しないメソッド・シーケンスを処理できる十分な堅固さを備えているかどうかを検査することです。以下の理由により、クラス・レベル・テストは、オブジェクト指向ソフトウェアのテストには最も有効な方法であると一般的に考えられています。
  • クラス・レベルでのテストは、コード・カバレッジの点で非常に効率的であるため。 ほんの数回のテストで、60% から 70% のコード・カバレッジを達成できます。
  • クラス・レベル・テストは、クラスが利用者に提供するサービスを反映するため。 このテストは簡単に作成でき、さらにクラスに関するドキュメンテーションとして使用できます。
  • クラス・レベル・テストは、設計プロセスの早い段階でバグを検出するのには最適のレベルのテストであるため。

メソッド・レベル・テスト

メソッド・レベル・テストでは、メソッド・コード内に定義されているさまざまな条件を、他のすべてのメソッドから分離して実際に試してみます。通常は、考えられるすべての入力をメソッドが正しく処理するかどうかを確認することに焦点が置かれます。多くのケースでは、一連のメソッドを分離してテストすると、不完全なテスト範囲しかカバーできません。また、private メソッドなどの一部のメソッドは、分離してテストすることはできません。 (private メソッドは、オブジェクトの状態に大きな影響を与える可能性があり、他のメソッド呼び出しの振る舞いを変更する可能性があります。)

1 つのクラスのメソッド間での相互作用が問題の原因となるのはよくあることです。これらの問題を発見するのに最適な方法は、メソッドをさまざまなシナリオで実行してみることです。したがって、常にメソッド・レベル・テストをクラス・レベル・テストまたはサブシステム・レベル・テスト (あるいはその両方) と組み合わせる必要があります。ステートレス・クラスのテストのような一部のケースでは、メソッド・レベル・テストにのみ焦点を当てても構いません。また、その他のケースでは、メソッド・レベル・テストは回避して、クラス・レベル・テストにのみ焦点を当てることにする場合もあります。

メソッド・レベル・テストを成功させる鍵は、実際にテストすべきメソッドの判別です。以下の表に、メソッド・レベル・テストに関する、よくある質問の幾つかに対する回答を示します。

質問 回答
メソッドがスーパークラスから継承されるものである場合はどうするか。 メソッドがスーパークラスから継承されるもので、すでにスーパークラスのパーツとしてテスト済みである場合は、このメソッドに対して継承オブジェクトのコンテキストでのメソッド・レベル・テストを行う必要はありません。 ただし、継承オブジェクトのクラス・レベル・テストのコンテキストでは、このメソッドを使用する必要があります。
メソッドが親クラスのメソッドをオーバーライドする場合はどうするか。 メソッドを親クラスのコンテキストでテスト済みであっても、そのオーバーライドするメソッドを再テストする必要があります。
メソッドが多重定義またはオーバーライドされる場合はどうするか。 メソッドが多重定義されるのは、同じクラス内に名前が同じでパラメーターが異なるメソッドが複数存在する場合です。メソッドがオーバーライドされるのは、メソッドの宣言はあるクラスで行われて、メソッドの実装の定義または変更はサブクラスで行われる場合です。オーバーライドされるメソッドを使用すると、1 つのオブジェクト型にポリモアフィックな性質を持たせられます。どちらのケースでも必ず、これらのクラス・メソッドのそれぞれの実装を個別にテストしてください。

インターフェース、抽象クラス、およびスーパークラスのテスト

抽象テストを使用して、Java のインターフェース、抽象クラス、およびスーパークラスをテストできます。抽象クラスを単独で実行することは実際には不可能ですが、インターフェースを実装するクラス、抽象クラスを実現するクラス、またはスーパークラスから継承されるクラスに対して抽象テストを適用することはできます。

EJB テスト

Enterprise JavaBean (EJB) に対するテストは、通常はその EJB のビジネス・ロジックの検査と、その EJB のライフ・サイクル・メソッドが正常終了するか失敗するかの検査から構成されます。これを行うには、Bean クラスに定義されているメソッドを、そのメソッドの各種のインターフェースを通じて呼び出すことでテストします。テストは、EJB と同じコンテナー内に置くことも、アプリケーション・サーバーの外側に置くこともできます。

EJB をテストするのに最適な方法は、EJB をアプリケーション・サーバーにデプロイして、そのコンテナーのコンテキストで実行することです。 EJB がローカル・インターフェースを持つ場合、その EJB は、(例えば別の EJB を使用して) 同じアプリケーション・サーバー内からテストする必要があります。 EJB がリモート・インターフェースを持つ場合、その EJB は、アプリケーション・サーバーの外側で実行されている Java クライアントを使用してテストできます (ただし、ネットワーク・トラフィックが増加するという欠点があります)。 どちらの方法でも、テスト対象 EJB の振る舞いを分離できるように、その EJB から呼び出されるコンポーネントをスタブする必要があります。

コンテナー管理パーシスタンスまたは Bean 管理パーシスタンス (CMP または BMP) のいずれかを持つステートフルおよびステートレス (どちらでも可) のセッション Bean とエンティティー Bean をテストできます。テストするためには、すべての Bean がリモート・インターフェースまたはローカル・インターフェースのどちらかを持っている必要があります。メッセージ駆動型 Bean のテストは、現在はサポートされていません。

EJB テストのプロセスを単純化できるテスト・パターンが幾つかあります。

Web サービス・テスト

Web サービスのような分散コンポーネントをテストする場合のアプローチは、基本的には他のすべてのコンポーネント・テストの場合と同じです。最適なアプローチは、サーバーに対して一連の要求を実行して、サーバーの応答が予期される戻り値と一致するかどうかを検査することです。

Web サービス記述文書 (WSDL) に記述されているように、Web サービス・インターフェースは Web サービス用のコンポーネント・テストを自動生成するのに必要な入力です。

関連概念
Java サブシステム
状態ベースのテスト技法
関連タスク
Java メソッドのテスト
Java クラスのテスト
フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.