功能介紹
安裝流程
LoadRunner是一款測試系統行為和性能的負債測試工具,通過模擬上千萬用戶實施並發復雜以實時性能監控的方式來確認和查找問題。它是一款付費商業軟件,開發商為HP,個人開發者可以使用社區免費版,社區免費版最大支持50個用戶並發,如果想要更多的就需要付費。
Windows版本的LoadRunner運行依賴於一些其他組件,在安裝時,會檢測本機組件狀態並聯網下載必須組件
如要允許LoadRunner自帶例子,要求LoadRunner安裝到默認目錄,如果修改了默認安裝路徑,就無法使用。
系統組件
LoarRunner安裝完成后,有三個組件,如圖所示
- Virtual User Generator(簡稱VuGen): 用於生成測試腳本,可以采用錄制模式或者編輯模式來生成測試腳本(稱為Vuser Script)
- Controller:用來組織、驅動、管理和監視測試案例
- Analysis:用於分析和圖形化顯示測試結果和報告
工作流程
-
計划
定義好測試目標和測試需求,預期待測試系統達到什么樣的並發量,認為是合格系統
-
建立測試腳本
通過錄制或手動編寫的方式,建立測試腳本
-
構建測試場景
使用Controller來建立壓力測試環境,並且管理和監視測試流程
-
分析結果
使用Analysis來建立圖形化的報告和評估系統性能
使用方式
VuGen有兩種編寫腳本的模式,錄制模式和手動編寫模式。錄制模式,降低編寫腳本的門檻,手動編寫能夠更加精確控制測試流程。
錄制模式
VuGen通過錄制用戶在客戶端軟件的操作來直接生成腳本,用戶每個協議級別的操作都會以LR的API函數方式記錄在腳本中。回放腳本時,通過執行API函數來模擬用戶最初的操作。
錄制模式有兩種級別
- HTML級別(默認級別)
- URL級別
HTML級別:會為隸屬於一個頁面的所有請求錄制成一個單獨的步驟(web_url),產生的腳本簡潔直觀,便於閱讀。
URL級別:為每個服務器對象的請求錄制步驟,一個請求對應一個(web_rul)支持頁面上的JavaApplets和ActiveX對象,對測試過程有更好的控制。
一般來說,基於瀏覽器的應用程序使用HTML級別錄制,不是基於瀏覽器的應用(比如API服務、DataServer服務)可使用URL級別的錄制。如果基於瀏覽器的應用程序中包含了向服務器進行通訊的JS代碼,或者基於瀏覽器的應用中使用HTTPS安全協議,也要使用URL級別錄制。
實際案例
使用URL-Mode錄制方式訪問網站https://www.baidu.com
-
創建腳本項目
-
修改配置
-
設置錄制參數
-
生成錄制腳本
錄制腳本為空的解決方法:
-
關閉已打開的待測試瀏覽器
-
按照如下設置
Recording Options-->Capture level-->
選擇Socket Level Data
或者選擇Socket level and WinNet Level Data
-
打開HTTPS的網站,無法錄制腳本。網上的處理方案
-
重置IE瀏覽器的高級設置
腳本模式
腳本模式,LR支持ANSI C語言,提供豐富的內置函數,幫助用戶編寫測試代碼。除開通用的流程控制外,LR提供了參數化、關聯、腳本模塊化等高級功能。
參數化
參數化是將腳本中的常量轉化為變量的過程,類似於隨機數。LR中提供的隨機變量種類非常豐富,具體設置如下:
遇到的問題:若使用參數化的VuGen腳本運行正常,而通過Controller啟動,提示參數化錯誤,此處需要檢查VuGen腳本參數化賦值方式。
關聯
關聯就是在響應數據中查找特定數據,將特定數據以參數的形式關聯保存起來。例如一個登陸請求通常會返回SessionId,后續指令需要用到SessionId,那么就需要在響應數據中設定好關聯規則和關聯變量,以便在后續流程中使用。
腳本模塊化
腳本模塊化是抽取通用流程函數,提高測試腳本可讀性和可重用性。
LR無法通過包含頭文件來引入具體的功能,原因是LR的C編譯器將所有涉及到的程序文件都打包為一個pre_cci.cc文件,如果直接包含.h頭文件,則在打包混合時,只會包含函數的定義,而沒有實現部分,腳本中執行此函數會出錯。
解決方案:
方法1:多文件編程,直接包含.c實現文件即可,無需.h文件。
方法2:在Actions中右鍵再添加一個Action,假設命名為test,那么這個test.c中的test函數會被自動執行。
輔助功能
-
事務相關
在自動化測試過程中,需要統計一段代碼執行所需時間,可使用LR提供的
lr_strat_transaction
和lr_end_transaction
來標記事務的事務名稱以及開始和結束。每個事務度量服務器響應指定Vuser請求所需的時間,這些請求可以是簡單的請求,也可以是復雜的請求。
事務的開始點和結束點必須在同一個Action中,事務名稱在腳本中必須是唯一,事務允許嵌套。 -
思考時間
用戶在執行兩個連續操作期間等待的時間,稱之為"思考時間",LR提供
lr_think_time
來設置等待時間(單位為秒),支持固定時間以及隨機變動時間等模式。
在測試腳本時,Run-Time Settings -> General -> Think Time 設置為不忽略思考時間,才會生效。 -
集合點
為了模擬多用戶並發操作,需要同步各個Vuser以便在同一時刻執行任務。通過創建集合點,可確保多個Vuser同時執行操作。當某個Vuser到達該集合點時,Controller會將其暫停,直到參與該集合的全部Vuser到達,Controller才允許Vuser執行。例如,同一時間,模擬100用戶一同登陸,登陸操作前設置好集合點(
lr_rendezvous
)。 -
驗證點
在指定HTML文檔中查找指定字符串是否存在,來檢查此項操作是否成功。LR提供
web_reg_find
來實現此功能,此函數需要在請求數據前插入,類似的還有檢查指定圖片是否存在,LR提供web_image_check
函數來完成此功能。 -
日志輸出
將測試過程中的相關信息輸出到日志文件和輸出窗口,方便查看運行信息,輔助問題定位,LR提供
lr_output_message
,lr_log_message
等輸出函數簇,具體參考LR幫助文檔。 -
常用函數
LR的通用函數以lr為前綴,可以在任何協議中使用,根據功能不同,分為信息相關、事務相關、運行相關、參數相關等。
特定協議的函數,這類函數跟錄制時創建的協議類型有關- Web協議:以web為前綴
高級功能IP欺騙
並發用戶
並發用戶產生方式設置如下圖:
選擇進程:場景運行時,會為每一個虛擬用戶創建一個進程(mmdrv.exe),10個用戶並發,就會有10個mmdrv.exe進程。
選擇線程:場景運行時,會將每一個虛擬用戶創建一個線程,一個進程最多可以支持50Vu線程並發,當此方式設定的用戶少於50,在任務管理器上只會看到一個進程。
使用多線程的方式,可在單台機器上高效地發起更多的用戶,但線程資源是從進程資源中分配出來的,同一個進程的多個線程會共享內存空間,可能會引起多個線程的同步問題。但只有支持線程安全的協議,才能使用LR的Vu並發方式。
備注:使用多線程來模擬多個用戶時,會受限於單一進程的資源限制,在實際測試時,會有一些Errors產生。
這些錯誤原因通常是進程可用資源受限。
C Vuser Scrpits
LR支持純C腳本模式,在C Vuser腳本模式下,可以使用標准ANSI C庫函數和語法,LoadRunner內置的C編譯器對C代碼有以下要求:
-
支持標准ANSI C90語言,變量的定義必須要放在可執行代碼之前,一旦在運行語句之間再有定義,會報錯。
-
Vuser腳本無法將某個函數的地址作為回調函數傳遞給庫函數。
-
Vuser不支持結構體參數或結構體返回值,指向結構體的指針是支持的。
-
字符串常量是只讀的,任何嘗試修改一個字符串常量都會觸發訪問異常。
-
一旦加載完DLL, 就可以立即使用其中的函數。
Action() { lr_load_dll("mydll.dll"); // 如果DLL放在腳本目錄里面,可以直接寫相對路徑 myfun(); // myfun() define in mydll.dll. }
注意
-
在C Vuser模式中,不能直接使用
web_url
等內置的網絡函數,如要使用,需要選擇Web-HTTP/HTML類型的腳本。 -
lr__load__dll加載dll不會自動加載其依賴的dll,因此,需要手動先將依賴的dll加載好,才能正確加載。
-
腳本的迭代數設置針對的是腳本內部的Action動作,比如說,設置為3,那么vuser_init執行1次,Action執行3次,vuser_end執行1次。在Action中進行for循環,也可以達到相同的功能
-
在VuUser中設置的迭代次數和在Controller中設置的迭代次數是兩個不同的屬性,前一個是在單獨測試腳本時的迭代次數,后一個是通過並發用戶去執行時設置的迭代次數。
-
如果想要在一個Vuser的一個Action中發起多個事務連接,那么在參數化設置時,就要選擇Random+Each occurence的組合,可以達到目的。
如果一個Vuser中一個Action中發起一次事務,那么在參數化設置時,可以配置Unique+Each occurence,每個Vuser分配一個值。或者是Random模式,不可配置為Sequential模式。
-
每次在Vuser中修改完腳本后,要在Controller組中選擇待執行的組,右鍵Detail->Refresh->[Script + Runtimeing Setting],使得Controller中加載的是最新的測試腳本。
場景控制器Controller
Controller組件是LR的控制中心,用來進行場景設計和執行,在VuGen中編輯完腳本后,將腳本加載到Controller組件中,設計場景好后,即可執行該場景。
Controller提供兩種測試場景
-
手動設計:能靈活按照需求來設計,使場景能更好的接近用戶的真實使用。
-
面向目標:測試性能是否達到預期目標。
一般情況下,使用手動測試場景設計方法。
場景設計
手動配置
手動配置有兩種組織方法,按場景組織和按組組織
按場景組織:所有用戶統一按照相同的規則來跑完所有的測試腳本。
按用戶組組織:每個組要設置自己的啟動規則、持續時間、停止規則等。
默認的測試場景如上圖:總計10個虛擬用戶,以每15秒增加2個用戶的方式進行加壓,1分鍾后加載完全部虛擬用戶,持續增壓5分鍾,當結束的時候,每30秒停止5個用戶,直到所有用戶都停止。
可以針對測試的各個階段,進行更加精細的運行規則設置,下圖以場景持續時間為例子,持續時間設置圖如下:
- 選擇"運行至結束",以Vugen中設置的迭代次數為准。
- 選擇"持續時間",忽略Vugen中的迭代次數,腳本的Action重復執行,直到時間結束為止,按退出策略,執行退出操作。
場景控制器中的並發數,指的是同時運行的VUser用戶數,可在Tools-->LR License Utility中查看:
社區版本最大可並發50個VUser,如果單次測試中超過50個Vuser,會彈提示
解決方法:
-
在只有50個VUser的情況下,每個腳本內部采用循環的方式,執行相關的迭代操作,可在一定程度上跳過限制。如果在單個場景中,創建了太多的線程用戶,LR會報錯,報錯示意圖如下:
-
安裝LR11.00破解版。
面向目標的場景
在此場景下,首先要定義預期目標,然后LR會根據這一目標自動創建場景,在運行過程中,會不斷地把結果和目標相比較,以決定下一步怎么走。
設置界面如下:
常見的測試目標有:
- 虛擬用戶並發數
- 每秒點擊數
- 每秒事務數
- 多用戶並發時的事務響應時間
以virtual users測試目標為例子,它用來測試服務器對並發用戶的處理能力,假設虛擬用戶有100個,那么LR會逐漸遞增虛擬用戶,直到加載到100個為之,如不能達到,將采取if target cannot be reached中設置的策略來繼續運行當前的場景。
參考鏈接:LR Controller介紹
配置Load Generator
Load Generator是負載發生器,默認情況下,使用本地的負載生產器來運行腳本,模擬用戶行為本身需要消耗一定的系統資源,所以一台電腦上無法模擬大量的虛擬用戶,此時,可通過多台機器上的Load Generator來完成大規模的性能負載。當控制器發出執行指令時,LG負責和其他負載機建立聯系並強制負載機執行。
詳細介紹:Controller控制器
LR中文參考教程:LoadRunner 12.02教程獨家中文版
執行完測試任務計划后,等待Controller自動收集各個負載生成器的數據后,可通過各式圖表來查看測試報告。
腳本調用DLL
LoadRunner提供了lr__load__dll函數,可使用第三方dll。此種方法對dll有導出格式要求,要求導出風格為C風格。LoadRunner需要調用ANSI版本的Windows系統函數.
遇到的問題:
- 創建C Vuser模式的腳本時,執行網絡相關的函數(例如web_rul等)會卡死,可能是因為執行LoadRunner內置的網絡相關函數,因為腳本的模式不對導致的。
Controller結果分析
設置好場景計划后,運行場景,如下圖所示:
左側有可用圖標提示:
查看詳細結果,可通過Results->Analysis Results打開Analysis軟件來進行詳細的分析。
LR發送TCP數據流
- 發送數據在哪里定義?
1.1 在data.ws文件中定義發送發送緩沖的內容和長度,定義接收緩沖的長度,采用這種方法,靈活性不好。
1.2 通過lrs_set_send_buffer
來自定義入參,可以選用Parameters List
來填充。使用這種方法,需要注意一點,lrs_set_send_buffer
函數的第三個入參表示傳入的字節數,此處有坑:當自定義內容中無參數列表時,可以采用如下實現:
char* pSendBuffer = "123456789"; lrs_set_send_buffer("socket2", pSendBuffer, strlen(pSendBuffer)); lrs_send("socket2", "sendBuffer", LrsLastArg);
當自定義內容中含有自定義參數列表時,比如說傳入隨機數,參數名稱起為Random,參數內容是1~10000之間的4位正整數,此時,第三格參數長度應該為{Random}字符串的長度,而不是真實傳輸內容的長度。
lrs_set_send_buffer("socket2", "{Random}", 8); // 設置為7,就會發送 "{Random"字符串,而不是參數化的信息 lrs_set_send_buffer("socket2", "{Random}", strlen("{Random}"));
以上兩種寫法都可以,為了減少記憶負擔,第三個參數始終使用strlen來計算待發送的長度。
- 接收數據在哪里查看?
2.1 通過lrs_get_last_received_buffer
來獲得接收數據。
- 如何接收不定長數據?
方法一
分兩次讀取,第一次讀取待接收數據流的長度信息,此長度信息的位置需要和服務端約定好。
第二次根據第一次讀取的長度來讀取后續的內容。
方法二
通過lrs_set_receive_option
函數來設置接收終止表示,該函數有三種使用方法:
LR接收Mismatch問題的處理辦法,自己在嘗試時,發現EndMarket_None
這種屬性設置的沒有效果,暫未測試成功。
通過第二種方法,讀取到指定結束符的方式來,也沒有試成功。