一、什么時候需要關聯
1.關聯的含義
關聯的含義A(correlation):在腳本回放過程中,客戶端發出請求,通過關聯函數所定義的左右邊界值(也就是關聯規則),在服務器所響應的內容中查找,得到相應的值,已變量的形式替換錄制時的靜態值,從而向服務器發出正確的請求,這種動態獲得服務器響應內容的方法被稱作關聯。
關聯的含義B(correlation):就是把腳本中某些寫死的代碼(hard_coded)數據,轉變成擷(xie)取自服務器所送的、動態的、每次都不一樣的數據。
其實關聯也屬於一種特殊的參數化,只是與一般的參數化有些不同
一般的參數化的參數來源於一個文件、一個定義的table、通過sql寫的一個結果集,但關聯所獲得的參數是服務器響應請求所返回的一個符合條件的、動態的值。
舉一個常見的例子,剛剛提到有些比較聰明的服務器,這些服務器在每個瀏覽器第一次跟它要數據時,都會在數據中夾帶一個唯一的辨識碼,接下來就會利用這個辨識碼來辨識跟它要數據的是不是同一個瀏覽器。一般稱這個辨識碼為Session ID。對於每個新的交易,服務器都會產生新的Session ID給瀏覽器。這也就是為什么執行腳本會失敗的原因,因為VuGen還是用舊的Session ID向服務器要數據,服務器會發現這個Session ID是失效的或是它根本不認識這個Session ID,當然就不會傳送正確的網頁數據給VuGen了。
當錄制腳本時,瀏覽器送出網頁A的請求,服務器將網頁A的內容傳送給瀏覽器,並且夾帶了一個ID=123的數據,當瀏覽器再送出網頁B的請求時,這時就要用到ID=123的數據,服務器才會認為這是合法的請求,並且把網頁B的內容送回給瀏覽器。
在執行腳本時會發生什么狀況?瀏覽器再送出網頁B的請求時,用的還是當初錄制的ID=123的數據,而不是用服務器新給的ID=456,整個腳本的執行就會失敗。
下面的圖示說明了這樣的情形:

