はじめに
多くの場合、開発者の仕事は機能コードを開発することだけではありません。開発するコードがアプリケーション環境で適切なスケーラビリティを持ち、適切に動作することを保証しなければなりません。開発したコードに対しては、本来、次の3つのテストを行う必要があります。
- 機能テスト…コードが提案どおりに機能することを確認します。
- スケーラビリティテスト…コードが提案どおりに機能しながら、できるだけ少ないリソースで動作することを確認します。
- ゴールテスト…コードが、指定のサービス品質保証契約(SLA)より短い時間で実行されることを確認します。
この3つの中では、通常は機能テストが最も行いやすいでしょう。
本稿では、スケーラビリティテストとゴールテストの違いを取り上げ、手動テスト向けの擬似コードテストハーネスの例を紹介し、実際にQuest SoftwareのToadという自動テストインターフェイスを使用してOracleプロシージャのテストを行う例を示します。適切なコードテストの方法、および開発者にとって利用しやすいテスト作成ツールについて学びたいと考えている開発者のお役に立てば幸いです。
手動で行うスケーラビリティテストの課題
まず取り上げるのは、プログラム、関数、あるいはステートメントが可能な限り効率的にリソースを使用していることを確認するテストで、「スケーラビリティテスト」と呼ばれます。スケーラビリティテストでは、本番システムで想定される環境とほぼ同じ環境に置いたコードを、ランダムな変数を使用し徐々にユーザー負荷を上げながら実行します。このとき、ユーザー負荷を特定のユーザー数まで高めていく場合もあれば、環境に明らかなストレスが見られるまでユーザー数を増やしていき、現行のプラットフォームでの最大スケーラビリティを判断する場合もあります。
スケーラビリティテストは、リスト1に示す擬似コードのような内製のテストハーネスを使用して実施できます。もちろん、このテストスクリプトは同時に複数のユーザーに手動で実行してもらう必要があります。
おそらく何百行にも及ぶと考えられるテストハーネスを管理することは、大変な作業です。また、ランダムな値を生成したり、手動テストハーネスの基礎となるインフラストラクチャを管理したりすることに、実際のアプリケーションの管理や改良よりも多くの時間と手間がかかってしまうでしょう。
スケーラビリティテストの結果は、通常、1秒あたりのトランザクション数(TPS)、あるいは1分あたりのトランザクション数(TPM)で表されます。
リスト1 スケーラビリティテストハーネスの例
Open procedure with "X" (number of times for each SQL iteration)
Loop 1: Choose Template SQL statement from SQL table
Loop 2: SQL Processing (iterate X times)
Read example SQL string from test SQL table
Parse variables from code
Loop3
Read variable types and values from variable table
Replace variables in SQL string with proper variable
End Loop3
Capture start timing
Execute parsed and variable loaded SQL into cursor
Capture end timing
Calculate total time spent executing
Load result table for executed SQL with timing
End Loop2
End Loop 1
Calculate Averages for all SQL
Determine TPS and or TPM
Generate report of results
End Procedure
ゴールテスト
パフォーマンスに関するもう1つのコードテストとして、コードが指定のSLAより短い時間で実行されるかどうかを確認する「ゴールテスト」があります。単一のステートメントを実行する場合と、複数のユーザーで同時に実行する場合の両方について検討します。SLAを締結する際には、マネジメントチームは、管理するシステムの該当部分のみに対応すれば十分です。
良いSLAとは、たとえば「トランザクションXは、データベースレベルで同時ユーザー数がZの場合、Yミリ秒(あるいは秒)以内で完了する」というものです。それに対して、言葉が不十分なSLAとは、たとえば「画面XはY秒以内に完了する」というものです。
なぜ、2番目の例は不十分なSLAなのでしょうか。理由は、利用状況を限定していないことにあります。画面Xを見ているユーザーはサーバーの隣にいるかもしれず、この場合、SLAに適合する可能性は高くなります。一方で、ユーザーはバングラデシュにいて、サーバーはアメリカにあるという状況も考えられます。この場合は、さまざまなネットワーク遅延が関係してくるため、単純にSLAに適合するかどうかを考えても意味がありません。
手動で行うゴールテストのテストハーネスの例をリスト2に示します。SLAを全面的にテストするためには、スケーラビリティテストと同様に、複数のユーザーに同時に手動テストを実行してもらう必要があります。ゴールテストの結果は、通常、特定の秒数に達するまでに行われるトランザクション数(TPMまたはTPS)、あるいは、あらかじめ指定されたTPSやTPMに到達するまでのユーザー数として報告されます。
リスト2 SLAテストハーネスの例
Open procedure with "X" (number of times for each SQL iteration)
Loop 1: Choose Template SQL statement from SQL table
Loop 2: SQL Processing (iterate X times)
Read example SQL string from test SQL table
Parse variables from code
Loop3
Read variable types and values from variable table
Replace variables in SQL string with proper variable
End Loop3
Capture start timing
Execute parsed and variable loaded SQL into cursor
Capture end timing
Calculate total time spent executing
Load result table for executed SQL with timing
End Loop2
End Loop 1
Calculate Averages for all SQL
Compare calculated averages to SLAs
Send alert if any SLA exceeded
End Procedure
スケーラビリティテストおよびゴールテストの自動化
自動テストの機能を持つユーティリティを提供している企業もあります。たとえばHP(正式にはMercury)の「LoadRunner」は高機能のテスト環境です。しかし、1人の開発者が、1つのステートメント、プロシージャ、あるいは機能コンポーネントに対してスケーラビリティテストやゴールテストを行いたい場合には、少々大げさかもしれません。個人で使うテスト環境という意味では、Quest Softwareの「Toad」の方が使いやすいでしょう。
自動で行うスケーラビリティテストの例
以降では、Toad for Oracleを使用した実際のスケーラビリティテストの例を紹介します。最初のステップは、必要なコードの開発です。今回は、従業員テーブルにレコードを挿入するプロシージャを開発します。図1は、このプロシージャをToadエディタで表示した様子です。
図1 Toad内のサンプルプロシージャ。従業員テーブルにレコードを挿入するコードです。
このプロシージャを作成する前に、Toad Code Testerで一連のテストを定義し、機能テストを自動化するためのテストハーネスを生成できるようにしておきました。図2は、図1のプロシージャをコンパイルしたものに対してCode Testerを実行した結果を示しています。
図2 Code Tester の結果。図1のプロシージャをコンパイルしたものに対してCode Testerを実行した結果です。
機能テストが完了したら、次のステップでスケーラビリティテストやゴールテストを行います。自動化したテストを実行するために、Benchmark Factoryインターフェイスでは自動化リンクが使われています。次のステップはPL/SQLプロシージャの選択です。図3は、Benchmark Factory(BMF)からプロシージャをテストするためのシナリオウィザードの画面で、テスト対象のプロシージャが選択されています。プロシージャのテストにランダムな変数を使用したい場合は、テスト対象のプロシージャを選択した後、図4の画面でランダム化スクリプトの呼び出しを挿入できます。
図3 プロシージャの選択。Benchmark Factory(BMF)からプロシージャテストを行うためのシナリオウィザードを示しています。
図4 変数の選択。ランダムな変数を使用するための呼び出しをウィザードで挿入できます。
次のステップでは、コードの同時実行に使用するユーザー数の範囲を選択します。BMFでは、単に、下限、上限、および増分を指定します。図5では、テスト範囲を1〜50、増分を10としています。
図5 ユーザー負荷の設定。テスト範囲を1〜50、増分を10としています。
実際のテストは、ユーザー負荷プロファイルが設定された後で実行されます。結果は表とグラフの両方の形式で提供され、Excelのスプレッドシートにダンプできます。図6に、プロシージャテストの結果を表形式で出力した最初のページを示します。
図6 表形式の出力。表形式の出力の最初のページです。
経営陣はグラフが大好きなものですが、その点に関してもぬかりはありません。図7に、このツールから出力できるさまざまなグラフの一例を示します。スプレッドシート形式の出力にも、手作業で作成したレポートに必要に応じてそのままカットアンドペーストできるグラフが含まれています。
図7 グラフ形式の出力の例。ツールから出力できるグラフの一例を示します。
開発、機能テスト、およびスケーラビリティテストやゴールテストを個人ユーザーレベルで統合して行うことのできる環境には、明らかなメリットがあります。標準ツールを使うことで、個々の開発者がコードの開発と共にテストの全フェーズにおけるテストレポートを作成でき、それを統合テストの実施時にQA/QCグループに引き渡すことができます。
開発者のためのコードテストの自動化
本稿では、スケーラビリティテストとゴールテストの違いを取り上げ、手動テスト向けの擬似コードテストハーネスと、自動化テストインターフェイスを使用したOracleプロシージャのテストの例を紹介しました。適切なコードテストの方法と、開発者によるテストを簡便化するツールについて知りたいと考えている開発者にとって、少しでも参考になれば幸いです。