第9回 Webサイト構築に必要なさまざまなテスト手法


樫山友一
2002/9/26


 今回はWebサイトのテストに関する解説です。Webサイトにはさまざまな性質がありますが、その性質にあったテストを行う必要があります。それぞれどのような目的を持ち、どのような方法で行うかを解説していきます。

 Webサイトのテストは、目的と内容をまとめると以下のようになります。

項目 内容 目的
論理的動作テスト 開発した機能をすべてチェックする すべての機能が設計どおり動作しているかを検証する
高負荷時のテスト Webサイトが実際に多くのユーザーに利用されている状況を作り出し、負荷をかける 負荷が高いときにしか起こらない障害を検出する
パフォーマンスチェック Webサイトの中から最も利用されるページや処理を選択して、どのくらいのパフォーマンスが得られるのかをチェックする 設計時の仕様を満たしているかをチェックする
障害時のテスト ネットワークの切断、サーバのダウンなどシステム障害を仮想的に実現して、障害時の動作をチェックする 障害が起こったときに、システムがエラーを検出して動作するかをチェックする。冗長化されているシステムでは、障害時も動作が継続するかをチェックする
ハッキングテスト ハッキングのテストを行っている企業などに依頼をし、Webサイトのセキュリティ強度を確認する セキュリティ・ホールがないかを確認する

 これらのテストは、パフォーマンスを必要としないシステム以外は、すべて行う必要があります。それぞれのテストについて、具体的にはどのように行うのかを解説します。

   論理的動作テスト

 これは、システムが仕様どおりに動作しているかをチェックするテストです。Webサイトの場合は、各ページが正しく動作しているかを確かめる必要があります。JSPやサーブレットでページを生成している場合には、そのロジックを考慮したうえでテストを行う必要があります。複雑なロジックを持つWebサイトの場合は、以下のような機能を持っています。

  • ログインしたユーザーにより表示される内容が異なる
  • アクセスした時間により、表示される内容が異なる
  • 管理者がページに表示する内容を変更できる
  • 外部のシステムからのデータ入力により、表示内容が変わる
 上記の条件によってページ内容が変化する場合は、詳細なテストを行う必要があります。条件が比較的簡単で、ページ数が少ない場合は、テストの仕様書を基に人手でテストを行うことになりますが、ページ数が多く、開発が段階的に行われるような場合は、自動テストツールを利用する方法もあります。

図1 Webブラウザとアプリケーションサーバ

 図1に示すように、ユーザーが入力した値は、HTTPプロトコルによりアプリケーションサーバに送信されます。リクエストを受け取ったアプリケーションサーバは、受け取った値を基にHTMLを生成して、Webブラウザに返します。HTTPプロトコルでは、HTMLがテキストとして受け渡しされます。人手によるテストでは、実際の入力をテスト担当者が入力し、結果を目視してチェックを行いますが、自動テストは以下のような仕組みでテストを行います。

  1. ユーザーの入力パターンを用意する。実際には、正常な値や予測されるエラーのパターンを引き起こすすべての値を用意する
  2. 上記の入力によって、得られるHTMLをあらかじめ取得しておく
  3. 自動テストツール
   高負荷時のテスト

 システムに負荷をかけてテストを行うことはとても重要で、主に以下のような障害を発見することができます。

  • セッション情報の不具合:複数のWebブラウザからデータを更新するような場合に、ほかのユーザーのデータを更新してしまったり、ほかのユーザーの情報が誤って表示されたりする障害を発見できる(図2)
  • プログラムの同期障害:負荷が高い状態でないとタイミング的に起こり得ない障害を発見できる
  • リソース待ちによるパフォーマンスの低下:複数のセッションで、1つのリソースを利用しているような場合は、同時に複数のセッションの処理はできないので、処理が極端に遅くなってしまうことがある
 上記の内容からも分かるように、同じ結果が得られる負荷をかけるのではなく、仮想的に複数のユーザーが、同時にログインしてWebサイトを利用している状態を作り出す必要があります。また、あらかじめ結果として返ってくるHTMLを事前に取得しておき、負荷が高い状態でも正しいHTMLを返してくるかを検査します。

図2 セッション情報の障害

 負荷をかけるプログラムは自作で開発することも可能ですが、市販のテストツールを利用することもできます。一般にはパフォーマンス計測のためのツールですが、テストにも利用することができるのです。市販のツールは、主に以下のような機能を持っています。
  • 複数ユーザーのログインが可能
  • 負荷の調整:複数のスレッドを用いて、アクセス間隔の指定などができる
  • 処理時間の計測:それぞれのページの表示にかかった時間を計測する
  • 結果のチェック:正しいHTMLが返ってきているかチェックできる
 フリーウェアとしては、Jakartaプロジェクトの「JMeter」がこれに当たりますが、市販ツールに比べて機能が劣っています。しかし、ソースコードが提供されているので自分の必要な機能を追加することも可能でしょう。

 負荷をかけるだけのツールを用いる場合は、負荷がかかっている状態でWebブラウザを用いてテスト担当者がすべてのページの機能をチェックすることによって、上記のテストの代わりにすることも可能です。

   デッドロックについて

 システムの負荷が高い状態では、デッドロックが発生することがあります。例えば、あるリソース(JDBCのコネクションなど)をスレッド1が持った状態で、なおかつ、同じソースを待っているスレッド2が、別のリソースも同時に持っている場合などに発生します。スレッド1とスレッド2は、お互いに持っているリソースが開放されるまで待つため、結局、2つのスレッドは永久に待ち続けることになってしまいます。よって、2つのリソースが開放されないために、他スレッドも処理を行うことができなくなります。

 デッドロックは、JDBCのコネクションプールの利用方法によって発生することがあります。ただ、単一のスレッドでは発生しないため、ある程度の負荷をかけてテストをしないと検出することができません。

   パフォーマンスチェック

 パフォーマンスチェックは、システムが要求されるパフォーマンスを実現するかチェックします。Webのパフォーマンスは、ページビュー(一定時間当たりのページ閲覧件数)などを用いて、一定時間内の表示(8秒くらい)を目安にします。実際には、Webサイトによってユーザーの利用形態はさまざまです。実際にサイトを訪れてからのページ閲覧数、ページ閲覧間隔など、あらかじめ綿密な予測データを作ることが必要になります。次に例を示します。

