はじめに
JMeterにはいろいろなコンポーネントがあって、性能テストやテストの自動化に便利なのですが、中にはよく分からないコンポーネントも少なくないです。多分その中の代表であると思われる BeanShell Pre/PostProcessor についての話です。
※なお、この記事では、JMeter3.3を使用しました。
BeanShellとは?
Javaのコードをスクリプトで書くことができるものらしいです。この仲間には、JSR223やGroovyなどがあります。ともかく、BeanShellを使うにはJavaを知らないければならない、ということです。
BeanShell Pre/PostProcessorの使い方
「HTTPリクエスト」を右クリック「追加」から選択できます。PreProcessorは「前処理」、PostProcessorは「後処理」にあります。
基本的には、「Script」の枠にコードを書きます。「Script File」にファイル名を書くと、ファイルに書かれたコードを使うようになります。
BeanShellで使える変数(予約変数)
BeanShellの一番難しいところは、何の変数(予約変数)が使えるのかが分かりにことでしょう。さらにBeanShellの種類によって使える変数が少し異なっている、というのも難しくしています(いちおうvariables
の箇所に書かれて入るのですが)。ほぼJMeterのマニュアルのコピペですが、表にまとめました。説明の欄は英語を日本語にしただけです。
各変数が使えるメソッドはjavadocを参照してください。リンクを張っておきました。
変数名 | BeanShell Listener | BeanShell PreProcessor | BeanShell PostProcessor | BeanShell Timer | 説明 | 型 |
---|---|---|---|---|---|---|
log | ○ | ○ | ○ | ○ | ログファイルの出力に使用できる | Logger |
ctx | ○ | ○ | ○ | ○ | contextへのアクセス | JMeterContext |
vars | ○ | ○ | ○ | ○ | 変数へのreadとwriteのアクセス | JMeterVariables |
props | ○ | ○ | ○ | ○ | JMeterのプロパティ | java.util.Properties |
sampleResult | ○ | 前のSampleResult へのアクセス |
SampleResult | |||
sampleEvent | ○ | 今のSampleEvent へのアクセス |
SampleEvent | |||
prev | ○ | ○ | ○ | 前のSampleResult へのアクセス |
SampleResult | |
sampler | ○ | 今のsampler へのアクセス |
Sampler | |||
data | ○ | 現在のsample data へのアクセス |
byte[] |
BeanShellの例1:Cookieを動的に付与する
Cookieは、通常スレッドグループに「HTTPクッキーマネージャ」を入れておけば、HTTPレスポンスからJMeterは自動的にCookieの処理をしてくれます。しかし、あるページがJavaScriptでCookieを付与しているなど、手動でCookieを付与したい場合がまれにあります。JMeterには「CookieマネージャPreProcessor」というものは存在しないので、BeanShellで行わなければなりません。
BeanShell Pre/PostProcessorの書き方
import org.apache.jmeter.protocol.http.control.CookieManager;
import org.apache.jmeter.protocol.http.control.Cookie;
CookieManager manager = ctx.getCurrentSampler().getCookieManager();
Cookie cookie = new Cookie();
cookie.setName("foo");
cookie.setValue("bar");
cookie.setDomain("hoge.example.com");
manager.add(cookie);
内容は見たとおりです。注意点としては、
-
import
文がいる -
PreProcessor
の場合、なぜか変数sampler
が使えないので、ctx.getCurrentSampler()
から取得する - Cookie Domain名も設定しないと送信されない
- 「HTTPクッキーマネージャ」もスレッドグループに追加する必要がある(そうしないと、Cookieが保存されない)
です。JMeterの変数からCookie名や値を取得する場合は、vars.get()
を使えば良いです(JMeterの変数にCookie値などを格納する場合は、vars.put()
)。
設定箇所
「HTTPリクエスト」にPreProcessorを追加すると、リクエストを送る前に処理するので、そのリクエストでCookieを送信します。PostProcessorかListenerで追加すると、リクエストを送った後で処理をするので、レスポンスの値(ヘッダーやボディ)を元にして、Cookieを付与できます。JavaScriptでCookieを付与している場合、レスポンスのボディにあるJavaScriptを(正規表現抽出などで)パーズしてCookie値を取り出すことになるので、Listenerを使うことになると思います(PostProcessorでもいいですが、ボディの扱いがListenerのほうが簡単なため)。
BeanShell の例2:JSONのパーズ
JMeter3では、「JSON Extractor」があるので BeanShell は不要になりましたが、BeanShell Listenerの例としてはちょうどよさそうなので、例として挙げておきます。
BeanShell Listener
import net.minidev.json.*;
var body = sampleResult.getResponseDataAsString();
log.warn(body);
var json = JSONValue.parse(body);
vars.put("hoge", json.get("error"));
これも見たとおりですね。注意点としては、
- JMeter3では、JSONのライブラリが変更になった。(org.json.* → net.minidev.json.*)
くらいでしょうか。
設定箇所
レスポンスをパーズすることになるので、当然PostProcessorかListenerになります。
まとめ
設定で動かすツール系は、プログラムをもろに書けるようなコンポーネントを使ってしまうと、内部の実装に大きく依存するため、バージョンアップやバグなどに強く影響を受けてしまうため、互換性が悪いことが多いのです。そのため、使わないで済むなら、なるべく使わないようにしたほうが良いです。しかし、JMeterで提供されていないコンポーネントについては、BeanShell を使わざるを得ないでしょう。