LoadRunner之自定義HTTP請求
性能測試開發腳本時使用的都是同樣的模式。對在性能測試規划時指定的典型業務邏輯場景進行錄制,形成基本的腳本骨架。
錄制腳本后需要對腳本進行編輯,以滿足性能測試需求,編輯腳本需要掌握參數化 、關聯動態數據、增加邏輯控制等技術。
如果不能處理好腳本的錄制和編輯, 就不可能有效和成功的繼續進行性能測試。什么是參數化數據和動態數據呢?
這些數據都會做為http請求數據的一部分發送到web服務器,但二者肯定是有區別的。
錄制業務邏輯腳本時,生成的腳本包含的是錄制期間實際用到的值。
不做參數化這個腳本仍可以重放,不做關聯動態數據,重放腳本就會出現問題。在給系
統施加壓力的時候,同一個腳本會被很多虛擬用戶調用執行,應用系統現在都采用各種各樣的
緩存機制設計,不能使用同樣的數據,這和應用系統的實際使用環境不一致,這會導致性能測
試結果不可信。為解決這樣的問題我們做參數化,使用參數替換已錄制的值。參數化數據也有
不同的種類,比如登錄用戶和密碼,這些數據必須是系統支持的注冊用戶,需要從數據庫表中
讀取。另一些表單的文本輸入框,就可能允許隨意輸入數據。需要關聯的數據是從服務器響應
中獲取的,在以后的請求中發送到服務器的數據。可以通過web_reg_save_parm()這個LR API從
服務器響應中獲取保存動態數據。動態數據通常在刪除一些數據或審核后記錄進入以后的流程
環節等情況下出現。
本篇文檔會結合實例對動態數據數組和自定義HTTP請求進行介紹。演示使用的性能測試
工具是LR8.0,使用的web應用是工具自帶的MercuryTours Web系統,版本不一致,可能導致本
文檔中的腳本不能正確運行。Mercury Tours系統功能很簡單,提供了航班訂票(Flight菜單)
和取消預訂航班(Itinerary菜單)兩個功能。需要自己注冊,登錄系統以使用這些功能。其中,
取消預訂航班的操作步驟為:登錄系統-點擊Itinerary菜單-選擇一條預訂的航班記錄-點擊按鈕
"cancel checked reservations"以取消該航班。如圖1:
現在系統中有五條航班預訂記錄,按上述操作步驟,錄制LR腳本取消一條預訂記錄,如圖2:
在試圖重放該腳本的時候出現會出現問題,如圖3:
我需要對動態數據進行關聯。錄制腳本的時候取消了一次航班預訂,現在有四條記錄,
繼續錄制一次腳本,並比較兩次腳本的action.c文件如圖4:
從圖中,可以看出,loadrunner函數web_submit_form()的參數數目竟然是不一樣的。其中,
"Name=1"表示是第幾條航班預訂記錄,"Value=on"表示向服務器發送請求取消對應的航班記錄。
試着刪除:"Name=4", "Value=", ENDITEM, 回放腳本這樣是成功的。但我們不能每次人
工干預腳本以使腳本回放成功啊。怎么辦?我們只能對LR API函數的參數做參數化或者關聯動態
數據,而在參數數目發生變化的情況下,可以使用HTTP自定義請求函數web_custom_request()
來替代函數web_submit_form()。這個演示系統是使用Perl開發的,原來沒見過這種情況。卻也能
很好的演示web_custom_request()。
簡單介紹一下web_custom_request()的參數TODO。。。。。。
下面看一下,向服務器發送的請求的Body部分,如圖5:
對應的RecordingLog.txt部分為:
*** [tid=1a8 Action 33] Sending request to host 192.168.1.101:1080 ( 6/5/2009 00:45:15 )
"1=on&flightID=1494-796-kz&flightID=1494-1565-kz&flightID=1494-2334-kz&flightID=1494-3103-kz&fl"
"ightID=1494-3873-kz&.cgifields=1&.cgifields=2&.cgifields=3&.cgifields=4&.cgifields=5&removeFli"
"ghts.x=122&removeFlights.y=11"
其中1=on表示向服務器發送請求取消對應的航班記錄,removeFlights.x=122&removeFlights.y=11
記錄的是按鈕cancel的位置,這個不影響。flightID和.cgifields來自於服務器響應,我們會把這些信息保
存在一個數組里面,如何判斷和操作web_reg_save_parm()參考其他資料,不再敘述。在 web_url("welcome.pl",
前添加:
//added by the Tester manually.start:
int i,ii,k;
char tmp[32],tmpp[32];
char str[1024],strr[1024];
web_reg_save_param("flight_name",
"LB/IC=
"RB=\">",
"Ord=ALL",
LAST);
web_reg_save_param("cgi_field",
"LB/IC=
"RB=\">",
"Ord=ALL",
LAST);
//added by the Tester manually.end!
其中 "Ord=ALL"表示會把所有的復合左右邊界的數據保存在數組里面。
下面對保存的動態數據進行解析,封裝成http請求的body部分:
i = atoi(lr_eval_string("{flight_name_count}"));
ii=atoi(lr_eval_string("{cgi_field_count}"));
//lr_error_message("fff %d",ii);
strcpy(str,"body=1=on&flightID=");
//lr_error_message("str : %s",str);
for (k=1;k<=i;k++)
{
sprintf(tmp,"{flight_name_%d}",k);
sprintf(tmpp,"{cgi_field_%d}",k);
//lr_error_message("str tmp : %s,%s",tmp,lr_eval_string(tmp));
//lr_save_string(lr_eval_string(tmp),tmpp);
//lr_error_message("str tmpp : %s",tmpp);
strcat(str, lr_eval_string(tmp));
strcat(str,"&flightID=");
strcat(strr,"&.cgifields=");
strcat(strr, lr_eval_string(tmpp));
//lr_error_message("str 2 : %s",str);
//lr_error_message("str 22 : %s",strr);
}
strcat(str,strr);
strcat(str,"&removeFlights.x=122&removeFlights.y=11");
//lr_error_message("str 2 : %s",str);
lr_output_message(str);
//return 0;
我們需要自定義http請求函數為:
web_custom_request("itinerary.pl",
"Method=POST",
"URL=http://192.168.1.101:1080/MercuryWebTours/itinerary.pl",
"RecContentType=text/xml",
"Snapshot=t4.inf",
str,
LAST);
現在我們再進行回放該腳本就不會出現問題了。腳本回放成功,我們的文字也
到此就結束了,我們不再對該腳本進行場景調度,已經分析性能測試運行的結果。我們的
目的只是演示動態數據數組的保存、使用及http自定義請求函數web_custom_request()。