要對付這種服務器,我們必須想辦法找出這個Session ID到底是什么、位於何處,然后把它擷取下來,放到某個參數中,並且取代掉腳本中有用到Session ID的部份,這樣就可以成功騙過服務器,正確地完成整個交易了。
二、什么時候需要做關聯
要想弄清這個問題,我們首先要知道客戶端與服務器端的請求與響應的過程
過程說明:
客戶端發出獲得登錄頁面的請求,服務器端得到該請求后,返回登錄頁面,同時動態生成一個Session Id
當用戶輸入用戶名密碼,請求登錄時,該Session Id同時被發送到服務器端;如果該Session Id在當前會話中有效,那么返回登錄成功的頁面,如果不正確則登錄敗。
在第一次錄制過程中LR把這個值記錄了下來,寫到了腳本中,但再次回放時,客戶端發出同樣的請求,而服務器端再一次動態的生成了Session Id,此時客戶端瀏覽器再次輸入用戶名和密碼時,請求登錄,還是用舊的Session Id
,發出的請求就是錯誤的,為了獲得這個動態的session Id我們這里用到了關聯。
所以我們得出結論:
當客戶端的某個請求是隨着服務器端的相應而動態變化的時候,我們就需要用到關聯。(凡是腳本每次執行時都必須獲得唯一標識的地方都需要關聯。)
當然我們在錄制腳本時應該對測試的項目進行適當的了解,知道哪些請求需要用到服務器響應的動態值,如果我們不明確那些值需要做關聯的話,我們也可以將腳本錄制兩遍,通過對比腳本的方法來查找需要關聯的部分,但並不是說兩次錄制的所有不同點都需要關聯,這個要具體情況具體分析。
如何做關聯?
關聯會用到下列函數:
web_reg_save_param;
web_create_html_param;
web_create_parmam_ex;
其中,web_reg_save_param的語法為:
web_reg_save_param("parameter Name" , <list of Attributes>, LAST);
web_create_html_param和web_create_parmam_ex這兩個函數主要是保留以兼容以前舊版本。建議使用web_reg_save_param.
- parameter Name:存放參數的名稱
- LB:數據匹配,左邊界
- RB:數據匹配,右邊界
- Search:搜索范圍(body,header,all,cookies)
- Ordinary:整數或是All(取出值的對應順序,寫all的話就匹配所有,寫1的話只取出第一個值。)
- request URL:針對URL地址減少關聯的范圍
那么,如何找出要關聯數據呢?簡單地說,每一次執行時都會變動的值,就有可能需要做關聯。VuGen提供兩種方式幫助用戶找出需要做關聯的值:自動關聯和手動關聯。
三、關聯有兩種機制,自動關聯和手動關聯:
首先談談自動關聯
VuGen內建自動關聯引擎(Auto-correlation Eengine),提供Rules Correlation 和Correlation Studio 兩種機制,可以自動找出需要關聯的值,並且自動使用關聯函數建立關聯。
1、“Rules Correlation”:在錄制過程中VuGen 會根據使用者事先制訂的規則,實時自動找出要關聯的值。規則的來源有內建(Built-in Correlation)和使用者自定義(User-defined Rules Correlation)關聯規則兩種。
內建(Built-in Correlation):VuGen已經針對常用的一些應用系統,如AribaBuyer、BlueMartini、BroadVision、InterStage、mySAP、NetDynamics、Oracle、PeropleSoft、Siebel、SilverJRunner等,內建了一些關聯規則。這些應用系統可能會有一種以上的關聯規則。
可以在單擊“VuGen”啟動>在菜單【Tool】>【Recording Options】>【HTTP Properties】>【Correlation】中啟用關聯規則,啟動關聯后,當錄制這些應用系統腳本時,VuGen會在腳本中自動建立關聯。也可以在【Recording Options】>【HTTP Properties】>【Correlation】檢視每個關聯規則的定義。
除了內建的關聯則之外,使用者也可以自定關聯規則。可以在【Recording Options】>【HTTP Properties】>【Correlation】建立新的關聯規則。
請依照以下步驟使用“Rule Correlation”:
單擊“VuGen”啟動>在菜單【Tool】>【Recording Options】>【HTTP Properties】>【Correlation】,勾選“Enable correction during recording”,以啟動自動關聯。如下圖所示:(建議不用,選擇手動關聯)


