
6.1 檢查點
6.1.1 插入檢查點的原因
以登錄場景為例,當?shù)卿浭r,接口其實已經(jīng)返回了相應的error code,可是因為我們在 Vuser -> Run-Time Settings里的 Error Handling 里選中了 Continue on error,所以雖然出錯了,但是登錄事務卻仍然執(zhí)行完成了,再加上我們的事務結(jié)束函數(shù)里一般設(shè)置的是AUTO,如下:
lr_end_transaction("用戶登錄", LR_AUTO),因此系統(tǒng)仍然判定該事務 PASS。
所以我們需要手工增加返回值檢查,否則場景運行時的統(tǒng)計分析結(jié)果就完全錯了。
6.1.2 插入檢查點
我們可以把腳本視圖切為“Tree View”模式,然后右鍵單擊需要插入檢查點的位置,在右鍵菜單里選擇 Insert After... 或者 Insert Before...,但是我們在實際應用中,都不是錄制腳本,而是直接寫,所以參見下節(jié);
6.1.3 檢查點函數(shù)
web_find() 和 web_reg_find():
(1)前者是普通函數(shù),后者是注冊函數(shù);
(2)前者需要在 Run-Time Settings -> Internet Protocol -> Peferences 窗口勾選上 Enable image and text check 才可用,后者沒有這個限制;
(3)前者錄制時只能基于 HTML 模式錄制的腳本中,而后者沒有這個限制;
(4)前者是在返回頁面內(nèi)容顯示出來以后才能查找,后者在緩存中查找;
(5)后者執(zhí)行效率比前者高;
6.1.4 通過檢查點判斷事務結(jié)束狀態(tài)
web_reg_find("Text=LR_Test", //設(shè)置需要查找的 String
? ?"SaveCount=apptype_count", ? //將查找到的次數(shù)存入該變量
LAST)
//lr_eval_string 函數(shù)讀取 apptype_count 的值是字符型,通過 atoi 轉(zhuǎn)換為整型,才能跟 1 比較
if (atoi(lr_eval_string("{apptype_count}")) >= 1) {
? ? ? ?lr_end_transaction("myMerchantList",LR_PASS);
? ?}
else{
? ? ? ?lr_end_transaction("myMerchantList",LR_FAIL);
? ?}
6.2 Block(塊)技術(shù)
LoadRunner 如何在一個腳本中實現(xiàn)不同事務、不同次數(shù)的循環(huán)或不同百分比的循環(huán)呢?

在某些復雜場景里,你也許需要用到這樣的設(shè)置??梢栽谏厦娴膶υ捒蚶镌O(shè)置。你也能選中 Block,點擊 Properties 對話框,去設(shè)置 Sequential 的次數(shù)或者 Random 的百分比。
目前,我在實際應用中還未應用到。
6.3 參數(shù)化技術(shù)
腳本參數(shù)化,就是用參數(shù)去取代腳本里的常量。參數(shù)的來源可以是文本文件,也可以是數(shù)據(jù)庫。參數(shù)化的過程體現(xiàn)了數(shù)據(jù)驅(qū)動的思想,即將測試腳本與測試數(shù)據(jù)剝離開。
6.3.1 參數(shù)化的原因及條件
原因:
(1)減小腳本的數(shù)量,如果寫死常量的話,那必須得復制并修改大量的腳本;
(2)模擬真實場景,每個 Vuser 使用不同的參數(shù)值來模擬;
需要進行參數(shù)化的一些情況:
(1)日期時間類的常量;
(2)唯一性約束。比如 User ID,Order ID 等在數(shù)據(jù)庫里被作為主鍵的;
(3)數(shù)據(jù)約束。指在測試過程中要求提交的業(yè)務數(shù)據(jù)必須是每次都不同,比如動態(tài) token;
(4)緩存數(shù)據(jù)約束。如果不參數(shù)化,每次查詢條件都用一樣的,從數(shù)據(jù)庫里查詢到的結(jié)果也就是一致的,所以系統(tǒng)就直接從緩存讀取了,而不需要從硬盤將數(shù)據(jù)讀到緩存。導致這樣測出來的時間不是真實的響應時間。
6.3.2 創(chuàng)建參數(shù)
選中需要被參數(shù)化的常量并右鍵單擊,選擇“Replace with a parameter”,打開“Select or Create Parameter”對話框

