アプリ開発やサイト制作のスマホ端末実機検証・テスト-Remote TestKit

Webサービスの性能テスト 基礎編その1

性能テストと一般に呼ばれるテストについての基本事項の説明と、それと混同やすい負荷テスト、ストレステストなどの違いの説明、および実際に性能テストを実施するうえで考慮するべき点について、ご紹介いたします。

概要

性能テストと一般に呼ばれるテストについての基本事項の説明と、それと混同やすい負荷テスト、ストレステストなどの違いの説明、および実際に性能テストを実施するうえで考慮するべき点について、ご紹介いたします。

性能テストとは?

本記事を読まれている読者の方が開発しているシステムには、多種多様なものがあると思いますので、それらを画一化してまとめて語ることはできません。しかし、一般的にシステム開発において、なんらかの形で性能に関する要件や要求が存在するはずです。(場合によっては、明文化されていない場合もありますが)

では、システムの性能を単純に定義するとはどういうことなのでしょうか。

極端に単純化すれば、ユーザのアクションに対してシステムがユーザの求める応答を返すまでにかかった時間を「性能」と考えることができます。
たとえば、ユーザインターフェースのあるシステムの場合には、ユーザがボタンをクリックしてから、その結果が表示されるまでの時間だったり、バッチプログラムのような場合には、起動してから(タイマーで起動されることもありますが)、終了するまでの時間であったりします。
開発されているシステムによって同時に利用するユーザ数に違いはあるかと思いますが、どのようなシステムであっても、「性能」という言葉で表す時には、既定の同時利用ユーザ数での応答時間をベースに考えるのではないでしょうか。

ただし、ここで注意したいのは、「性能を計測する行為」と「性能テスト」は似て異なるということです。

性能を計測することは、システムの現状を把握することですが、性能テストでは、その後が重要です。つまり、測定することで判ったシステムの現状の是非を問うことが「性能テスト」です。お客様の要求する時間内でシステムが応答しているかどうかを評価して、判断結果を出すのがテストになります。

機能性のテストの場合には、OKとNGがはっきりしていますが、性能テストのような非機能性テストの場合には、OK、NGの基準があっても、あいまいなケースが存在します。
たとえば、応答時間3秒以内というサイトのシステム構築の場合に、どのようなケースであっても3秒以内の応答時間という条件を満たすことは不可能に近いと考えられます。何らかの付加条件が要件に記載されていればよいのですが、「応答時間3秒以内」をいうように簡単な記述だけの場合が比較的多いようです。
その場合に、何を測定してOKとするかNGとするかということが重要となってきます。
この「何を測定するか」をシステムに照らし合わせて、適切に定義することが性能テストを難しくしている要因の一つです。

次の問題は、何を測定するかが決まっても、それをどうやって測定するかということです。
たとえば、10000ユーザの同時利用における応答時間という測定条件があったとして、10000人の人を実際に集めてテストするわけではないことはお分かりだと思います。何らかの仕組みを使って測定したい条件を作り出す必要があるということです。
これが、性能テストを難しくしている二つ目の要因です。

そして、三つ目の問題は、性能を正しく測定するためのデータの準備です。これについては、別途後述いたしますが、性能を測定するときに、数件しかないデータでは、実際の運用時とはかけ離れた性能になることは、お分かりかと思います。

まとめると、「なにを測定するか」「どうやって測定するか」、そして「データの準備」をどうやって行うかが、性能テストを難しくしている三大要因だと考えられます。

負荷テストとストレステスト

「性能テスト」と混同されやすいテストに、「負荷テスト」と「ストレステスト」が挙げられます。この3種類のテストは、名前が異なるように目的が異なっていますが、その方法が類似しているために、混同される場合があります。

ここで、「JSTQB Foundation」にて記載されている定義を引用してみましょう。JSTQBの言葉では、負荷テストは、「ロードテスト」と記載されています。

性能テスト(performance testing)

ソフトウエア製品のパフォーマンスを判定するためのテスト。

ロードテスト(load testing)