上面兩個圖片,都可以啟動Recording Options,勾選“Enable correction during recording”,以啟動自動關聯。
假如錄制的應用系統屬於內建關聯規則的系統,如AribaBuyer、BlueMartini、BroadVision、InterStage、mySAP、NetDynamics、Oracle、PeropleSoft、Siebel、SilverJRunner等,請勾選相應的應用系統。或者可針對錄制的應用系統加入新的關聯規則,此即為使用者自定的關聯規則。
以下是自動關聯的腳本,如下圖所示:
1 Action() 2 { 3
4 //Correlation comment - Do not change!Original value='707897934' Name ='CorrelationParameter_1'
web_reg_save_param ("WCSParam_Diff1",//變量名 16 "LB=userSession value=",//左邊界 17 "RB=>",//右邊界 18 "Ord=1",//取值順序 19 "RelFrameId=1.2.1", 20 "Search=Body",//搜索范圍 21 LAST); 22
23 web_url("WebTours", 24 "URL=http://127.0.0.1:1080/WebTours/", 25 "Resource=0", 26 "RecContentType=text/html", 27 "Referer=", 28 "Snapshot=t1.inf", 29 "Mode=HTML", 30 LAST); 31
32 lr_think_time(7); 33
34 web_submit_data("login.pl", 35 "Action=http://127.0.0.1:1080/WebTours/login.pl", 36 "Method=POST", 37 "RecContentType=text/html", 38 "Referer=http://127.0.0.1:1080/WebTours/nav.pl?in=home", 39 "Snapshot=t2.inf", 40 "Mode=HTML", 41 ITEMDATA, 42 "Name=userSession", "Value={WCSParam_Diff1}", ENDITEM,//參數 43 "Name=username", "Value=jojo", ENDITEM, 44 "Name=password", "Value=bean", ENDITEM, 45 "Name=JSFormSubmit", "Value=on", ENDITEM, 46 "Name=login.x", "Value=0", ENDITEM, 47 "Name=login.y", "Value=0", ENDITEM, 48 LAST);
使用“Correlation Studio” 的步驟如下:
(1)錄制腳本並執行。
(2)執行完畢后,VuGen會跳出“Scan Action for Correlation”窗口,詢問用戶是否要掃描腳本並建立關聯,單擊“yes”按鈕,掃描腳本。
(3)掃描完后,可以在腳本下方的“Correlation Results”中看到掃描的結果。
(4)檢查一下掃描的結果,選擇要做關聯的數據,然后單擊“Correlation”按鈕,逐次關聯,或是單擊“Correlate All” 讓VuGen 一次就對所有的數據建立關聯。
注意:由於Correlation studio會找出所有有變得的數據,但是並不是所有的數據都需要做關聯,所以不是建議用戶直接“Correlate All”。
重復步驟(1)~(4),直到所有需要做關聯的數據都找出來為止。
注意:有時關聯的地方有多處,前面的管理如果沒有執行通過,執行將停止驗證腳本的正確性,后面需要做關聯的部分無法被掃描出來。
四、手動關聯
手動關聯的步驟如下:
第一步:錄制測試腳本,錄制兩遍;
第二步:使用WinDiff工具找出兩次腳本的不同,判斷是否需要進行關聯;
第三步:使用web_reg_save_param函數手動建立關聯;
第四步:將腳本中有用到關聯的數據,已參數代替;
第一步:錄制測試腳本,錄制兩遍;
先錄制一份腳本存檔,取名為loginA,再依照相同的操作步驟與數據錄制第二份腳本並保存,取名為loginB並關閉loginB;(兩次錄制的操作步驟及使用數據最好保持一模一樣)
第二步:使用WinDiff工具找出兩次腳本的不同,判斷是否需要進行關聯;
在腳本loginA中,單擊VuGen的菜單tool→compare with vuser...,並選擇loginB,如下圖所示:

第三步:接着WinDiff會開啟,同時顯示兩份腳本,並顯示有差異的地方。WinDiff會以一整行黃色標示有差異的腳本,並且以紅色的字體顯示真正差異的文字。(假如沒有看到紅色字體,請單擊“Options>View>Show inline Differences”)如下圖所示:

逐一檢查兩份腳本中差異的部分,每一處差異都有可能是需要做關聯的地方,選取差異的腳本,然后復制。在復制時,有時並不需要整行腳本,可能只會選擇腳本中的一部分。
注意:lr_thik_time是用來模擬每個步驟之間使用者思考延遲的時間,這一部分可以忽略。
接着打開Recording Log(單一協議)或是Generation Log(多重協議)中找到這個值。我個人推薦在Generation Log的第一行開頭,按Ctrl+F組合鍵,開始“find”窗口,黏上剛剛復制的腳本,找出其在Generation Log第一次出現的位置。
例如:上圖中一行和第二行的差異已經讓系統自動做了關聯,故不管;在第三行中兩個腳本存在差異性。差異的地方在【LT-68750-afrD2frlzMHDQ1wwDsjlNugZgY0mxw】,此時復制這一差異點,在Generation Log中進行查找。查找的結果如下圖所示:

找到數據后,看此差異在什么地方,檢查數據的標頭,例如上面查找的
【LT-68750-afrD2frlzMHDQ1wwDsjlNugZgY0mxw】在Body區域,如下圖所示:

一般情況下關聯函數寫到發出請求的函數之前就可以了。如下圖所示:

第四步:插入關聯函數
在插入關聯函數前,我們先介紹關聯函數web_reg_save_param
一個web_reg_save_param函數的例子:
web_reg_save_param ("sessionid","LB=Session_id:","RB=;","Search=Body",LAST);
語法:int web_reg_save_param(const char *ParamName, <list of Attributes>, LAST);
參數說明:
ParamName: 存放得到的動態內容的參數名稱;
list of Attributes: 其它屬性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。屬性值不分大小寫;
LB( Left Boundary ) : 返回信息的左邊界字串。該屬性必須有,並且區分大小寫;
RB( Right Boundary ): 返回信息的右邊界字串。該屬性必須有,並且區分大小寫;
Search : 返回信息的查找范圍。可以是Headers,Body,Noresource,All(缺省)。該屬性質可有可無。
怎么插入關聯函數呢?
根據我的經驗,當找到兩個腳本的差異后,在對應區域插入關聯函數,單擊回車鍵,顯示一行為空,在此行可以手動輸入關聯函數web_reg_save_param("參數名稱","左邊界","右邊界","查詢區域",LAST);或單擊鼠標右鍵單擊【insert】>【net step...】>在add step界面,step type中選擇services>web_reg_save_param,單擊【ok】鍵,彈出如下圖所示:




參數說明:
int web_reg_save_param (const char *mpszParamName, <List of Attributes>, LAST);
ParamName:存放動態數據的參數名稱。
list of Attributes:其他屬性,包含 “Notfound”、“LB”、“RB”、“RelFrameID”、“Search”、“ORD”、“SaveOffset”、“Convert”以及“SaveLen”。
下面將詳細說明每個屬性值的意義:
1、Notfound:指定當找不到要找的動態數據時該怎么處理。
當指定Notfound=error時,表示着找不到動態數據時,就發出一個錯誤消息。此為該屬性的默認值。
當指定Notfound=warning時,表示當找不到動態數據時,不發出錯誤消息,只發出警告,腳本也會繼續執行下去不會中斷。在對腳本出錯時,可以如此設置。
2、LB:動態數據的左邊界字符串。此屬性是必須要有的,而且區分大小寫。
3、RB:動態數據的右邊界字符串。此屬性是必須要有的,而且區分大小寫。
4、RelFrameID:相對於URL而言,欲搜尋的網頁的Frame。此屬性可以是All或是數字,而且可有可無。
5、Search:搜尋的范圍,其值可以是Headers(只搜尋headers)、Body(只搜尋body部分,不搜尋header)、Noresource(只搜尋body部分,不搜尋header與resource)或是All(搜尋全部范圍,此為默認值),此屬性可有可無。
6、ORD:指明從第幾次出現的左邊界開始才是要擷取的數據,默認值是1。假如該屬性值為All,則所有找到符合的數據會存儲在數組中。此屬性可有可無。
7、SaveOffset:當找到符合的動態數據時,從第幾個字符開始才開始存儲到參數中。此屬性值不可為負數,其默認值為0。
8、Convert:轉換數據格式。當指定該屬性值為HTML_TO_URL時,意味着將HTML-encoded數據轉成URL-encoded數據格式。如果是HTML_TO_TEXT,表示將HTML-encoded數據轉成純文字數據格式。
9、SaveLen:當找到匹配項后,偏移量之后的幾個字元存儲到參數中。此參數可有可無,默認值是-1,表示一直到結尾的整個字符串都存入參數中。
轉義字符總結
在做手動關聯時,取邊界值的時候,會經常用到轉義字符,現將轉義字符整理如下:
\b 退格
\f 換頁
\n 換行
\r 回車
\t 水平制表
\v 垂直制表
\\ 反斜杠
\? 問號字符
\' 單引號字符
\" 雙引號字符
\0 空字符