JMeterでCSVファイルのランダムな行を抽出する!

JMeterで「userid,entryid」みたいなデータをもとにランダムアクセスしたい!
と思ったんですがCSV Data Set Configは順番にアクセスするだけだし、
CSVRead関数はカラムしか指定できないし…!
かといってランダムに並び替えたCSVファイルを読み込むとかも嫌だし…!


だからBeanShellでやるお!


BeanShellはJavaベースのスクリプト言語です。
ようはJMeterJavaのコード書いてそこで作った変数とか使えちゃう感じです。
参考:BeanShell - Lightweight Scripting for Java


BeanShellアサーションとかListenerとかなんか色々あるんですが、
今回は前処理のところにあるBeanShell PreProcessorを使います。
作ってスレッド実行の度に読み込まれるようなところにぶちこんでおきましょう。


いくつか設定出来る値があるんですが、今回はParametersとScriptをいじります。
まずはParametersに読み込みたいファイルの絶対パスを入力!


次にScriptを書きます!

if (bsh.shared.myDataList == void || bsh.shared.myDataList.size() == 0){
    log.info("initialize myDataList");
    String[] params = Parameters.split(",");
    String filePath = params[0];
    bsh.shared.myDataList = new ArrayList();
    try {
        File file = new File(filePath);
 
        if (!file.exists()) {
            throw new Exception ("ERROR");
        }
 
        BufferedReader bufRdr = new BufferedReader(new FileReader(file));
        String line = null;
 
        while((line = bufRdr.readLine()) != null) {
            bsh.shared.myDataList.add(line);
        }
        bufRdr.close();
    }
    catch (Exception ex) {
        IsSuccess = false;
        log.error(ex.getMessage());
        System.err.println(ex.getMessage());
    }
    catch (Throwable thex) {
        System.err.println(thex.getMessage());
    }
} 
Random rnd = new java.util.Random();
int size = bsh.shared.myDataList.size();
String data = bsh.shared.myDataList.get(rnd.nextInt(size));
String[] columns = data.split(",");
vars.put("userId",columns[0]);
vars.put("entryId",columns[1]);

こんな!かんじで!
これで${userId}とか${entryId}とかやれば他の変数と同じように呼び出せます。すてきね!
この方法ならそもそもCSVにこだわることもありません。


ファイルの各行をリストで持って好きな区切り文字使って配列にしてるだけなので、
スペース区切りでもタブ区切りでも好きなフォーマットのファイルを読み込めます。
まあCVS Data Set Configもフォーマット指定できますが…。


最初データをstaticで持ってたんですが、
どうやら実行の度新しく作られてるっぽく意味ないじゃんしにたい!
と思って調べたところ、bsh.sharedを使えばいけることが分かりました。


JMeterのプロセスが生きてる限り共通で使われる領域みたい。
上のコードでもやってますが、たとえば「myDataList」って変数を作りたい場合、

bsh.shared.myDataList = new ArrayList();

とかやればおっけーです。
既に作成されているかどうかのチェックをしたい場合は

if (bsh.shared.myDataList == void) {
    log.error("まだないよ!");
} else {
    log.error("もうあるよ!");
}

という感じでできます。やったー!


あとおまけですが、パラメータの取得は2つ方法があります。
一つ目は上のコードでもやってる方法。

String[] params = Parameters.split(",");
String filePath = params[0];

Parametersはパラメータ全体を一つのStringとして持ってるので好きな区切り文字で区切って使えます。


もう一つはbsh.argsを使う方法です。

String hoge = bsh.args[0];

みたいな。みたいな。
これだと問答無用でスペース区切りになりますが、
パラメータをそもそもスペース区切りで指定してるならこれで事足ります。


それではみなさますてきなJMeterライフを!

スポンサーリンク