うさぎ組

kyon_mm with software

このエントリーをはてなブックマークに追加

Webアプリ性能テストツールGatling-シナリオ作成編-

はじめに

このエントリはソフトウェアテストAdventCalendar2014の4日目の記事です。

http://connpass.com/event/4544/

3回にわけて、GatlingというWebアプリケーションの性能テスティングフレームワークについて解説します。

GatlingのDSLチートシート

GatlingはScalaのDSLでスクリプトを書きますが、ほとんどはメソッドチェーンでつなげて書けるようになっていて初心者でも扱いやすくなっています。つまり、IDEの支援があれば補完が効いて「それっぽいのを選んで打ってみる」+「Ctrl + Spaceで次の動作(メソッド)を表示して選択する」で比較的スムーズに始められます。

なのですが、最初になにがあるのかわからなければ補完を出す前に到達できません。ということで、DSLの一覧的なチートシートが公式で存在します。Gatlingを使うときには手元に表示させておくとよいです。

http://gatling-tool.org/cheat-sheet/

サンプルのスクリプトを動作させてみる

解凍したディレクトリにcdしてgatling.shを実行すると次のような感じですすみます。

$gatling-charts-highcharts-1.5.3>sh bin/gatling.sh
GATLING_HOME is set to /Users/kyon_mm/apps/gatling-charts-highcharts-1.5.3
Choose a simulation number:
     [0] advanced.AdvancedExampleSimulation
     [1] basic.BasicExampleSimulation
1
Select simulation id (default is 'basicexamplesimulation'). Accepted characters are a-z, A-Z, 0-9, - and _

Select run description (optional)

3回入力をする必要があります。

  1. どのスクリプト(シミュレーション)を実行するか
  2. 選択したシミュレーションのIDをデフォルト(ファイル名を全て小文字にしたもの)から変更するか
  3. シミュレーションに説明書きを追記するか

ここでは、 「1 Enter」「Enter(入力なし)」「Enter(入力なし)」としました。

その後スクリプトが実行され、次のような表示がされて完了します。

