用LoadRunner編寫socket應用的測試指令碼
LoadRunner提供了很好的對socket應用的支援,使用者可以通過錄制方法完全獲得客戶端傳送和接收的資料,然後在錄製的基礎上對相應的資料進行引數化和關聯等處理。
但在有些情況下(例如,客戶端程式沒有windows上的版本),我們就很難通過錄制達成生成指令碼的目標了。但如果我們能夠完全知曉服務端和客戶端的互動過程,完全手工編寫一個測試指令碼也並不是一件特別困難的事情。
在本文中,我們以一個實際的例子說明如何根據服務端和客戶端互動的過程,用LoadRunner自行編寫相應的指令碼。
以下是服務端工作執行緒的程式碼:
從這段程式碼中可以看到,當客戶端和服務端建立連線後,客戶端會先向服務端傳送一個請求,該請求的第一個位元組是大寫的“S”或是“R”,分別向服務端寫檔案或是從服務端讀取檔案。從第三個位元組開始,後面的內容是請求檔案的檔名。
服務端在接收到客戶端的請求後,根據請求的型別,如果是“S”,則開啟指定的檔案,並返回一個字串“OK”;如果是“R”,則開啟指定的檔案並向客戶端傳送“OK”+“檔案長度”。
隨後,如果是“S”,則由客戶端傳送寫入的檔案長度和檔案內容給服務端;如果是“R”,則向客戶端傳送檔案的內容。
到此我們已經完全明瞭了客戶端和服務端的互動過程,因此,我們可以嘗試在LR中建立一個指令碼使用者模擬客戶端行為。
下面我們以“S”的處理過程為例編寫指令碼。
1、開啟VUGen應用;
2、新建指令碼,選擇“windows sockets”協議,不需錄製;
3、在Action Section中增加以下內容:
4、這樣就成功的描述了整個互動過程,但還沒有給出實際要傳送的資料。在採用“Windows Sockets”協議的指令碼中,實際傳送的資料存放在data.ws Section中,因此,開啟該Section,直接輸入:
每個傳送和接收的資料包在這裡都有登記,“send”和“recv”表示資料的方向;“buf0”等表示資料包的描述,和指令碼中的內容對應;接下來的一個整數表示資料包的長度;然後是資料包的內容,“\x00”表示16進位制的00。
該指令碼描述了客戶端向服務端請求寫入一個檔案1.txt,檔案內容為“12345678901234567890”的過程。
但在有些情況下(例如,客戶端程式沒有windows上的版本),我們就很難通過錄制達成生成指令碼的目標了。但如果我們能夠完全知曉服務端和客戶端的互動過程,完全手工編寫一個測試指令碼也並不是一件特別困難的事情。
在本文中,我們以一個實際的例子說明如何根據服務端和客戶端互動的過程,用LoadRunner自行編寫相應的指令碼。
以下是服務端工作執行緒的程式碼:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->DWORD WINAPI mythread( LPVOID lpParameter) //客戶執行緒
{
struct My my;
memcpy(&my,lpParameter,sizeof(My));
printf("One client connect!\n");
char str1[1024]; //接收字串
char str2[1024];
int i;
i=recv(my.skt,str1,sizeof(str1),0); //接收客戶請求
str1[i]=0;
char *filename;
filename=new char[255];
for(int j=2;j<i;j++) //獲得檔名
{
filename[j-2]=str1[j];
}
filename[i-2]=0;
if (str1[0]=='S')
{
printf("The file name : %s\n",filename);
ofstream out(filename); //創檔案流
if (!out)
{
printf("cannot open file.\n"); //檔案是否正確開啟,開啟錯誤則退出
send(my.skt,"q",1,0); //向客戶傳送退出資訊
closesocket(my.skt); //解除客戶連線;
return 0;
}
str2[0]='O';
str2[1]='K';
str2[2]=0;
send(my.skt,str2,strlen(str2),0); //回覆OK資訊
i=recv(my.skt,str1,sizeof(str1),0); //接收檔案長度
str1[4]=0;
int len;
len=str1[0]*1000+str1[1]*100+str1[2]*10+str1[3];
printf("The File lenght is: %d Byte\n",len);
for(int j=0;j<len;j++)
{
char str[1];
i=recv(my.skt,str,sizeof(str),0);//接收檔案,按位元組接收,接收字串為2個位元組
str[i]=0;
out.put(str[0]);
}
out.close(); //關閉檔案
printf("over!One client quit!\n"); //接收檔案完畢
closesocket(my.skt); //解除此客戶連線
return 0;
}
if (str1[0]=='R')
{
ifstream in(filename);
if (!in)
{
printf("cannot open file or file not exist.\n"); //檔案是否正確開啟,開啟錯誤則退出
send(my.skt,"q",1,0); //向客戶傳送退出資訊
closesocket(my.skt); //解除客戶連線;
return 0;
}
char ch;
int len=0;
while(in.get(ch))
{
len++; //get file lenght
}
in.close();
str2[0]='O';
str2[1]='K';
str2[2]=len/1000;
str2[3]=(len%1000)/100;
str2[4]=(len%100)/10;
str2[5]=len%10;
printf("%s",str2);
send(my.skt,str2,6,0); //發OK+檔案長度
in.open(filename);
if (!in)
{
printf("cannot open file or file not exist.\n"); //檔案是否正確開啟,開啟錯誤則退出
send(my.skt,"q",1,0); //向客戶傳送退出資訊
closesocket(my.skt); //解除客戶連線;
return 0;
}
while(in.get(ch)) //發檔案
{
char str[1];
strcpy(str,"");
str[0]=ch;
str[1]=0;
send(my.skt,str,1,0); //傳送一個字元
}
in.close();
printf("over,One client quit!\n"); //傳輸檔案完畢
closesocket(my.skt); //解除此客戶連線
return 0;
}
printf("Bad command!\n");
closesocket(my.skt);
return 0;
}
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->DWORD WINAPI mythread( LPVOID lpParameter) //客戶執行緒
{
struct My my;
memcpy(&my,lpParameter,sizeof(My));
printf("One client connect!\n");
char str1[1024]; //接收字串
char str2[1024];
int i;
i=recv(my.skt,str1,sizeof(str1),0); //接收客戶請求
str1[i]=0;
char *filename;
filename=new char[255];
for(int j=2;j<i;j++) //獲得檔名
{
filename[j-2]=str1[j];
}
filename[i-2]=0;
if (str1[0]=='S')
{
printf("The file name : %s\n",filename);
ofstream out(filename); //創檔案流
if (!out)
{
printf("cannot open file.\n"); //檔案是否正確開啟,開啟錯誤則退出
send(my.skt,"q",1,0); //向客戶傳送退出資訊
closesocket(my.skt); //解除客戶連線;
return 0;
}
str2[0]='O';
str2[1]='K';
str2[2]=0;
send(my.skt,str2,strlen(str2),0); //回覆OK資訊
i=recv(my.skt,str1,sizeof(str1),0); //接收檔案長度
str1[4]=0;
int len;
len=str1[0]*1000+str1[1]*100+str1[2]*10+str1[3];
printf("The File lenght is: %d Byte\n",len);
for(int j=0;j<len;j++)
{
char str[1];
i=recv(my.skt,str,sizeof(str),0);//接收檔案,按位元組接收,接收字串為2個位元組
str[i]=0;
out.put(str[0]);
}
out.close(); //關閉檔案
printf("over!One client quit!\n"); //接收檔案完畢
closesocket(my.skt); //解除此客戶連線
return 0;
}
if (str1[0]=='R')
{
ifstream in(filename);
if (!in)
{
printf("cannot open file or file not exist.\n"); //檔案是否正確開啟,開啟錯誤則退出
send(my.skt,"q",1,0); //向客戶傳送退出資訊
closesocket(my.skt); //解除客戶連線;
return 0;
}
char ch;
int len=0;
while(in.get(ch))
{
len++; //get file lenght
}
in.close();
str2[0]='O';
str2[1]='K';
str2[2]=len/1000;
str2[3]=(len%1000)/100;
str2[4]=(len%100)/10;
str2[5]=len%10;
printf("%s",str2);
send(my.skt,str2,6,0); //發OK+檔案長度
in.open(filename);
if (!in)
{
printf("cannot open file or file not exist.\n"); //檔案是否正確開啟,開啟錯誤則退出
send(my.skt,"q",1,0); //向客戶傳送退出資訊
closesocket(my.skt); //解除客戶連線;
return 0;
}
while(in.get(ch)) //發檔案
{
char str[1];
strcpy(str,"");
str[0]=ch;
str[1]=0;
send(my.skt,str,1,0); //傳送一個字元
}
in.close();
printf("over,One client quit!\n"); //傳輸檔案完畢
closesocket(my.skt); //解除此客戶連線
return 0;
}
printf("Bad command!\n");
closesocket(my.skt);
return 0;
}
從這段程式碼中可以看到,當客戶端和服務端建立連線後,客戶端會先向服務端傳送一個請求,該請求的第一個位元組是大寫的“S”或是“R”,分別向服務端寫檔案或是從服務端讀取檔案。從第三個位元組開始,後面的內容是請求檔案的檔名。
服務端在接收到客戶端的請求後,根據請求的型別,如果是“S”,則開啟指定的檔案,並返回一個字串“OK”;如果是“R”,則開啟指定的檔案並向客戶端傳送“OK”+“檔案長度”。
隨後,如果是“S”,則由客戶端傳送寫入的檔案長度和檔案內容給服務端;如果是“R”,則向客戶端傳送檔案的內容。
到此我們已經完全明瞭了客戶端和服務端的互動過程,因此,我們可以嘗試在LR中建立一個指令碼使用者模擬客戶端行為。
下面我們以“S”的處理過程為例編寫指令碼。
1、開啟VUGen應用;
2、新建指令碼,選擇“windows sockets”協議,不需錄製;
3、在Action Section中增加以下內容:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> //建立到服務端的連線
lrs_create_socket("socket1","TCP","RemoteHost=127.0.0.1:8000",LrsLastArg);
//傳送“S”和檔名
lrs_send("socket1", "buf0", LrsLastArg);
lrs_receive("socket1", "buf1", LrsLastArg);
//傳送要寫入的資料的長度
lrs_send("socket1", "buf2", LrsLastArg);
//傳送資料內容
lrs_send("socket1", "buf3", LrsLastArg);
//關閉連線
lrs_close_socket("socket1");
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> //建立到服務端的連線
lrs_create_socket("socket1","TCP","RemoteHost=127.0.0.1:8000",LrsLastArg);
//傳送“S”和檔名
lrs_send("socket1", "buf0", LrsLastArg);
lrs_receive("socket1", "buf1", LrsLastArg);
//傳送要寫入的資料的長度
lrs_send("socket1", "buf2", LrsLastArg);
//傳送資料內容
lrs_send("socket1", "buf3", LrsLastArg);
//關閉連線
lrs_close_socket("socket1");
4、這樣就成功的描述了整個互動過程,但還沒有給出實際要傳送的資料。在採用“Windows Sockets”協議的指令碼中,實際傳送的資料存放在data.ws Section中,因此,開啟該Section,直接輸入:
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->send buf0 7
"S"
"\x00"
"1.txt"
recv buf1 2
"OK"
send buf2 3
"\x00"
"\x00"
"\x02"
"\x00"
send buf3 20
"12345678901234567890"
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->send buf0 7
"S"
"\x00"
"1.txt"
recv buf1 2
"OK"
send buf2 3
"\x00"
"\x00"
"\x02"
"\x00"
send buf3 20
"12345678901234567890"
每個傳送和接收的資料包在這裡都有登記,“send”和“recv”表示資料的方向;“buf0”等表示資料包的描述,和指令碼中的內容對應;接下來的一個整數表示資料包的長度;然後是資料包的內容,“\x00”表示16進位制的00。
該指令碼描述了客戶端向服務端請求寫入一個檔案1.txt,檔案內容為“12345678901234567890”的過程。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1384/viewspace-615952/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 用Jmeter編寫一個較複雜的測試指令碼JMeter指令碼
- loadrunner 資料庫測試指令碼資料庫指令碼
- LoadRunner長連線效能測試指令碼指令碼
- 如何用 JMeter 編寫效能測試指令碼?JMeter指令碼
- 【轉】測試用例編寫(功能測試框架)框架
- 效能測試——壓測工具locust——指令碼初步編寫指令碼
- 如何編寫測試團隊通用的Jmeter指令碼JMeter指令碼
- LoadRunner測試J2ME的Socket程式
- LoadRunner編寫Socket協議指令碼方法(XML/16進位制報文data.ws格式)協議指令碼XML
- TCL指令碼語言在測試系統中的應用指令碼
- 用Junit Framework編寫單元測試Framework
- 介面測試用例編寫和測試關注點
- 軟體測試用例編寫(含思路)
- 用Junit Framework編寫單元測試 (轉)Framework
- 寫好測試,提升應用質量
- 軟體測試用例的設計和編寫
- LoadRunner JAVA Vuser協議開發效能測試指令碼Java協議指令碼
- 【編測編學】分享一套好用的功能測試用例編寫框架框架
- C語言[工程專案應用]gtest測試框架編寫以及自定義測試框架C語言框架
- 用 Swift 編寫網路層單元測試Swift
- 編寫可測試的 JavaSript 程式碼Java
- 編寫可測試的 JavaScript 程式碼JavaScript
- 如何編寫介面測試用例?測試工程師必備技能!工程師
- 第8課—設計測試用例編寫技巧
- postman寫測試用例Postman
- Go 編寫 Web 應用GoWeb
- .NET應用架構設計—表模組模式與事務指令碼模式的程式碼編寫應用架構模式指令碼
- ddosify:用Golang編寫的高效能負載測試工具Golang負載
- 使用 xunit 編寫測試程式碼
- 使用 intern 編寫測試程式碼
- 編寫高效的MySQL應用(轉)MySql
- 用PHP編寫Android應用程式PHPAndroid
- 如何編寫優秀的測試程式碼|單元測試
- 開發測試用例:手動擼程式碼 VS 填鴨式編寫
- 用 Cloud Performance Test 怎麼錄製測試指令碼CloudORM指令碼
- 用 Cloud Performance Test怎麼錄製測試指令碼CloudORM指令碼
- 用Python開發自動化測試指令碼Python指令碼
- Shell指令碼應用(三)指令碼