はじめに
Gatling の主要概念についての簡単な整理です。
これまで雰囲気でスクリプトを書いてしまっていたので、きちんと理解するために公式ドキュメントを読んで、自分なりの理解を言葉と図でまとめてみました。
記事に書かないこと
Gatling の使い方
記事の構成
次の2部構成になっています。
- 言葉による3行まとめ
- 図によるまとめ
3行まとめ
公式ドキュメントの Glossary の項目について、それぞれ3行でまとめています。
Gatling の特徴
Domain-Specific Language (DSL) / 負荷試験を “定義” するための DSL
- Gatling のテストスクリプトは DSL で記述する
- DSL は試験内容を “定義” するだけ
- setUp メソッドに渡さない限り、リクエストが投げられることはない
Immutability / あらゆるものがイミュータブル1
- 提供されるクラスは基本的にすべてイミュータブル
- どのメソッドもインスタンスの状態は変更しない
- 状態が変更された新しいインスタンスを返すだけ
テストスクリプトにおける重要な概念
Virtual User / 仮想ユーザー
- Gatling では “仮想ユーザー” による操作を模したスクリプトを記述する
- 仮想ユーザーはそれぞれ独立したデータを保持できる
- Cookie やブラウザキャッシュなど、実際のブラウザ操作によるアクセスをある程度再現できる
Scenario / シナリオ
- 仮想ユーザーによる操作を DSL で記述したもの
- DSL でループや条件分岐などの制御が可能
- DSL で用意されていない処理もコードで記述可能
Injection Profile / 仮想ユーザーの “注入”
- シナリオを実行する仮想ユーザーのアクセス頻度やユーザー数の指定
- Open Model と Closed Model をサポート
- Open Model は秒間ユーザー数を指定、Closed Model は同時ユーザー数を指定
Simulation / システム負荷のシミュレーション
- テスト実行の単位
- 実際のシステム負荷のシミュレーション
- 複数のシナリオをまとめて並列実行、または順次実行可能
シナリオ作成のための機能
Session / 仮想ユーザーのデータストア
- 仮想ユーザーごとに独立したデータストア
- Feeder や HTTPレスポンスなどから値を保存可能
- 保存された値は EL 式で URL やリクエストなどに埋め込み可能
Feeders / 仮想ユーザーのデータソース
- すべての仮想ユーザーで共有するデータソース
- CSV や JSON 形式のファイルを元データとして利用可能
- List などを元にコード上で定義することも可能
Checks / エラー判定とデータ保存
- リクエストの成功(OK)、失敗(KO)の判定
- CSSセレクタ や JSONPath、XPath、JMESPath などで抽出した値で検証可能
- 抽出した値を Session に保存することも可能
その他
Assertions
- シミュレーション全体の成功、失敗の判定
- 「全リクエスト」を対象に「レスポンスタイム」の「平均」が「100ms以下」というように、スコープ、測定値、統計量、合格基準、の4つを指定
- 結果は JSON と XML ファイル(JUnit 互換) の2種類で出力
Reports
- テスト結果のレポートが static な HTML で出力される
- 統計値は
.js
や.json
ファイルで書き出される - 統計値の区分(Response Time の percentile など)は gatling.conf で変更可能
Durations
- Gatling の duration の単位は「秒」
- これは3行書くことがない
- 公式ドキュメントでもここだけ粒度がおかしいと思います…
図によるまとめ
主要概念
- シナリオを元に仮想ユーザーがテストを実行する
-
feed
メソッドでは Feeder から値を取得して Session に保存する - EL式による変数展開では Session から値が取得される
- HTTP レスポンスの中身を抽出して検証したり Session に保存できる
Injection
- 仮想ユーザーを投入する頻度、タイミングなどの設定
- 投入された仮想ユーザーは、同じシナリオを参照する
シナリオの可変部分
同じシナリオを参照する仮想ユーザーの挙動を変える手段は大きく2つ。どちらも Session に値を保存、更新することで挙動を変えます。
Feeder
- シナリオ実行中、feed メソッドのところに到達したら Feeder から値を取得
- 取得した値は Session に保存される
- 共通のキューから値を取得するので、各仮想ユーザーが feed メソッドを呼んだタイミングによって取得する値が異なる
例
.feed(csv("userid.csv")) // ここで1行分のデータが Session に追加
.exec(http("sample").get("/users/#{userId}")) // それをEL式で展開するようなシナリオにしておく
exec メソッド
- exec メソッドの引数のラムダ式は
(Session) -> Session
型 - 現在の Session を受け取り、更新した Session を返す
例
.exec { session -> session.set("userId", Random.nextInt()) } // Session に値を追加
.exec(http("sample").get("/users/#{userId}")) // それをEL式で展開するようなシナリオにしておく
-
公式ドキュメントでは "Most Gatling APIs" となっているので「あらゆるもの」は言い過ぎかもしれません。 ↩