---- Scenario name -------------------------------------------------------------
Users  : [#################################################################]100%
          waiting:0     / running:0     / done:10
---- Requests ------------------------------------------------------------------
> Global                                                     OK=197    KO=103
> request_1                                                  OK=10     KO=0
> request_2                                                  OK=10     KO=0
> request_3                                                  OK=10     KO=0
> request_4                                                  OK=50     KO=0
> request_5                                                  OK=0      KO=50
> request_6                                                  OK=49     KO=1
> request_7                                                  OK=0      KO=50
> request_8                                                  OK=48     KO=2
> request_9                                                  OK=10     KO=0
> request_10                                                 OK=10     KO=0
================================================================================

Simulation finished.
Simulation successful.
Generating reports...
Reports generated in 1s.
Please open the following file : /Users/kyon_mm/apps/gatling-charts-highcharts-1.5.3/results/basicexamplesimulation-20131228210609/index.html

最後の文言に従って対象のファイルを開いてみるとレポートが開きます。

  • 全体の結果を表示している。
../../../_images/Global_Information.png
  • 全体でアクティブになっていたセッション数の遷移とレスポンス時間の分布
../../../_images/active_session.png
  • 1秒間あたりのリクエスト数とトランザクション処理数
../../../_images/number_of_request.png
  • 各レスポンスの詳細まとめ
../../../_images/detail.png
  • レスポンス時間の分布とレイテンシ間隔
../../../_images/response_time.png

適当にHTTPリクエストを10ユーザーから送信された場合の想定として上のような結果になった。という感じです。では、次で実際に作成してみます。

新しくスクリプトを作成する

では、新しくスクリプトを作成しましょう。次の手順で進めます。(その後でサンプルコードをのっけます。)

  1. SWTestAdventSampleというcom.excilys.ebi.gatling.core.Predef.Simulationをextendsしたクラスを作成する。(サンプルプロジェクトを使う場合はbasic配下、Maven + IntelliJで行う場合はsrc/test/scala配下)
  2. 次をimportしておく。com.excilys.ebi.gatling.core.Predef._ , com.excilys.ebi.gatling.http.Predef._, akka.util.duration._, import bootstrap._
  3. httpConfigでHTTPの共通になる設定、scenarioでHTTPリクエスト、レスポンスチェックの作成を行なう。それぞれ適当な変数に束縛しておく。(val httpConf, val scnなど)
  4. setupで3で作ったhttpConfとscnを設定する。ユーザー数(同時リクエスト数)などはsetup前にscnに指定する。

ということで、1のようなclassを作成したら、httpConf, scenario, setupを書き始め、あとは適当にCtrl + Spaceの補完でそれっぽいのが出てくるはずです。

package basic

import com.excilys.ebi.gatling.core.Predef._
import com.excilys.ebi.gatling.http.Predef._
import akka.util.duration._

class SWTestAdventSample extends Simulation {
  val httpConf = httpConfig
    .baseURL("http://excilysbank.gatling.cloudbees.net")
    .acceptCharsetHeader("ISO-8859-1,utf-8;q=0.7,*;q=0.7")
    .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
    .acceptEncodingHeader("gzip, deflate")
    .acceptLanguageHeader("fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3")
    .disableFollowRedirect

  val headers_1 = Map(
    "Keep-Alive" -> "115")

  val scn = scenario("Scenario name")
    .exec(
      http("request_1")
        .get("/")
        .headers(headers_1)
        .check(status.is(302)))
    .pause(0 milliseconds, 100 milliseconds)
    .exec(
      http("request_2")
        .get("/public/login.html")
        .headers(headers_1))

  setUp(scn.users(10).ramp(10).protocolConfig(httpConf))

}

httpConfigで設定している項目はGatlingというよりはHTTPの仕様を調べてもらう方がいいかなっておもいます。scenarioの部分で使っているAPIについて一言ずつ解説します。

  • scenario : シナリオを作成するためのメソッドチェーンの最初のAPIです。Stringを引数にとっていて、ここにシナリオの名前を指定します。1スクリプトで複数のシナリオを実行できるのですが、その場合には区別するために別別の名前にする必要があります。
  • exec : リクエストを送信します。引数にHTTPリクエストをとります。
  • http : HTTPリクエストを作成するためのメソッドチェーンの最初のAPIです。
  • get : GETリクエストを作成します。引数にURLをとります。setupでhttpConfigを指定する場合には、httpConfigで設定したbaseURLから後ろのURLを指定することになります。同じようにpostも存在します。
  • headers : HTTPヘッダーを指定します。引数にMapをとります。指定したいHTTPヘッダーをMapにして渡します。
  • check : HTTPレスポンスに対して検査を書きます。ここでは、HTTPステータスが302であることを検査しています。
  • pause : 前の処理から指定した時間を一時停止します。時間の間隔を引数にとります。2つ渡すと、その間の値をランダム的に選択します。

サンプルにもあるように1つのシナリオで複数のexecを書くことができます。なので、いわゆる「○○をクリックすると、××が返ってきて、○○をクリックして、、、」というようなシナリオも書けます。

スクリプトを実行する

サンプルプロジェクトで実行する場合は、gatling.shを実行し、対象のクラスをコンソールで指定します。 IntelliJから実行する場合は、src/test/scala配下のEngine.scalaを右クリックしてRunします。そうすると、IntelliJの画面下部に下の写真のようなコンソールがでます。あとは、gatling.shから実行した場合と同じです。

../../../_images/engine_idea.png

すごくザックリですが、基本的な使い方はかんじです。ここでまだ書いていないけどよく使うものとしては、リクエストのボディをファイル直接指定するとか、パラメタライズテストのようなことをするとかです。これはまた別の場所で書こうと思います。

次回は実際のブラウザ操作をキャプチャしてスクリプト化します。