在上述對話框里設(shè)置成功一個參數(shù)后,會在腳本保存的根目錄下自動生成一個參數(shù)化文件(.dat)
這里需要注意兩點:
(1)參數(shù)化文件可以與腳本分離,單獨保存在一個參數(shù)文件夾,同一套腳本可以共用;
(2)如果多個參數(shù)是成組使用的話,可以合并成一個參數(shù)化文件;
6.3.3 參數(shù)類型屬性
常用的:
Date/Time / Random Number / File
注意:隨機數(shù)設(shè)置項里,顯示的格式也可以自定義,比如設(shè)成:%03lu,則表示不管隨機數(shù)為多少,都用3位來表示,如隨機數(shù)為3,那么顯示的結(jié)果為003。
不常用的:
Group Name /?Iteration Number /?Load Generator Name / Unique Number / Vuser ID
6.3.4 數(shù)據(jù)文件

? ? 1. File path:Browser 設(shè)置
? ? 用來選擇參數(shù)文件的路徑,需要注意的是,默認參數(shù)化時文件是保存在腳本根目錄下的,但如果單獨放到參數(shù)化文件夾下了,就需要選擇參數(shù)的路徑。不過在實際應用中,建議將 File path 設(shè)置為相對路徑,將腳本的根目錄用“.”來代替。
? ? 2. Edit with Notepad 設(shè)置
? ? 記事本打開后,內(nèi)容中第一行是參數(shù)名稱,第二行是參數(shù)的初始值。參數(shù)之間用逗號隔開。你也可以直接用 UltraEdit 或 Notepad++ 打開.dat文件編輯。
? ? 3. Select column 設(shè)置
? ? 指明參數(shù)選擇的列,實際應用中建議用 By name,直觀不易選錯。
? ? 4.File Format - Column 設(shè)置
? ? 參數(shù)列一般用默認的逗號作為分隔符,也可以選擇 Tab 或 空格分隔。
? ? 5.File Format - First data 設(shè)置
? ? 設(shè)置成N,就從列標題后的第 N 行開始執(zhí)行。
? ? 6. Select next row 設(shè)置
? ? 針對 Controller 運行時的 Vuser,決定 Vuser 選擇參數(shù)的過程。
? ? ? ? (1)順序 Sequential。如果參數(shù)化文件中的數(shù)據(jù)都執(zhí)行了一遍,則返回到第一行繼續(xù)執(zhí)行。
? ? ? ? (2)隨機 Random。隨機讀取參數(shù)數(shù)據(jù)。
? ? ? ? (3)唯一 Unique。分配一個唯一的有順序的值給每個 Vuser 作為參數(shù)。
? ? ? ? ? ? 當選中了 Unique 時,下面兩個選項變?yōu)榭捎脿顟B(tài):
? ? ? ? ? ? ? ?3.1 ?When out of values:表示當參數(shù)不夠時的3種處理方式:
? ? ? ? ? ? ? ? ? ?3.1.1 Abort Vuser:忽略剩下的所有 Vuser 不再運行
? ? ? ? ? ? ? ? ? ?3.1.2 Continue in a cyclic manner:將參數(shù)繼續(xù)循環(huán)一次,Vuser 按順序參數(shù)進行迭代
? ? ? ? ? ? ? ? ? ?3.1.3 Continue with last value:一直使用最后一個數(shù)據(jù)進行后面的迭代
? ? ? ? ? ? ? ? 3.2 Allocate Vuser values in the Controller:指在 Controller 運行時,2種分配參數(shù)的方式:
? ? ? ? ? ? ? ? ? ? 3.2.1 Automatically allocate block size:由 LoadRunner 自動分配每個 Vuser 使用的參數(shù)情況
? ? ? ? ? ? ? ? ? ? 3.2.2 Allocate XXX values for each Vuser:為每個 Vuser 分析所設(shè)置的虛擬用戶。
? ? ? ? (4)Same link as ***:與某個已定義好的參數(shù)取同一行值。要求至少其中的一個參數(shù)必須是 Sequential、Random 或 Unique。
? ? ? ? (5)Update value on 設(shè)置:設(shè)置腳本迭代過程中取值的策略,可以在調(diào)試腳本的日志中查看表現(xiàn)。
? ? ? ? ? ? ? 5.1 Each iteration:在同一個迭代過程中,不管同一個參數(shù)出現(xiàn)多少次,都只使用同一個值。實際應用中要注意,經(jīng)常會沒選這個值,導致同一個 Action 里上下午接口出錯;
? ? ? ? ? ? ? 5.2 Each occurrence:每次迭代的過程中,參數(shù)的值都會更新;
? ? ? ? ? ? ? 5.3 Once:同一個 Vuser 中一直取同一個值,表中其他的數(shù)據(jù)不參與迭代過程。
6.3.5 導入數(shù)據(jù)
LoadRunner 允許利用參數(shù)化從數(shù)據(jù)庫里導入數(shù)據(jù),提供了兩種方式:Microsoft Query 和 指定數(shù)據(jù)庫連接字符串和 SQL 語句,后者在我的實際應用中較多。
(1)在 Parameter Properties 對話框點擊 Data Wizard 按鈕,則會打開下面的對話框;

