JMeterのBeanShell Pre/PostProcessorを使う


はじめに

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 を使わざるを得ないでしょう。

マニュアル