Jmeterでサンプラーを作るめも

Jmeter使うときに送信するパラメータを動的に変えつつ試験をしたいって時がありますよね。その場合、サンプラーを自前で用意するのが簡単だと思うのと最近その辺をやってたので忘れないようにメモです( ..)φカキカキ

実行の流れとしてはだいたい↓のようになります。
1.AbstractJavaSamplerClientを継承したクラスFooBarを作ってJmeterJavaリクエストからそいつを呼び出す。
2.FooBarでなにかしてSampleResultクラスにデータをセットしてreturnする
3.Jmeterに戻って正規表現抽出でSampleResultにセットされてるデータを取り出す
4.取り出したデータをどこか(HTTPリクエストとか)で使う

上の場合だとJmeterの構造としてはこんな感じでしょうか。

Thread Group
   |
   |--Javaリクエスト
   |      |
   |      |--正規表現抽出
   |
   |--HTTPリクエスト   

では実際にやってみるとします。といっても単にbingで検索するだけです。

それではまずはJavaリクエストから見てみますが、今の段階ではFooBarがjarになっていてしかるべき場所にあるって前提で話を進めます。
f:id:masami256:20121213225256p:plain
まずは使いたいクラスをClassnameのところで設定します。そうすると「Send Parameters With the Request:」が変化すると思います。今はNameに"searchWord"、Valueに"linux"が入っていますが、これはFooBarクラスがデフォルトのパラメータとして設定しているものです。

さて、FooBarクラスですがこんな感じです。このFooBarが入ったjarファイルを作ってlib/extディレクトリに置くだけです。eclipseだとプロジェクトを適当に作ってAbstractJavaSamplerClientを継承したクラスを作ってプロジェクトをjarとしてエクスポートするだけなので簡単ですね。

package foobar;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;

public class FoobarSampler extends AbstractJavaSamplerClient {

	@Override
	public SampleResult runTest(JavaSamplerContext ctx) {
		String searchWord = ctx.getParameter("searchWord");
		
		String s = String.format("search?setmkt=ja-JP&q=%s", searchWord);
		
		SampleResult sr = new SampleResult();
		sr.setSuccessful(true);
		sr.setResponseCodeOK();
		sr.setResponseMessageOK();
		sr.setResponseData(String.format("query=%s", s), "UTF-8");
		sr.setDataType(SampleResult.TEXT);
		
		return sr;
	}

	@Override
	public Arguments getDefaultParameters()
	{
		Arguments params = new Arguments();
		params.addArgument("searchWord", "linux");

		return params;
		
	}
	
}

先ほどのデフォルトパラメータはgetDefaultParameters()で設定しています。そして、Javaリクエストの実行時はrunTest()が呼ばれます。このなかでJavaSamplerContextクラスのgetParameter()で指定したパラメータを取得することができます。
そして適当にデータを弄ってからSampleResultクラスにデータを突っ込みます。ここで以下のようなフォーマットでデータをセットしていますが、このフォーマット形式を使ってJmeter正規表現抽出でデータを取り出してます。

sr.setResponseData(String.format("query=%s", s), "UTF-8");

正規表現抽出はこのような感じです。
f:id:masami256:20121213230915p:plain
"Reference Name"はこの名前の変数に抽出結果が入ります。ここでは"search_query"としてます。
"Regular Expression"は↓のようにしています。FooBarクラスがSampleResultのsetResponseData()にセットした形に合わせています。

query=(.*)

"Template"は"$1$"を指定しています。これは下のような正規表現でbarのデータが欲しいような時に$2$と指定します(うろ覚えですが…)

foo=(.*) bar=(.*)

ここまででFooBarクラスでセットしたデータを正規表現抽出を使って取り出し、search_queryという名前の変数にデータが格納されたのでこれを別の箇所で使うことができるようになりました。
下記はPathにデータをセットしています。
f:id:masami256:20121213231658p:plain
変数の参照は${Reference Name}という形式です。

それで実際に投げられたリクエストを確認するとこのようになっていて思った通りにリクエストが投げれていることが分かります。

GET /search?setmkt=ja-JP&q=linux HTTP/1.1
Connection: keep-alive
Host: www.bing.com
Proxy-Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.2.1 (java 1.5)

ということで、これで自前のサンプラーを用意してJmeterから使えるようになりました!

話は変わってhttpリクエストの内容とか確認したりデバッグするのにBurp Suiteを結構活用してます。これ便利ですよね( ´∀`)bグッ!