項目
同時ログインユーザー数 100ユーザー
ページの平均滞在時間 5分
ユーザー当たりの平均閲覧ページ数 10ページ

 これを市販のパフォーマンス計測ツールにパラメータとして入力し、閲覧するページをランダムに設定、100ユーザーのデータを設定すればパフォーマンスを計測することが可能です。市販ツールが、ページをリクエストしてから実際にHTMLが返ってくるまでの時間を計測してくれます。

図3 負荷と応答時間

 Webサイトに負荷をかけてみると処理の量によって、図3のようなグラフになります。応答時間が横ばいで一定の時間を維持しているようであれば、システムはかかっている負荷を処理する能力があります。しかし、応答時間がどんどん遅くなっていくようだと、システムの処理能力を超えて負荷がかかっている状態になります。限界値を求めるためには、左のグラフから右のグラフに移る境界を探せばいいことになります。

   障害時のテスト

 障害時にシステムがどのような振る舞いをするのかを確認し、設計どおりの動作をするかを確認します。予想される障害を以下に挙げます。

アプリケーションサーバの障害 停止してしまった場合は、HTTPサーバでエラーページにフォワードします。HTTPサーバがなく、直接Webブラウザからアプリケーションサーバにアクセスしている場合は、タイムアウトとなります。ただし、クラスタ構成の場合は、処理が自動的に継続されるので1つのアプリケーションサーバを停止させても、問題なく処理が継続されるかをチェックする必要があります
データベースの障害 データベースとの通信エラーを検出するので、エラーページにフォワードすることが可能です。データベースが冗長構成になっている場合は、障害時には自動復旧するので、復旧を確認します
HTTPサーバの障害 Webブラウザと直接通信をする部分なので、エラーを表示することができません。その結果、Webブラウザがタイムアウトになります。HTTPサーバがDNSラウンドロビンにより冗長化されている場合は、一度タイムアウトになっても次回は正常に動作します。(DNSラウンドロビンの設定がされている場合)2度目のアクセスが正常に動作するかを確認します
ネットワークの切断 アプリケーションサーバ、データベース、HTTPサーバ間それぞれいずれかが通信エラーになるので、エラーページにフォワードされるかをチェックします。ネットワーク構成がすべて冗長化されている場合は、正常動作します。仮想的に切断しても問題なく動作が継続されるかを確認する必要があります
サーバのオペレーティングシステム(OS)の障害 OSをシャットダウンしてしまい、仮想的に障害を発生させます。サーバが通信エラーになるので、エラーページにフォワードされるかを確認します。冗長化構成の場合は、正常に動作が継続されるかを確認します

 それぞれの障害を仮想的に起こして、結果が設計どおりの動作になるかをチェックします。障害時の動作は、システムの構成によって異なります。

   ユニットテストについて

 最終的なシステムが完成する前にテストを行うことはとても重要です。特に繰り返し開発においては、小さなリリースごとにテストを繰り返す必要があります。テストもプログラムとして自動化しておけば、リリースごとにテストをする手間が少なくなり、とても便利です。Javaを用いた開発では、ユニットテストに「JUnit」がよく用いられます。JUnitは、テストロジックを実装するためのフレームワークです。J2EEでは、JSP、ServletなどHTTPをインターフェイスとするものは、市販のテストツールでテストを行うことが多いのですが、EJBなどのRMIインターフェイスを持つものに関しては、JUnitを用いてテストを行うことが多くなっています。

 実際の開発現場においては、今回解説したもののほかに多くのテストを行うことが必要です。最近開発されるWebサイトは、アプリケーションサーバ、データベース以外にも外部のシステムと連携するなど構成が複雑になってきているからです。設計時に障害の種類やケースなどを想定して、早い段階から仕様としてまとめておくことをお勧めします。


■参考文献
「わかりやすいUML入門」オーム社
「Webサイトのわかる本」オーム社


プロフィール
樫山友一(かしやま ゆういち)

大手電機メーカー研究所でオブジェクト指向によるシステム開発に従事する。1996年よりJavaへの取り組みをはじめ、J2EEアプリケーションサーバを活用したWebシステム構築のコンサルタントとして多数のプロジェクトを手掛ける。
2001年3月にイーズ・コミュニケーションズ株式会社の設立に参加し、最高技術責任者に就任。
著書に「わかりやすいUML入門」、「Webサイトがわかる本」(いずれもオーム社)がある。


Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間