コンポーネントやシステムの動作を測定するテスト。負荷を増大させ、コンポーネントがどの程度負荷に耐えられるかを判定する。

ストレステスト(stress testing)

要件で定義した限界、またはそれを超えた条件で、システムやコンポーネントを評価するテスト。

この定義を見てお分かりかと思いますが、どのテストも何がしかの方法でシステムを動作させ、その結果を観測するという点では同じです。
ただし、システムに対する負荷の与え方と、何を評価するかという点がまったく異なります。
逆に言えば、それ以外の環境の準備や、負荷を与える仕組みなどはほとんど同一のものを使えるともいえます。

したがって、この三種類のテストを実施する場合、性能テスト、負荷テスト、ストレステストの順に行われることが多いようです。
最後にストレステストを実施するのは、過剰なストレスを与えた結果、システムに何らかの損傷が発生し、他のテストが実施できないということを防ぐためです。

また、それ以前に、システムの性能要件を満たすことを確認するはずの性能テストでNGとなった場合、システムに対する何らかの(おそらく大幅な)変更を適用して、再度テストを行う必要があります。そのような場合、それ以降の負荷テストや、ストレステストを行っても参考情報以上の意味はありません。

性能テスト実施について

では、性能テストを実際に実施するうえで、考慮しなければならない点について、一例を挙げて説明します。
まず、架空のWEBサイトのシステムを想定してみましょう。

架空のWEBサイトシステム

架空のWEBサイトシステムの画像

これは、インターネット上に公開しているWEBサイトの簡単な例です。実際のシステムでは、負荷分散装置があったり、複数のWEBサーバーを用意する場合があるかと思いますが、単純化して基本を考えてみましょう。

このような一般に公開されているサイトの場合、不特定多数に対してサービスを提供することになりますが、要件としては、同時アクセスユーザ数と、その時の応答時間の形で性能を定義することが多いと思います。
では、もう一度最初の説明を振り返ってみましょう。次の三点が難しいと指摘したかと思います。

  1. 何を測定するか
  2. どうやって測定するか
  3. データの準備

では、1番目の何を測定するかということを考えてみましょう。
要件に同時アクセスユーザ数と、応答時間が定義されている場合、何をというのは明確にされているでしょうか。
本当に単純な情報提供機能のみを実現しているサイトでなければ、一般には参照系のユーザのアクセスと更新系のユーザのアクセスが同時に動作していると考えられます。つまり、同時アクセスユーザ数といっても、個々のユーザがどのようにアクセスをしているかで、サイトに与える負荷は異なります。一般的に参照系のアクセスは高速に処理しやすいが、更新系のアクセス(特にトランザクション処理)は、ある程度の時間を必要とするケースが多いはずです。

したがって、まず同時アクセスユーザ数が定義されていても、その中のアクセスの割合などを決めていかないと、測定することができません。
そして、その割合は開発されているサイトがどういう目的で使用されるかによっても異なります。これを見極めて、適切なアクセスの割合を定義する必要があります。

また、次に説明する「どうやって測定するか」の実現方法にもアクセスの割合の検討は関係します。
誤ったアクセスパターン定義の例としては、参照系ユーザが同じページを繰り返しリロードするようなアクセスを測定する場合や、更新系ユーザが、同一ユーザでログインして、常に同じ商品ばかり購入するようアクセスを測定する場合があります。性能測定用ツールの設定を簡単に済まそうと考えると、ついこういった楽なアクセスパターンを設定してしまうという悪い例です。

実際のユーザの行動を考えた場合には、参照アクセスのみの通りすがりユーザであっても、同一のパターンによるページアクセスはあり得ないことは明らかです。参照アクセスに限定しても、複数パターンのアクセスを想定するのが正しいアクセスパターンの検討といえます。

つまり、個々のユーザがどのようにサイトを使うかをあらかじめ想定して、それらのパターンを考慮したうえで、「すべてのパターンを網羅することはできないこと」を前提とし、テストの基準となるアクセスパターンを取捨選択して定義する必要があるということです。

これらを考慮したうえで「なにを測定する」に答えることができるのです。

