JMeter でレスポンスデータを利用した負荷試験

東京オフィス、エンジニアの山田です。 先日、負荷試験をする機会があり、Apache JMeter を使用したの…

東京オフィス、エンジニアの山田です。
先日、負荷試験をする機会があり、Apache JMeter を使用したので、今回はそれについて書きたいと思います。
メジャーなツールなので今更感がありますが、誰かのお役に立てば幸いです。

 

概要

負荷試験をする際、レスポンスで受け取った値を次のリクエストで使用したいなどのケースが往々にしてあるかと思います。
特にログイン→会員ページというケースは非常に多いはず!

事前にブラウザでセッションを発行しておいて、テストにベタ書きして使うという方法もできなくはないですが、面倒な上に本来のユーザのオペレーションと違うのがちょっと微妙ですよね。

ということで、今回はテスト内でログインさせ、そのレスポンスに含まれる認証情報を使用して、後続の認証必須なリクエストを実施していく、といったケースの設定をしていきます。

 

前提

冒頭で説明した通り、認証必須のページに対して、ログイン時のレスポンスを利用して、正常に負荷試験を行うことを目的とします。
テスト対象のサンプルは Ruby on Rails に devise_token_auth という Gem で認証機能を追加したものを使用しています。

なお、JMeterで結果を表示するためのリスナーは

  • 結果をツリーで表示
  • 結果を表で表示
  • 統計レポート

の3点を使用しています。
これらを生成するためにも処理コストがかかるので、正式なテストを実施する際は「統計レポート」のみなど、必要最低限にするよう注意してください。

 
それでは、まずログインしていない状態のまま実施してみます。
GET /home というパスはあらかじめ認証必須に設定してあります。
1

認証していない状態なので、ちゃんと401が返ってきてますね。
このままでは正常な負荷試験をすることができません。
このリクエストに対して200が返ってくることを目標に設定していきましょう。

 

レスポンスから認証情報を取得

まずはログイン用のリクエストを作ります。
テストシナリオにもよりますが、今回はスレッドの頭で一度だけログインすれば十分なので、「一度だけ実行されるコントローラ」を追加して、その下に作ります。

それでは「HTTP リクエスト」を追加してログインの設定しましょう。
パラメータ or ボディには適切な認証情報を入れてください。

POST http://localhost:3000/auth/sign_in
{"email": "tayamada@example.com", "password":"mypassword"}

上記、サンプルにログインするための設定はこんな感じです。
2

 

実行するとこんな感じのレスポンスが返ってきます。
3

ログインに成功して、200 OKが返っているのが確認できますね。その他にも色々返ってきています。

 
今回のサンプルの場合、認証済みの状態でリクエストするには、ここで返ってきた値をリクエストに付けてあげる必要があります。
そのためにはまずレスポンスから値を取得しなければいけませんね。

そんなときは「正規表現抽出」という機能を使用すれば、正規表現で値を取得することができます。

 
対象のリクエスト、この場合は「HTTP リクエスト (ログイン)」を右クリックして、「追加」→「後処理」→「正規表現抽出」を選択しましょう。
リクエストの配下に「正規表現抽出」が追加されたのが確認できたかと思います。
あとは先ほど確認したレスポンスの内容に合わせて正規表現を書くだけです。

以下の例では、レスポンスからAccess-Tokenというヘッダの値を取得し、access_tokenという変数に置いています。

Apply to:"Main sample only"
Field to check:"Response Headers"
参照名:access_token
正規表現:Access-Token:(.+)
テンプレート:$1$
一致番号:1

ちなみにテンプレートは正規表現中に()が複数ある場合に何番目を対象とするのか、一致番号は複数マッチした場合に何番目を抽出するのか、という設定です。
今回、()は1つで、1番目を抽出できればよいので、上記のような設定になっています。

4

 
その他必要な値も同じように設定していきます。
サンプルでは上記の他に client, uid という変数で値を取得しました。

 
値がちゃんと取れているか確認したい場合は、ログインリクエストの後に「Debug Sampler」を追加してあげれば、「結果をツリーで表示」の「応答データ」で変数の値を確認することができます。
5

 

取得した認証情報をリクエストで使用

レスポンスからデータを取得するところまでは設定できました。
今度は認証済みであることを示すために、取得した情報をリクエストに付加する設定をしていきましょう。

 
まず認証済みリクエストをまとめるためのシンプルコントローラを追加します。
どういう目的のコントローラなのか名前を付けておくと後々便利です。
今回は何のコントローラかわかるよう「シンプルコントローラ(認証後用)」としています。

次にHOMEへのリクエストをドラック&ドロップで上記のコントローラの下に移します。

最後に「シンプルコントローラ(認証後用)」の配下に「HTTP ヘッダマネージャ」を追加し、
以下の項目を設定します。
※ 以下の設定は今回のサンプル用です。実際はテスト対象のアプリケーションの仕様に合わせて設定する必要がありますので、ご注意ください。

名前
Client ${client}
Uid ${uid}
Token-Type Bearer
access-token ${access_token}

 
設定後はこんな感じです。
6

これでシンプルコントローラ内のリクエストに認証用のヘッダが付加されるようになりました。

今回のサンプルはヘッダで認証情報を受け取るため、「HTTP ヘッダマネージャ」を使用しましたが、Webアプリだと Cookie にセッション情報を格納するケースも多いかと思います。
その場合は「HTTP クッキーマネージャ」というものが用意されていますので、そちらを使用しましょう。

 
準備が整ったところで早速テストを実行してみましょう!
7

冒頭で401が返ってきていた箇所もちゃんと200を返してくれていますね。目標達成です!
これで認証が必要なページにも問題なく負荷試験ができるようになりました。
あとは負荷テストのシナリオに沿ってリクエストを追加していけば完成です。

 

まとめ

今回はほんの一部しか紹介できませんでしたが、JMeterには色々な機能が用意されています。
例えば、カウンタ機能を使えば、スレッドごとにカウントを増やして別ユーザ(user1, user2, …)としてログインさせる、なんてことも簡単にできてしまいます。

他にもスクリプトを実行するコントローラなども用意されており、設定の自由度は非常に高くてとても便利なので、ぜひ使ってみてください!