Vuser發生器(VisualUserGenerator,簡稱爲VuGen)主要通過捕獲用戶端向伺服器發送的HTTP請求,將這些請求錄製成指令碼,在回放時將捕獲的HTTP請求再次發送,以達到模擬客戶的行爲的目的,所以Vuser主要是用來捕獲終端使用者業務流程和建立自動化測試指令碼,即生成測試指令碼。VuGen是錄製測試指令碼、編輯與完善測試指令碼的一個平臺,支援C語言語法。
主要包括以下內容:
指令碼錄製
Recording Options設定
Run-Time Settings設定
指令碼完善
啓動VisualUserGenerator,建立一個新的指令碼,開始錄製指令碼,在錄製指令碼過程中,VuGen會自動捕獲操作過程中用戶端與伺服器端進行通訊的所有數據。這裏涉及的關鍵點是如何選擇錄製協定。
指令碼開發主要包括四大步驟:計劃、錄製指令碼、指令碼增強和單機偵錯指令碼,如圖所示。
如何選擇協定
在建立一個新的指令碼時,首先會彈出一個對話方塊,在該對話方塊中選擇錄製時需要的協定,這步非常重要,選擇的協定將直接影響到錄製後的指令碼是否理想,如何選擇錄製協定是錄製前必須要解決的問題。
各種協定和相關標頭檔案的對應關係如圖所示。
選擇協定的常用方法主要有以下幾種:
1.最簡單的方法就是向開發工程師確認數據通訊所採用的協定,因爲開發工程師最清楚應用程式採用的是何種通訊協定。
2.沒有開發工程師支援時,可以通過概要或詳細設計手冊獲知所使用的協定。
3.使用協定分析工具捕獲通訊時的數據包並進行分析,然後確定被測物件所使用的協定。在使用協定分析工具分析協定過程中一定要摒除底層協定,不要被底層協定所迷惑。
4.根據以往測試經驗來判斷被測試物件採用的協定,這種方法具有猜測性,有時候不一定準確。
在LoadRunner新的版本中有一個協定分析的工具(ProtocolAdvisor),通過該工具可以分析當前系統所使用的協定。協定分析工具的使用步驟如下:
1.在【WelcometotheVirtualUserGenerator】介面單擊【ProtocolAdvisor】按鈕,如圖所示。
2.彈出【ProtocolAdvisor】對話方塊,如圖所示。
Applicationtype:選擇應用程式的型別,被測試的應用程式型別主要包括兩類:InternetApplictions和Win32Applications,也即通常說的B/S和C/S框架的兩類應用程式。
Programtoanalyze:分析的程式,如果選擇的應用程式型別爲InternetApplications那麼,該選項爲MicrosoftInternetExplorer,即IE瀏覽器,因爲LoadRunner在錄製時預設啓動IE瀏覽器進行錄製;如果選擇的應用程式型別爲Win32Applications,那麼該選項爲需要測試的應用程式的路徑。
URLAddress:即需要分析的網頁地址;
Workingdirectory:工作目錄,預設的爲LoadRunner所在路徑的bin目錄。
3.設定待分析程式的路徑或URL地址,單擊【OK】按鈕,即開始分析應用程式,通常分析一個簡單的業務即可停止分析。
4.單擊浮動框中的【StopAnalyzing】按鈕,停止分析應用程式,併產生分析後的結果。
LoadRunner提供了多種協定,具體的協定分類見表。
1.單協定指令碼:建立單協定Vuser指令碼,在對話方塊中選擇錄製時需要的協定,如圖所示。建立新指令碼時,會彈出一個對話方塊,LoadRunner提供三種選擇協定的方式:單協定指令碼、多協定指令碼和最近使用過的協定。
2.多協定指令碼:建立多協定Vuser指令碼。在AvailableProtocols中選擇一個或多個協定,點選右箭頭,將其移入到SelectedProtocols部分中,同樣,在SelectedProtocols中選擇一個或多個協定,點選左箭頭可以移除選中的協定,如圖所示。
3.最近使用過的協定:從最近錄製指令碼的協定列表中,選擇一種協定進行錄製,如圖所示
協定選擇好後可以開始錄製指令碼。這裏以Web(HTTP/HTML)協定爲例進行錄製。
VuGen錄製瀏覽器主要是通過代理的方式來實現的。開始錄製時,VuGen開啓瀏覽器(預設使用Mircosoft自帶的IE瀏覽器,使用其它瀏覽器錄製容易出現HTTP請求被丟失的現象,所以儘量使用IE瀏覽器進行錄製),並以VuGen作爲代理來存取目標伺服器。這樣,VuGen就可以捕獲用戶端與伺服器之間通過的數據包,如圖所示。
在使用VuGen進行錄製使用者操作時,VuGen會對捕獲的數據進行分析,並將其還原成對應協定的由API組成的指令碼。同時,VuGen會將這些函數生成的指令碼插入到VuGen編輯器中,以建立原始的Vuser指令碼。
錄製時系統彈出一個錄製視窗,如圖所示。
在URLAddress中輸入要錄製的站點地址。RecordintoAction選項表示將錄製的程式碼放到哪個部分。LoadRunner生成的程式碼由三部分組成:vuser_init、Action和vuser¬_end。
注意:一般情況下都是將生成的程式碼放在Action部分,因爲vuser_init和vuser¬_end兩部分的程式碼只會執行一次,這樣會出現這種問題,客戶的併發虛擬使用者只執行一次,執行完成一次後再也不執行,這樣就沒有HTTP請求給伺服器,也即伺服器沒有壓力。如下例子,圖是每秒點選率的值。
從圖中可以看出,在場景執行到25秒後,用戶端的點選率爲0,即25秒後用戶端沒有提交任何請求,這就是典型的由於將指令碼放在vuser_init引起的,因爲指令碼放在vuser_init中,導致每個虛擬使用者只會執行一次這部分的指令碼,當使用者載入完成後,再也不行,所以看到後期的點選率都爲0。
Recordtheapplicationstartup選項表示應用程式一旦啓動,VuGen就立即開始錄製;如果不選中,應用程式啓動後,VuGen會彈出如圖所示的對話方塊,並且暫時不會進行錄製,當使用者操作應用程式到需要錄製的地方時,點選Record按鈕,VuGen纔開始錄製。預設情況下Recordtheapplicationstartup是選中的狀態。點選Record按鈕開啓錄製。
在錄製前還需要注意在RecordinOptions設定對話方塊中,設計指令碼錄製的方式,關於指令碼的錄製方式將在3.2.1小節中詳細介紹。
開始錄製後,會出現如圖所示的工具列
該工具條從左到右依次代表開始錄製、暫停錄製、停止錄製、新建Action、在指令碼與錄製介面之間切換、新增開始事務標識、新增結束事務標識、設定集合點和新增註 加注釋。
錄製過程中,LoadRunner會自動記錄使用者的操作。錄製完成後,點選「停止錄製」按鈕結束錄製,這時VuGen會自動生成一個指令碼,如圖所示。
這是一個比較簡單的指令碼,但可以看出LoadRunner生成的指令碼都是由函陣列成。
在進行錄製時,首先要對錄製的一些參數進行設定,只有將這些參數設定好,才能 纔能錄製並生成需要的指令碼。
首先是RecordingOptions設定,需要注意的設定項有:Recording索引標签、Advanced索引標签和Correlation索引標签。
在Tools選單中選擇RecordingOptions或直接按快捷鍵Ctrl+F7進入參數設定對話方塊,如圖所示。
Recording索引標签
在RecordingOptions對話方塊中,選擇Recording索引標签。RecordingLevel包含兩種錄製模式:HTML-basedscript和URL-basedscript,如圖所示
預設情況下選中HTML-basedscript錄製方式。當然,兩種錄製模式也存在差別
單擊【HTMLAdvanced…】按鈕,彈出【AdvancedHTML】對話方塊,如圖所示
在該對話方塊中關於HTML-basedscript指令碼方式又有兩種:「Ascriptdescribinguseractions」和「Ascriptcontainingexplicit」。
Ascriptdescribinguseractions:模擬使用者行爲錄製,即GUI錄製,把使用者每一步的操作顯示出來,最後生成的指令碼非常直觀並且會將上下文的一些敏感資訊記錄下來。它建立URL(web_url)、link(web_link)、image(web_image)和提交表單(web_submit_form)。
下面 下麪以Ascriptdescribinguseractions方式錄製一個登錄的功能,錄製後的程式碼如下:
web_url(「WebTours」,
「URL=http://127.0.0.1:1080/WebTours/」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=」,
「Snapshot=t1.inf」,
「Mode=HTML」,
LAST);
lr_think_time(4);
web_submit_form(「login.pl」,
「Snapshot=t2.inf」,
ITEMDATA,
「Name=username」,「Value=test1」,ENDITEM,
「Name=password」,「Value=1」,ENDITEM,
「Name=login.x」,「Value=65」,ENDITEM,
「Name=login.y」,「Value=8」,ENDITEM,
LAST);
return0;
從生成的程式碼中可以看到,在錄製時只做了兩個操作,生成的程式碼也只有兩個函數,也即這種錄製模式只錄制使用者的操作,其它的內容不會被錄製。使用的提交資訊函數爲web_submit_form()。
AscriptcontaningexplictURLsonly:錄製所有links(鏈接)、images(圖片)和URL(web_url),但不建立web_link、web_image和提交表單(web_submit_form)。這種錄製方式生成的指令碼不直觀。
下面 下麪以AscriptcontaningexplictURLSonly方式錄製一個登錄的功能,錄製後的程式碼如下:
web_url(「WebTours」,
「URL=http://127.0.0.1:1080/WebTours/」,
「TargetFrame=」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=」,
「Snapshot=t1.inf」,
「Mode=HTML」,
LAST);
web_submit_data(「login.pl」,
「Action=http://127.0.0.1:1080/WebTours/login.pl」,
「Method=POST」,
「TargetFrame=body」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home」,
「Snapshot=t2.inf」,
「Mode=HTML」,
ITEMDATA,
「Name=userSession」,「Value=108748.859052248ffQDHzQptDHfDDfzcpzVzzcf」,ENDITEM,
「Name=username」,「Value=test1」,ENDITEM,
「Name=password」,「Value=1」,ENDITEM,
「Name=JSFormSubmit」,「Value=off」,ENDITEM,
「Name=login.x」,「Value=53」,ENDITEM,
「Name=login.y」,「Value=10」,ENDITEM,
LAST);
return0;
從生成的程式碼中可以看到,同樣的提交登錄的資訊但使用的函數爲web_submit_data(),不再以表單的方式提交,而web_submit_form()函數則是以表單的資訊進行提交的,該函數執行時,首先在頁面上去查詢表單,再提交數據,而web_submit_data()則不需要,直接向伺服器發送要提交的數據。
但在錄製過程中很可能會錄製到一些非HTML的元素(如Java小程式、XML、ActiveX元素、JavaScript),這些非HTML元素主要用於包含或去獲取自己的一些資源,例如,JavaScript的JS檔案用於呼叫載入多個圖片。對於這類非HTML的元素,錄製時有三種方式:
Recordwithinthecurrentscriptstep:在錄製時對於非HTML資源並不會生成一個新的功能。它列出所有相關資源的參數,如web_url、web_link和web_submit_data。這些web功能的參數使用EXTRARES標示。
如以下程式碼:
web_url(「index.asp」,
「URL=http://www.daisy.com/index.asp」,
「TargetFrame=」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=」,
「Snapshot=t2.inf」,
「Mode=HTML」,
EXTRARES,
「Url=http://www.daisy.com/ScrollApplet.class」,「Referer=」,ENDITEM,
「Url=http://www.daisy.com/board.txt」,「Referer=」,ENDITEM,
「Url=http://www.daisy.com/nav_login1.gif」,ENDITEM,
…
LAST);
Recordinseparatestepsanduseconcurrentgroups:在一個組中記錄這些單獨的步驟,爲每個非HTML資源建立一個新的功能(但不包括一些頁面的功能,如web_url、web_link等)。所有的web_url資源都將放置並行組中(並行組由web_concurrent_start和web_concurrent_end進行標示)。
如以下程式碼:
web_url(「index.asp」,
「URL=http://www.daisy.com/index.asp」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=」,
「Snapshot=t2.inf」,
「Mode=HTML」,
LAST);
web_concurrent_start(NULL);
web_url(「ScrollApplet.class」,
「URL=http://www.daisy.com/ScrollApplet.class」,
「Resource=1」,
「RecContentType=application/octet-stream」,
「Referer=」,
LAST);
web_url(「board.txt」,
「URL=http://www.daisy.com/board.txt」,
「Resource=1」,
「RecContentType=text/plain」,
「Referer=」,
LAST);
web_concurrent_end(NULL);
Donotrecord:不記錄,對於非HTML元素不記錄。
注意:使用HTML-Based模式錄製時,VuGen插入目標幀到web_url函數中時,VuGen會在run-time執行的瀏覽器中和結果報告中顯示頁面的正確性。
如以下程式碼:
web_url(「buttonhelp.gif」,
"URL=http://www.hplab.com/home?com/rstr?BV_EngineID…,
「TargetFrame=main」,
「Resource=0」,
「RecContentType=text/html」,
"Referer=http://www.hplab.com/home?..
「Snapshot=t5.inf」,
「Mode=HTML」,
LAST);
URL-basedscript方式:將每條用戶端發出的請求錄製成一條語句,對LoadRunner來說,在該模式下,一條語句只能建立一個到伺服器的連線,並將通訊過程中的很多隱藏的資訊都錄製出來(如session、cookie)。LoadRunner提供了web_concurrent_start()和web_concurrent_end()函數模擬URL-basedscript的工作方式。
下面 下麪以URL-basedscript方式錄製一個登錄的功能,錄製後的程式碼如下:
web_url(「WebTours」,
「URL=http://127.0.0.1:1080/WebTours/」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=」,
「Snapshot=t1.inf」,
「Mode=HTTP」,
LAST);
web_concurrent_start(NULL);
web_url(「header.html」,
「URL=http://127.0.0.1:1080/WebTours/header.html」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/」,
「Snapshot=t2.inf」,
「Mode=HTTP」,
LAST);
web_url(「welcome.pl」,
「URL=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/」,
「Snapshot=t4.inf」,
「Mode=HTTP」,
LAST);
web_concurrent_end(NULL);
web_concurrent_start(NULL);
web_url(「hp_logo.png」,
「URL=http://127.0.0.1:1080/WebTours/images/hp_logo.png」,
「Resource=1」,
「RecContentType=image/png」,
「Referer=http://127.0.0.1:1080/WebTours/header.html」,
「Snapshot=t3.inf」,
LAST);
web_url(「webtours.png」,
「URL=http://127.0.0.1:1080/WebTours/images/webtours.png」,
「Resource=1」,
「RecContentType=image/png」,
「Referer=http://127.0.0.1:1080/WebTours/header.html」,
「Snapshot=t5.inf」,
LAST);
web_concurrent_end(NULL);
web_concurrent_start(NULL);
web_url(「home.html」,
「URL=http://127.0.0.1:1080/WebTours/home.html」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true」,
「Snapshot=t6.inf」,
「Mode=HTTP」,
LAST);
web_url(「nav.pl」,
「URL=http://127.0.0.1:1080/WebTours/nav.pl?in=home」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/welcome.pl?signOff=true」,
「Snapshot=t7.inf」,
「Mode=HTTP」,
LAST);
web_concurrent_end(NULL);
web_url(「mer_login.gif」,
「URL=http://127.0.0.1:1080/WebTours/images/mer_login.gif」,
「Resource=1」,
「RecContentType=image/gif」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home」,
「Snapshot=t8.inf」,
LAST);
web_submit_data(「login.pl」,
「Action=http://127.0.0.1:1080/WebTours/login.pl」,
「Method=POST」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home」,
「Snapshot=t9.inf」,
「Mode=HTTP」,
ITEMDATA,
「Name=userSession」,「Value=108749.254191981ffQDHiQpHzcfDDfzcpHDifHf」,ENDITEM,
「Name=username」,「Value=test1」,ENDITEM,
「Name=password」,「Value=1」,ENDITEM,
「Name=JSFormSubmit」,「Value=off」,ENDITEM,
「Name=login.x」,「Value=63」,ENDITEM,
「Name=login.y」,「Value=9」,ENDITEM,
LAST);
web_concurrent_start(NULL);
web_url(「nav.pl_2」,
「URL=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/login.pl」,
「Snapshot=t10.inf」,
「Mode=HTTP」,
LAST);
web_url(「login.pl_2」,
「URL=http://127.0.0.1:1080/WebTours/login.pl?intro=true」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=http://127.0.0.1:1080/WebTours/login.pl」,
「Snapshot=t12.inf」,
「Mode=HTTP」,
LAST);
web_concurrent_end(NULL);
web_concurrent_start(NULL);
web_url(「flights.gif」,
「URL=http://127.0.0.1:1080/WebTours/images/flights.gif」,
「Resource=1」,
「RecContentType=image/gif」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home」,
「Snapshot=t11.inf」,
LAST);
web_url(「itinerary.gif」,
「URL=http://127.0.0.1:1080/WebTours/images/itinerary.gif」,
「Resource=1」,
「RecContentType=image/gif」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home」,
「Snapshot=t13.inf」,
LAST);
web_url(「signoff.gif」,
「URL=http://127.0.0.1:1080/WebTours/images/signoff.gif」,
「Resource=1」,
「RecContentType=image/gif」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home」,
「Snapshot=t14.inf」,
LAST);
web_url(「in_home.gif」,
「URL=http://127.0.0.1:1080/WebTours/images/in_home.gif」,
「Resource=1」,
「RecContentType=image/gif」,
「Referer=http://127.0.0.1:1080/WebTours/nav.pl?page=menu&in=home」,
「Snapshot=t15.inf」,
LAST);
web_concurrent_end(NULL);
return0;
選擇URL-basedscript選擇,單擊【URLAdvanced…】,彈出【AdvancedURL】對話方塊。關於URL的高階設定有兩種方式:「CreateconcurrentgroupsforresourcestheirsourceHTMLpage」和「Useweb_custom_requestonly」。
CreateconcurrentgroupsforresourcestheirsourceHTMLpage:將捕獲所有HTML頁面的資源,並將其儲存在併發組中(併發組使用web_concurrent_start和web_concurrent_endstatements兩個函數標識),如果不選中該選項時,HTML頁面資源將會分成獨立的、單獨的web_url步驟,但並不放入並行組中。
如以下程式碼:
web_concurrent_start(NULL);
…
web_url(「ClickHereForAdditionalRestrictions」,
「URL=http://www.hplab.com/restrictions.html」,
「Resource=0」,
「RecContentType=text/html」,
"Referer=http://www.hplab.com/home?..
「Snapshot=t4.inf」,
「Mode=HTTP」,
LAST);
web_url(「buttonhelp.gif」,
"URL=http://www.hplab.com/home?com/rstr?BV_EngineID…,
「Resource=0」,
「RecContentType=text/html」,
"Referer=http://www.hplab.com/home?..
「Snapshot=t5.inf」,
「Mode=HTTP」,
LAST);
…
web_concurrent_end(NULL);
Useweb_custom_requestonly:如果錄製的是非瀏覽器的應用程式,可以設定VuGen自定義HTTP請求,在LoadRunner中使用web_custom_reques函數來實現,不管內容如何。
如以下程式碼:
web_custom_request(「www.hplab.com」,
「URL=http://www.hplab.com/」,
「Method=GET」,
「Resource=0」,
「RecContentType=text/html」,
「Referer=」,
「Snapshot=t1.inf」,
「Mode=HTTP」,
LAST);
選擇HTML-basedscript還是URL-basedscript,應該根據實際需要進行,下面 下麪是一些常見的參考原則:
1.基於瀏覽器的應用程式推薦使用HTML-basedscript。
2.不是基於瀏覽器的應用程式推薦使用URL-basedscript。
3.如果基於瀏覽器的應用程式中包含了JavaScript,並且該指令碼向伺服器發送了請求,比如DataGrid的分頁按鈕等,推薦使用URL-basedscript。
4.基於瀏覽器的應用程式中使用了HTTPS安全協定,建議使用URL-basedscript。如果使用HTML-basedscript模式錄製後不能成功回放,可以考慮改用URL-basedscript模式來錄製。因爲這種情況多是由上面所列舉的原因所引起的。
Advanced索引標签
Advanced選項是設定指令碼回放的高階選項,如圖所示。
Savesnapshotresourceslocally:表示執行結果中儲存一個快照。
AddcommentstoscriptforHTTPerrorswhilerecording表示出現錯誤時會自動新增註 加注釋。
點選Headers…按鈕,會彈出HTTPHeaders設定對話方塊,如圖所示。在該對話方塊中可以選擇需要錄製的Headers,以便伺服器能夠正確處理編輯資訊。需要注意的是Accept-Language選項,像Websphere這類伺服器會根據HTTP請求中的Header來確定編碼。
Correlation索引標签
Correlation索引標签用來對指令碼中的關聯屬性進行設定,如圖3-19所示。LoadRunner包括兩種規則:一是內建規則;二是:自定義的規則;LoadRunner會預設自帶一些內建規格。在錄製時選中需要的關聯規則,錄製指令碼過程中LoadRunner會自動匹配需要關聯的規格,並生成關聯函數。如果當前的這些關聯規則無法滿足錄製的需求,那麼可以點選【NewApplication】按鈕來新建一個關聯,再點選
【NewRule】按鈕爲該關聯新建一個規則。