(2)打開創(chuàng)建新數(shù)據(jù)源對話框:

(3)現(xiàn)在本機安裝 mysql-connector-odbc-3.51.20-win32,在下面的驅(qū)動程序列表里就能看到對應的 MySQL ODBC 3.51 Driver。

(4)輸入相應的 DB server IP,正確的用戶名和密碼,就能在 Database 下拉列表里看到相應的數(shù)據(jù)庫。

(5)數(shù)據(jù)源建立成功后,可以在選擇數(shù)據(jù)源對話框選擇你創(chuàng)建的數(shù)據(jù)源,然后在下面對話框里的“SQL statement” 編輯框里輸入你要查詢數(shù)據(jù)的 SQL,點擊 Finish。再稍等片刻(取決于你查詢數(shù)據(jù)量的大?。?,就能在參數(shù)化文件里看到相應的數(shù)據(jù)了。

6.4 關(guān)聯(lián)技術(shù)
LoadRunner 中的關(guān)聯(lián)技術(shù)一直以來是我不太理解,為什么要跟參數(shù)化分開來看。按我個人的理解:“關(guān)聯(lián)”其實可以看做參數(shù)化的動態(tài)賦值方法。上一節(jié)中說的是在腳本執(zhí)行前給某個參數(shù)預先賦值,而“關(guān)聯(lián)”可以說就是在腳本執(zhí)行時,動態(tài)從服務端獲取到值,再賦予某個參數(shù)。
好了,以上是我個人的疑惑和不解。我們還是先回到書上吧。
6.4.1 關(guān)聯(lián)的原理
關(guān)聯(lián)(Correlation)是把腳本中某些寫死的數(shù)據(jù)(hard-coded)轉(zhuǎn)變成取自服務器返回的、動態(tài)的、每次都不一樣的數(shù)據(jù)。常用關(guān)聯(lián)技術(shù):錄制中關(guān)聯(lián)、錄制后關(guān)聯(lián)和手動關(guān)聯(lián)。
LoadRunner 關(guān)聯(lián)是通過左右邊界值來查找服務器返回給客戶端的值。
6.4.2 手動關(guān)聯(lián)
我在應用中只使用手動關(guān)聯(lián),因為比較靈活快捷。常用的關(guān)聯(lián)函數(shù):
? ? web_reg_save_param("userid",? //創(chuàng)建變量名稱。將
? ? ? ? "LB=\"userId\":\"",? //需要獲取到的動態(tài)值的左邊界值
? ? ? ? "RB=\",", //需要獲取到的動態(tài)值的右邊界值
? ? ? ? "Search=Body", //指定在Body 緩沖區(qū)中查找
? ? ? ? "ORD=ALL", //不填及默認值為1,指查找待匹配的內(nèi)容第一次出現(xiàn)時,就保存到變量里。設(shè)為All 時,是將所有符合條件的值保存在一個數(shù)組里。
? ? LAST); //結(jié)束參數(shù)的標志


理論上關(guān)聯(lián)與參數(shù)化的區(qū)別:
(1)數(shù)據(jù)處理方式不同,參數(shù)化的數(shù)據(jù)是由客戶端向服務器提交的,而關(guān)聯(lián)是需要獲取服務器返回客戶端的數(shù)據(jù)。
(2)處理的數(shù)據(jù)是否確定,參數(shù)化數(shù)據(jù)是測試工程師知道的,而關(guān)聯(lián)數(shù)據(jù)的內(nèi)容是不清楚的。