次に、「どうやって測定するか」を考えてみましょう。まず、非現実的な方法の例です。
同時アクセスユーザ数が決まっているので、その数だけ端末を用意して、オペレーションする人を集めます。そして定義された操作を実行してもらい、その時間を測定すれば、性能テストを実施することはできます。
ただし、同時アクセスユーザ数が、数名であれば実現の可能性はありますが、100名以上ともなると、現実的でないのは自明のことかと思います。

したがって、何らかの方法を使って、擬似的に同時アクセスユーザ数相当のアクセスを発生させる仕組みが必要になります。
人手によるテストが現実的でないことから、この性能テスト関連の領域については、比較的古くから自動化が盛んに行われています。

その結果、いくつもの商用のツールが販売されていますし、「Apache JMeter」に代表されるようなオープンソースのツールもあります。
とはいえ、これらのツールを単純に導入すれば良いというわけではありません。測定する内容(ユーザのアクセスパターンや、同時アクセス数)に合わせて、ツールの設定や調整、あるいは、同時アクセス数によってはツールを複数同時に利用するようなケースも十分考えられます。
したがって、ツールを選ぶことも大事ですが、ツールを使いこなして測定したいものを的確に測定できるように準備することが、大変な作業となる場合が往々にしてあります。
逆に、これをサービスとしている会社もありますので、プロジェクトの予算次第では専門家に依頼する方が確実な場合もあります。
これが、2つ目の「どうやって測定するか」です。

そして、3つ目の問題が「データの準備」です。

システムの性能を測定するのですから、当然ながら、データベースサーバーの中には、システムの運用時点で想定されるボリュームのデータが入っていなければ、性能テストにはなりません。

また、同時に単にボリュームがあればよいというのではなく、できるだけ本番運用で想定されるようなデータの質であり、かつ適度にかきまぜられたデータが必要になります。

データボリュームが必要なのは、少ないデータの場合には、キャッシュヒットによって、実際のディスクからのデータ読み込みが行われずに、高速に処理が行われる可能性があるからです。同様に、適度にかきまぜられたデータというのも、キャッシュヒットを起こりにくくするための意図があります。

これらの考えには、採用するデータベースエンジン、テーブル設計、システムの構成などが複雑に絡み合っているため一概には言えませんが、性能測定用のアクセスが発生した時に、できるだけシステムの各コンポーネントが動作するようなデータを用意する必要があります。
このデータの準備を怠ると、性能テストでは問題がなかったのに、本番運用になったとたんに性能が出ないという危険性があります。

性能は作りこむもの

システムの性能をテストするのですから、すべての結果がOKとなる訳ではありません。むしろNGとなるケースの方が多いかもしれません。特にプロジェクトの終わり間際で、性能テストを行ってNGとなった場合には、リカバリをすることができないケースもあり得ます。
データベース性能が支配的な問題の場合には、ハードディスクをやめて、シリコンディスクを使うという選択肢も最近では出てきましたが、コスト的な問題や、耐用年数の問題(シリコンディスクの書き込み可能回数の制限)などから、現実的な対応とはならない場合もあり得ます。

品質も性能も後付けで何とかなるものではなく、最初から慎重に考えて作りこむものです。
機能性要件に関する品質は、多重にチェックされていることが多いのですが、非機能性要件である性能に関しては、後ろへ後ろへと追いやられて、最後に一発勝負的なチェックをされる場合がよくあります。そして、そこで火を噴くこともよくあるのですが。
これを防ぐためにも、早めに早めに擬似環境をつかった性能に関する測定を事前に行うといった性能リスクを低減する策を講じる必要があると考えます。

執筆者プロフィール 吉村 好廣(ヨシムラ・クオリティ・サービス)

外資系コンピュータメーカーに入社し、ハードウエアからソフトウエアまで幅広く開発の経験を積む。その中で様々なレベルのテストを経験する。独立後、テストをキーワードにプロジェクトを渡り歩くフリーランスのエンジニア。Androidテスト部、自動化テスト研究会等の活動の中でさらに切磋琢磨し腕を磨き続ける。