前回に引き続きApache JMeterに関する話を書きます。
今回はシナリオ作成の際のちょっとした応用、それも結構頻繁に使うものです。
タイトルとして「Apache JMeterでASP.NETアプリをテストする」と書きましたが、要はリクエストの戻り値(レスポンスのHTML)中に含まれている値を、次のリクエストのPOST/GETパラメータに含める方法を説明します。
さて、なぜわざわざ「ASP.NETをテストする」と書いたかをASP.NETを知らない人に説明すると、所謂ポストバックというHttp Sessionに含めるような内容をレスポンス中のhiddenとして吐き出し、次のPOSTに含めることでHttp Sessionに近い状態管理を行うことができる仕組みを使っているからです。内部実装的にはSessionに含める情報(Object)をシリアライズしてBASE64エンコードしたものをhiddenに埋め込む感じです。
私ももともとJava開発中心でASP.NETは詳しくはありませんが、上記で大体あっているはずです。間違いがあったらご容赦ください。
さて、そのような仕組みで動いているため、ASP.NETアプリをテストする際にはレスポンスHTMLをパースしその中から特定の部分を抽出、次のPOSTに含めるということをしなければなりません。そのための簡単な方法を説明します。
レスポンス(のHTML)から値を取得し、JMeterで利用可能な変数として扱う方法はいくつかあります。汎用的で有名なところでは正規表現抽出があります。これは名前の通り正規表現で抽出するものなので汎用性がある一方、今回のASP.NETのように特定のhidden値を取得するには若干面倒な部分があります。
そこで手軽なものとして今回おすすめするのがXPath Extractorです。これも名前のままですが、レスポンスをXPathで解析し指定した箇所の値を変数として使用することができます。HTML/XMLにしか基本対応できませんが、正規表現よりも楽に、且つASP.NET以外でHTMLの表記ゆれがある場合にも対応できるのがよいです。
XPath Extractor固有の主要設定項目は以下のキャプチャの通り
です。
Apply toはXPath Extractorをどこに適用させるかです。通常は「Main Sample only」で問題ないかと思います。
XML Parsing Options はそのままXMLのParse時のオプションです。ASP.NETを含むWebアプリをテストする場合、通常レスポンスはHTMLなのでそのままXMLとして解釈すると失敗します。そこで、このオプションで「Use Tidy(toleramt parser)」と「Quiet」にチェックをつけ緩く解釈させます。もちろん、テスト対象のレスポンスがXHTMLだったりXMLならばこのオプションは必要ありません。
参照名はJMeter内で参照する変数名です。JMeter内で変数参照する場合は${参照名}と、ここで設定した参照名を使用することになります。今回はASP.NETのVIEWSTATE値を変数とするので、viewstateとしました。
XPath queryはレスポンスを解釈するためのXPath式です。XPath式の詳細は今回の説明範囲外なので各自で調べてください。ASP.NETの場合は参考にあるとおり
//input[@name'_VIEWSTATE']/@value
で問題なく動作すると思います。
この式の意味としては、
任意の場所にあるinput要素でname属性が「_VIEWSTATE」となっている個所のvalue属性
となります。
つまり
<input name="_VIEWSTATE" value="hoge" />
と任意の場所にあった場合、「hoge」が取得されるのです。
初期値は上記のXPath queryで値が取得できなかった場合に設定すべき値です。ここでは${viewstate}としていますが、ここもASP.NETでテストを行う際のポイントです。 XPath Extractorは、指定したXPath queryで値が取得できなかった場合空文字を返します。そうすると、一連のテストシナリオ中でASP.NETと関係のないリクエストが発行された場合、変数viewstateが空になりASP.NETへ次にリクエストを送る際にエラーとなります。それを防ぐため、途中で空文字が返ってきても引き続き以前のviewstateを使い続けるようにこのような記述をします。
以上のようにApache JMeterでASP.NETをテストするためのTipsのようなものを書きましたが、XPath式を変更すればほぼ全てのWebアプリで応用が利く内容になっています。XPath式は応用範囲が広いので、これを機に覚えて使ってみるのも良いかと思います。
XML/HTMLから値を抽出するのにDOMで頑張るよりよほど楽ですよ。