【轉載】LoadRunner用戶行為模擬器 《第三篇》
轉載出處:https://www.cnblogs.com/kissdodog/p/3759270.html
用戶行為模擬器簡稱VU,VU通過運行VU腳本模擬了用戶對軟件的操作行為。VU是基於網絡協議的。很明顯,被測服務器是通過各種各樣的網絡協議與客戶端打交道的。VU要“騙過”被測服務器,當然就要遵守這些協議,按規矩、按步驟來執行動作,否則就會吃“閉門羹”。
基於網絡協議的腳本的一個好處是,我們可以使用相對少的硬件資源,來生成大量的虛擬用戶負載。相比之下,WinRunner和QTP腳本時基於界面事件的,它在一臺主機上同時只能運行一個虛擬用戶的腳本,因為一個虛擬用戶會占用整個主機的資源。
所以可以有如下結論:
- VU不關心用戶在界面發生的事情(如用戶鼠標移動、填寫WebForm數據)等。
- VU中的操作關聯與界面上的操作關聯是不一致的。如正常用戶的操作是,打開列表頁,點擊一行進入詳細頁面。而LoadRunner只記錄一個請求,以及這個請求的參數直接進入,對它來說根本沒有打開列表頁的步驟。
一、錄制腳本
VU通過錄制用戶在客戶端軟件的操作來直接生成腳本,用戶的每個協議級的操作以LoadRunner的API函數方式記錄在腳本裏。回放腳本的時候,通過執行API函數來模擬最初用戶的操作動作。
1、選擇協議
協議有好多種,是用哪種協議當時你開發的時候你自然會知道。目前我一般用的都是Web(HTTP/HTML)協議。
當我們試圖創建一個新的VUser的時候,就會彈出協議選擇對話框。
有兩種協議選擇方式:單協議模式和多協議模式。
(1)、單協議模式:當用戶以單協議錄制時,VU只錄制在既定協議上的用戶操作,在VU中我們可以使用單協議模式選擇任何一種協議。
(2)、多協議模式:當用戶以多協議錄制時,VU錄制幾個協議上的操作。並不是任意的協議都可以組合成多協議模式。
2、規劃腳本結構
在錄制時,用戶可以選擇哪些操作生成腳本在vuser_init、Action和vuser_end中,同時,也可以在錄制時隨時加入transaction的定義、註釋和同步點。VU錄制工具條如下所示:
3、HTTP Vuser中的URL mode和HTML mode
在錄制之前,我們需要設置錄制選項:
在默認情況下,選擇“HTML-based script”,說明腳本中采用HTML頁面的形式來表示,這種方式的Script腳本容易維護,容易理解,推薦以這種方式錄制。
“URL-based script”說明腳本中的表示采用基於URL的方式,所有的HTTP的請求都會被錄制下來,單獨生成函數,所以URL模式生成的腳本顯得有些雜亂。
Action() { web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTML", LAST); }
而以HTML模式錄制,則生成如下腳本:
Action() { web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTTP", LAST); web_url("Default.css", "URL=http://127.0.0.1:9090/Resources/CSS/Default.css", "Resource=1", "RecContentType=text/css", "Referer=http://127.0.0.1:9090/Account/Login", "Snapshot=t4.inf", LAST); web_url("gwu1.jpg", "URL=http://127.0.0.1:9090/Resources/Images/login/gwu1.jpg", "Resource=1", "RecContentType=image/jpeg", "Referer=http://127.0.0.1:9090/Account/Login", "Snapshot=t5.inf", LAST);
... 省略N個 }
是選擇HTML還是URL錄制,有以下參考原則:
- 基於瀏覽器的應用程序推薦使用HTML-based script。
- 不是基於瀏覽器的應用程序推薦使用URL-based script。
- 如果基於瀏覽器的應用程序中包含了JavaScript並且該腳本向服務器產生了請求,比如DataGrid分頁按鈕等,也要使用URL-based script方式錄制。
- 基於瀏覽器的應用程序中使用了HTTPS安全協議,使用URL-based script方式錄制。
4、查看日誌
在錄制和回放的時候,VU會分別把發生的事件記錄成日誌文件,這些日誌有利於我們跟蹤VU和服務器的交互過程。我們可以通過VU輸出窗口觀察日誌,也可以到腳本目錄中直接查看文件。
1、執行日誌(Execution Log,新版本是Replay Log)
腳本運行時的輸出都記在這個Log裏。
“執行日誌”中使用了不同顏色的文本。
- 黑色:標準輸出信息。
- 紅色:標準錯誤信息。
- 綠色:用引號括起來的文字字符串(例如URL)。
- 藍色:事務信息(開頭、結束、狀態和持續時間)。
2、錄制腳本(Recording Log)
當錄制腳本時,Vugen會攔截Client端(瀏覽器)與Server端(服務器)之間的對話,並且通通記錄下來,產生腳本。在Vugen的Recording Log中,我們可以找到瀏覽器與服務器之間所有的對話,包含通信內容、日期、事件、瀏覽器的請求、服務器的響應內容等。腳本和Recording Log最大的差別在於,腳本只記錄了Client端要對Server端的請求內容,而Recording Log則是完整記錄二者的對話。所以,通過錄制日誌,我們能夠更加清楚地看到客戶端與服務器的交互。
3、產生日誌(Generation Log)
產生日誌記錄了腳本錄制的設置、網絡事件到腳本函數的轉化過程。
提示:腳本能正常運行後應禁用日誌。因為產生及寫入日誌需占用一定資源。
二、回放腳本
單擊run按鈕,或按快捷鍵“F5”就可以運行腳本。VU腳本運行工具條如下:
錄制完成之後,最好先運行一次腳本,因為在跑測試之前必須先確保腳本沒有錯誤。
三、關聯
關聯的作用是客戶端每次的訪問,服務器都會有動態的內容產生,如果這個動態內容跟不上,則服務器就報錯的情況。如SessionId,假如每次訪問,服務器都為其分配一個session號(隨機的)導致報錯時,此時就要對seesion做關聯。
這個看起來好像很難的樣子,先跳過, 用到再學。
四、腳本視圖和樹視圖
VU提供兩種視圖來查看腳本的內容,一個是腳本視圖,另一個是基於圖標的樹視圖。
所有類型的Vuser都有文本腳本視圖,但是只有特定的Vuser才會有樹視圖。
1、樹視圖(Tree View)
Tree View也叫做基於icon的View,也就是說,腳本的每個函數在Tree View中都以一個帶有icon的節點來代替。可以點擊工具欄=>"Tree"按鈕或者在“View”=>“Tree View”,顯示VU樹視圖。
Tree View的好處是使用戶更方便地修改腳本,Tree View支持拖拽,用戶可以把任意一個節點拖拽到他想要的地方,從而達到修改腳本的目的。用戶可以右鍵單擊節點,進行修改/刪除當前函數參數屬性,增加函數等操作,通過Tree View能夠增加LoadRunner提供的部分常用通用函數和協議相關函數。比如Web Service Vuser就不能通過Tree View參數化一些復雜的數據類型,在這種情況下,就需要Script View了。
2、腳本視圖(Script View)
在Script View中能夠看到一行行的API函數,Script View適合一些高級用戶,通過Script View向腳本中增加一些其他的API函數。可以單擊工具欄上的"Script"按鈕或者在"View"菜單下選擇"Script View",顯示VU腳本視圖。
當用戶在Script View中對腳本做了修改之後,Tree View也會做相應的變化。如果腳本有語法錯誤,Script View將不能轉化為Tree View或縮略圖。
3、理解Snapshot
napshot,顧名思義,就是快照,代表當前的step,Snapshot顯示了客戶端執行完當前step後的樣子,在Tree View右側的frame中可以查看Snapshot,在LoadRunner 8.0中,Snapshot包含Page View、Client Request和Server Response。
Snapshot有兩種生成方式,一種是在record的時候生成,另一種是在replay的時候生成。可以對比兩種方式生成的Snapshot,以發現哪些是動態值,需要參數化。
五、事務、同步點和思考時間
1、Transaction(事務)
在LoadRunner裏,我們定義事務主要是為了度量服務器的性能。每個事務度量服務器響應指定的Vuser請求所有的時間,這些請求可以是簡單任務,也可以是復雜任務。
要度量事務,需要插入Vuser函數以標記任務的開始和結束。在腳本內,可以標識的事務不受數量限制,每個事務的名稱都不同。
在場景執行期間,Controller將度量執行每個事務所用的時間。場景運行後,可使用LoadRunner的圖和報告來分析各個事務的服務器性能。
設置Transaction的方法如下:
- 選擇新Transaction開始點,在被度量腳本段之前插入lr_start_transaction。
- 選擇新Transaction結束點,在被度量腳本段之後插入lr_end_transaction。
下面的腳本例子中將登陸操作設為一個名為"login"的事務:
lr_start_transaction("login_start"); web_submit_data("login", "Action=http://127.0.0.1:9090/account/login", "Method=POST", "RecContentType=text/html", "Referer=http://127.0.0.1:9090/Account/Login", "Snapshot=t19.inf", "Mode=HTTP", ITEMDATA, "Name=userName", "Value=xpj", ENDITEM, "Name=submitBtn", "Value= ", ENDITEM, "Name=password", "Value=123", ENDITEM, LAST); lr_end_transaction("login_end",LR_AUTO);
如果手工插入的Transaction如果稱為“顯式事務”的話,那麽LoadRunner還提供了一種“隱式事務”的機制,在VU的Run-time Settings中又稱為“自動事務”。
在Run-time Settings中,在Miscellaneous選項卡的Automatic Transactions中定義自動事務。
Vuser => Run-time Setting => Miscellaneous
可以設置LoadRunner直接按事務處理Vuser中的每個Action或step。這裏,Action指的是vuser_init、Action和vuser_end三大函數,而step指的是LoadRunner執行的每個函數。LoadRunner將Action名或step指定為事務名。默認情況下,將啟用按Action使用自動事務的功能。
- 要禁用按操作使用自動事務的功能,清除"Define each action as a transaction"復選框(默認情況下啟用)。
- 要啟用按步驟使用自動事務的功能,選中"Define each step as a transaction"復選框。
Transaction的開始點和結束點必須在一個Action中,跨越多個Action是不允許的。Transaction的名字在腳本中必須是唯一的,當然也包括在多個Action的腳本中唯一。你也可以在一個Transaction中創建另外一個Transaction,叫做Nested Transaction。
2、Rendezvous Point同步點
在系統上模擬較重的用戶負載,需要同步各個Vuser以便在同一時刻執行任務。通過創建集合點,可以確保多個Vuser同時執行操作。當某個Vuser到達該集合點時,Controller會將其保留,直到參與該集合的全部Vuser到達。Controller才允許Vuser執行。
可通過將集合點插入到Vuser腳本中來指定回合位置。在Vuser執行腳本並遇到集合點時,腳本將暫停執行,Vuser將等待Controller的允許才繼續執行。Vuser被從集合釋放後,將執行腳本中的下一個任務。
lr_rendezvous("the begin port"); //集合點 web_submit_data("login", "Action=http://127.0.0.1:9090/account/login", "Method=POST", "RecContentType=text/html", "Referer=http://127.0.0.1:9090/Account/Login", "Snapshot=t19.inf", "Mode=HTTP", ITEMDATA, "Name=userName", "Value=xpj", ENDITEM, "Name=submitBtn", "Value= ", ENDITEM, "Name=password", "Value=4297F44B13955235245B2497399D7A93", ENDITEM, LAST);
註意:
- 只能在Action中添加集合點(不能在vuser_init或vuser_end中添加)。
- 同步點只有多用戶並發的場景,同步點的意義才表現出來。
3、註釋
LoadRunner支持C語言的註釋方法:
多行註釋:
/* 這是多行註釋 */
單行註釋:
//這是單行註釋
4、Think Time(思考時間)
用戶在執行兩個連續操作期間等待的時間成為“思考時間”。Vuser使用lr_think_time函數模擬用戶思考時間。錄制Vuser腳本時,Vugen將錄制實際的思考時間並將相應的lr_think_time腳本插入到Vuser腳本。此功能通過lr_think_time實現。
lr_think_time參數的單位是秒,比如lr_think_time(5)意味著LoadRunner執行到此條語句時,停留5秒,然後再繼續執行後面的語句。
如果不想在腳本中執行Think Time語句,需要逐條語句刪除,這是非常麻煩,LoadRunner提供了再Run-time Settings中可以設置直接忽略Think Time,而不用修改腳本。
有Think Time比沒有Think Time的腳本對服務器造成的壓力更小,但是有Think Time才是更符合用戶的實際工作場景的。
Vuser => Run-time Settings => General => Think Time
六、數據驅動-參數化(Parameters)
數據驅動就是把測試腳本和測試數據分離開來的一種思想,腳本體現測試流程,數據體現測試案例。數據不寫死在腳本裏面,這樣大大提高了腳本的可復用性。
1、為什麽需要參數化
在錄制程序運行的過程中,Vugen(腳本生成器)自動生成了腳本以及錄制過程中實際用到的數據。在這個時候,腳本和數據是混在一起的。
如登錄操作:
web_submit_data("login", "Action=http://127.0.0.1:9090/account/login", "Method=POST", "RecContentType=text/html", "Referer=http://127.0.0.1:9090/Account/Login", "Snapshot=t19.inf", "Mode=HTTP", ITEMDATA, "Name=userName", "Value=xpj", ENDITEM, "Name=password", "Value=123123", ENDITEM, LAST);
在登錄操作中,很明顯xpj與123123是填入的數據,如果Controller裏以多用戶方式運行這個腳本的時候,每個虛擬用戶都會以同樣的用戶名"robin"、密碼"123123"去登錄系統。這樣做性能測試,不太眼睛,服務器大多會采用緩存功能提高系統性能,以同樣的用戶名/密碼登錄系統的緩存命中率會很高,也要快得多。
因此,LoadRunner支持參數變量。
web_submit_data("login", "Action=http://127.0.0.1:9090/account/login", "Method=POST", "RecContentType=text/html", "Referer=http://127.0.0.1:9090/Account/Login", "Snapshot=t19.inf", "Mode=HTTP", ITEMDATA, "Name=userName", "Value={username}", ENDITEM, "Name=password", "Value={password}", ENDITEM, LAST);
參數化後,用戶名xpj被一個參數{username}替換,密碼被另外一個參數{password}替換。其中{username}和{password}分別和參數文件關聯,在腳本運行時,用戶名和密碼的值從參數{username}和{password}中獲得。而我們會在後面介紹LoadRunner有一套機制來保證參數的使用和變化,這樣就實現了腳本與數據的分離。
參數化是我們學習LoadRunner中經常用到的功能。除了實現數據驅動之外,參數化腳本還有以下兩個優點:
- 可以使腳本的長度變短;
- 可以增強腳本的可讀性和可維護性;
實際上,參數化的過程如下:
- 在腳本中用參數取代常量值;
- 設置參數的屬性以及數據源;
2、參數的創建
LoadRunner對腳本中參數個數沒有限制,我們可以在一個腳本中創建任意多個參數。
選擇參數類型:
- Parameter name:輸入參數名稱;
- Parameter type:選擇參數類型;
參數類型說明
- Data Files:這是我們最長使用的一種參數類型,它的數據存在於文件中。該文件的內容可以手工添加,也可以利用LoadRunner的Data Wizard從數據庫中導出。
- User-Defined Functions:調用外部DLL函數生成的數據
- Internal Data:虛擬用戶內部產生的數據。Internal Data包括以下幾種類型:
- Date/Time:用當前的日期/事件替換參數。要指定一個Date/Time的格式,菜單中可以選擇格式。格式要與腳本中錄制的格式保持一致。
- Group Name:用虛擬用戶組名稱替換參數。在創建scenario的時候,你可以指定虛擬用戶組的名稱。
- Load Generator Name:用腳本負載生成器的名稱替換參數。負載生成器是虛擬用戶在運行的計算機。
- Iteration Number:用當前的叠代數目替換參數。
- Random Number:用一個隨機數替換參數。通過指定最大值和最小值來設置隨機數的範圍。
- Unique Number:用一個唯一的數字來替換參數。你可以指定一個起始數字和一個塊的大小。
- VuserID:用分配給虛擬用戶的ID替換參數,ID是由LoadRunner的控制器在scenario運行時生成的。如果從腳本生成器運行腳本的話,虛擬用戶的ID總是-1.
然後為該參數設置不同的值。
如果想用以前定義過的參數來代替常量字符串的話,選中該字符串,單擊右鍵,然後選擇“Use existing parameters”,從彈出的子菜單中選擇參數,或者用"Select from Parameter List"來打開參數列表對話框。
對於已經用參數替換過的地方,如果想取回原來的值,那麽就在參數上單擊右鍵,然後選擇"Restore Original value"。
不是所有的數據都可以參數化
在LoadRunner中,只有函數的參數才能參數化,不能參數化非函數參數的數據。
如lr_eval_string,我們可以在Vuser腳本中的任何地方使用它來參數化數據,lr_eval_string用來得到一個參數的值,而參數可以預先在LoadRunner的Parameter List裏定義好,也可以是之前通過其他函數創建的。
//通過lr_save_datetime把七天後的時間保存在date參數中 lr_save_datetime("%d %m %y", DATE_NOW + (ONE_DAY * 7),"date"); //通過lr_eval_string把date參數中的值取出來,lr_output_message的輸出值為七天後的時間 lr_output_message("Date is s%",lr_eval_string("{date}"));
更多的函數可以翻查LoadRunner函數手冊。lr_eval_string函數的返回值是一個指向參數值的指針,如果這個指針向的內存是LoadRunner內部分配的,每次Iteration後自動釋放。如果在Iteration中還有多層循環進行參數化,那麽最好不要使用lr_eval_string了,這會導致內存遲遲不能釋放。在這種情況下,應該使用lr_eval_string_ext,同時配對使用lr_eval_string_ext_free來及時釋放內存。
3、定義參數的屬性
1、數據文件
數據文件包含著腳本執行過程中虛擬用戶訪問的數據。局部和全局文件中都可以存儲數據。可以指定現有的ASCII文件、用腳本生成器創建一個新的文件或者引入一個數據庫。數據文件中的數據是以表的形式存儲的。一個文件中可以包含很多參數值。每一列包含一個參數的數據,列之間用分隔符隔開,比如用逗號。
如果使用文件作為參數的數據源,必須指定以下內容:文件的名稱和位置、包含數據的列、文件格式、包括列的分隔符、更新方法。
如果參數的類型是"File",打開參數屬性(Parameter Properties)對話框,設置文件屬性如下:
(1)、在"File path"中輸入文件的位置,或者單擊"Browse"按鈕指定一個已有文件的位置,如圖:
在默認情況下,所有新的數據文件名都是"parameter_name.dat",註意,已有的數據文件的後綴必須是.dat。
(2)、單擊"Edit With Notepad"按鈕,打開記事本,裏面第一行是參數的名稱,第二行是參數的初始值。使用諸如逗號之類的分隔符將列隔開。對於每一個新的表行開始一行新的數據。
在沒有啟動記事本的情況下如果想添加咧,就在參數屬性對話框中單擊"Add Column"按鈕,打開"Add new column"對話框。輸入新列的名稱,單擊"OK"按鈕,腳本生成器就會將該列添加到表中,並顯示該列的初始值。
(3)、在"Select column"部分,致命選擇參數數據的列。可以指定列名或列號。列號是包含你所需要數據的列的索引;列名顯示在每列的第一行。
(4)、在"Column delimiter"中輸入列分隔符,可以指定逗號、空格符等。
(5)、在"First data line"中,在腳本執行的時候選擇第一行數據使用。列標題是第0行,若從列標題後面的第一行開始的話,那麽就在"First data line"中輸入1;如果沒有列標題,就輸入0;
(6)、在"Select next row"中輸入更新方法,以說明虛擬用戶在獲取第一行數據後,下一行數據按照什麽規則來取。方法可以是:順序的(Sequential)、隨機的(Random)、唯一的(Unique),或者與其他參數表相同的行(Same Line as..)。
- 順序(Sequential):該方法順序地給虛擬用戶分配參數值。取的時候會逐次取下一行數據,到最後一條又循環回取第一行。
- 隨機(Random):該方法在每次叠代的時候會從數據表中隨機取一行數據。
- 唯一(Unique):該方法分配一個唯一有順序的值給每個虛擬用戶。10行數據,能分10次。第11個虛擬用戶來取LoadRunner會報錯,提示數據不夠用。
- 與以前定義的參數取同一行(Same Line As <parameter>):該方法從以前定義過的參數中同樣的一行分配數據,但必須指定包含有該數據的列。在下拉列表中會出現定義過的所有參數列表。註意:至少其中的一個參數必須是Sequential、Random或Unique。
NUser,password xpj,111 //前面定義了xpj,則後面是111(同一行) fzc3,222 fzc1,333
(7)、Update value on,數據的更新方法
我們做事主要考慮3個因素:什麽時候做,什麽地點做,還有怎麽做。對應參數表的讀取規則來說,上面的Select next row指的是怎麽取新值,是順序還是隨機等。而這裏Update value on指的是什麽時候取新值。
LoadRunner並不是每次取值都是要取新值的。所以就有了以下幾種取新值的策略:
- Each iteration:每次叠代就要取新值(在同一個叠代中,無論讀幾次參數,獲得的都是同一個參數值)。
- Each occurrence:只要取一次,就要新的(同一個叠代中,讀一次參數,就要取其新值,而新值從哪裏來,有Select next row來規定)。
- Once:在所有的循環中都使用同一個值(只取一次,也就是說,這個參數只有一個值)。
(8)、When out of values,超出範圍:(選擇數據位Unique時才可用到)
- Abort Vuser:中止。
- Continue in cyclic manner:繼續循環取值。
- Continue with last value:取最後一個值。
(9)、Allocate Vuser values in the Controller在控制器中分配值:(選擇數據為unique時才可用到)
- Automatically allocate block size:自動分配。
- Allocate()calues for each Vuser:指定一個值。
4、高級-從已存在的數據庫中導入參數數據
LoadRunner允許你利用參數化從已經存在的數據庫中導入數據。可以使用下列兩種方式之一:
(1)、使用Microsoft Query(要求在系統上先安裝MS Query)。
(2)、指定數據庫連接字符串和SQL語句。
用戶腳本生成器在從數據庫中導入數據的過程中提供了一個向導。在向導中,指明如何導入數據。通過MS Query創建查詢語句或者直接書寫SQL語句。在導入數據以後,以.dat為後綴並作為正規的參數文件保存。要開始導入數據庫中數據的過程,在參數屬性對話框中單擊"Data Wizard"按鈕,則打開數據庫查詢向導。
由於第一種要安裝MS Query,下面介紹第二種方式。
指定數據庫連接或SQL語句
1.選擇"Specify SQL statement manually",下一步;
2.打擊"Create"按鈕,指定一個新的連接字符串。
3.選擇已有的數據源,或者單擊"新建"按鈕創建一個新的數據源。向導將提示你完成創建ODBC數據源的過程。在完成後,連接字符串就會在連接字符串框中顯示出來。
點擊下一步,在選擇一個路徑用於保存文件數據源。註意後綴是.dsn。
下一步後,點擊完成。
此時,在D盤會生成一個D:xxx.dsn文件。
在彈出的對話框中輸入數據庫連接的信息
4.在SQL statement框中,輸入或粘貼SQL語句。
5.輸入SQL語句後,單擊"Finish"按鈕。數據庫記錄將以data文件的形式顯示在參數列表對話框中。
6.在"Select column"部分中,指定包含當前參數數據的列。你可以指定列號或者列名。
7.從"Select next row"列表中選擇一個更新方法來告訴虛擬用戶在腳本指定的過程中如何選擇表中的數據。可選項是:Sequential、Random、Unique或者Same Line as。
8.如果從Update value on中選擇"Each iteration",虛擬用戶在每次叠代的時候都會使用新的一行數據而不是重復同樣的數據。
8、檢查點(Check point)
1、為什麽需要檢查點
LoadRunner的很多API函數的返回值會改變腳本的運行結果。比如web_find函數,如果它查找匹配的結果為空,它的返回值就是LR_FAIL,整個腳本的運行結果也將置為FAIL;反之,查找匹配成功,則web_find返回值是LR_PASS,整個腳本的運行結果置為PASS。而腳本的結果則反應在Controller的狀態面板上和Analysis統計結果中。
但是僅僅通過腳本函數執行結果來決定整個腳本的成功/失敗,這並不嚴謹。因為腳本往往是在執行一個業務流程,VU腳本函數本身是協議級的,它執行的失敗會引起整個業務的失敗,但它運行成功卻未必意味著業務會成功。比如,要測100人登錄一個Web郵件系統,此郵件系統限制不允許同一個IP登錄兩個用戶。這時,如果LoadRunner沒有開啟多IP欺騙功能的話,第一個虛擬用戶登錄成功後,第二個虛擬用戶試圖登錄,系統將返回一個頁面,提示用戶"你已經登錄本系統,請不要重復登錄!"。在這種場景下,如果沒有設檢查點來判斷這個頁面,那麽VU認為它已經成功地發送了請求,並接到了頁面結果(http狀態碼200,雖然是個錯誤頁面)。這樣VU就認為這個請求時成功的,但事實這次請求用於性能測試結果是不準確的。這個時候,我們就要采用檢查點來判斷結果。
檢查點(Check Point)並不是一個LoadRunner裏專有的概念。在WinRunner和QTP中就有檢查點。對於自動化測試來講,檢查點是一個很重要的功能,它的作用是驗證程序的運行結果是否與預期結果相符。
2、檢查點實施1:ContentCheck定義
在"導航條Vuser => Run-time settings => ContentCheck"中,這裏的設置是為了讓Vugen檢測何種頁面為錯誤頁面。如果被測的Web應用沒有使用自定義錯誤頁面,那麽這裏不用更改;如果被測的Web系統使用了自定義錯誤頁面,那麽這裏需要定義,以便讓Vugen在運行中檢測,服務器返回的頁面是否包含預定義的字符串,從而判斷該頁面是否為錯誤頁面,如果是,Vugen就停止運行,指示運行失敗。
3、檢查點實施二:檢查函數
另外一種設置方法是在Web Vuser裏,通過檢查函數來完成檢查點功能。Web Vuser提供Image Check和Text Check兩種方式,其原理就是在上一個請求頁面的函數完成後,運行檢查函數,在結果頁面中搜索指定的圖片或關鍵文字等。
檢查關鍵字示例:
web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTTP", LAST); web_find("login Check", "expect=notfound", "matchcase=yes", "onfailure=abort", "report=failure", "repeat=no", "what=頁面已刪除", LAST )
在這個例子中,web_find函數在login頁面中搜索"頁面已刪除"關鍵字。有關web_find函數的各個參數的含義以及使用方法。
檢查圖片示例:
web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTTP", LAST); web_image_check("NotFount", new String[]{"Alt = NotFound", web.LAST});
web_image_check在login頁面中查找alt屬性為NotFount的圖片。
VU的Web Vuser還提供了和web_find十分類似的另外一個檢查點函數:web_reg_find。
web_reg_find裏的reg意為註冊(register)。因此web_reg_find和web_find的不同之處是web_reg_find是先註冊,後查找;而web_find是查找前面的請求結果。因此,我們再使用web_reg_find函數的時候,將它放在請求語句的前面。
web_reg_find("Text=ABC","SaveCount=abc_count",LAST); web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTTP", LAST); if(strcmp(lr_eval_string("{abc_count}"),"0") == 0) Action A else Action B
上面腳本運行的過程是:如果web_reg_find在login頁面中沒有找到"ABC"字符串,則執行Action A;如果找到了一次或一次以上,則執行Action B。
web_find和web_reg_find函數兩者是有一些區別的:
web_reg_find("Text=ABC","SaveCount=abc_count",LAST); web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTTP", LAST); if(strcmp(lr_eval_string("{abc_count}"),"0") == 0) Action A else Action B
- web_reg_find先註冊的優勢是腳本能夠一邊接收Server的數據緩沖,一邊進行查找,提高了查找的效率。
- web_reg_find的參數與web_find並不完全一樣,其中有個參數叫做SaveCount,它能夠記錄查找匹配的次數,而web_find的機制是一旦查找匹配成功就立即返回,並不繼續查找和記錄匹配次數。
- VU run time設置中的"enable image and text check"對web_find有效,而對web_reg_find無效。
4、檢查點設置技巧
如何加入檢查點,才能檢查出正確的結果。與事實相符,有如下技巧:
- 它必須滿足是驗證事務通過與與否的充分必要條件。檢查點通過,我們就能夠確信系統是一個正常的狀態。
- 檢查點可以是常量,也可以是變量。
- 檢查點可以是文本、圖像文件,也可以是數據庫記錄等。
9、高級-腳本錯誤處理機制
VU提供了一套在出錯情況下的腳本處理機制。VU的錯誤處理機制可設定Vuser在執行腳本時遇到錯誤怎樣處理。當Vuser遇到錯誤時,可以由兩種處理策略:
- 一是停止執行腳本,這適用於嚴重的問題。
- 二是忽略這個錯誤,繼續執行下去。
默認情況下,當檢測到錯誤時,Vuser將停止執行腳本,在Run-time Settings中我們就可以看到它的默認設置。
如不想VU在出錯後結束,而是繼續執行。那麽在運行設置中,可以勾選"Continue on error"(出現錯誤時仍繼續)。這個設置適用於整個Vuser腳本,它是一個全局開關。
這種方法有一個問題,不夠靈活。對於所有的錯誤,都是跳過或停止執行。不能對於不同函數應用不同的錯誤處理機制。對於這種問題,我們只能在腳本使用lr_continue_error函數來自定義實現。
- 使用lr_continue_on_error函數。通過lr_continue_on_error(1)和lr_continue_on_error(0)語句將其括起來。
- 使用lr_continue_on_error函數的腳本段將會覆蓋"出現錯誤時仍繼續"的Run-time Settings運行時設置。
例如,下面的腳本,其運行時設置沒有勾選"Continue on error",VU如果訪問xxx錯誤,將會結束執行腳本。
lr_continue_on_error(1); web_url("Login", "URL=http://127.0.0.1:9090/Account/Login", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTTP", LAST); lr_continue_on_error(0); lr_output_message("finished linking");
在上面的腳本中,幾時web_url函數執行失敗,li_output_message("finished linking")也會被繼續執行。第一個lr_continue_error(1)是將"Continue on error"設為true,其後面的語句的錯誤處理機制都被應用為"Continue on error",直到VU遇見lr_continue_error(0),再將"Continue on error"恢復成false。
【轉載】LoadRunner用戶行為模擬器 《第三篇》