LoadRunner中常用的字符串操作函數有:
strcpy(destination_string, source_string);
strcat(string_that_gets_appended, string_that_is_appended);51Testing軟件測試網:J3~c:c[(wR%A2l
atoi(string_to_convert_to_int); //returns the integer value
itoa(integer_to_conver_to_string, destination_string, base); // base is 10
strcmp(string1, string2); // returns 0 if both strings are equal51Testing軟件測試網q%USEK
對各函數的定義:
strcpy( ):拷貝一個字符串到另一個字符串中.
strcat( ):添加一個字符串到另一個字符串的末尾。
strcmp( ):比較兩個字符串,如果相等返回0。
atoi():轉換一個ASCII字符串為一個整型。
itoa():根據給定的進制,轉換一個整型數據為ASCII字符串51Testing軟件測試網D&VI2KD|
下面的例子使用了上面這些函數:
Actions() { char MyString1[20] = ""; char MyString2[20] = ""; char MyString3[20] = "Mercury2"; char Cstring[10] = "12345"; int Cint; // MyString1 is empty // lr_output_message(">>>>>>>>>> MyString1 = %s",MyString1); // copy "Mercury1" into MyString1 // strcpy(MyString1,"Mercury1"); // Now MyString1 contains "Mercury1" // lr_output_message(">>>>>>>>>> MyString1 = %s",MyString1); // Copy MyString3 into MyString2 // lr_output_message(">>>>>>>>>> MyString2 = %s",MyString2); strcpy(MyString2,MyString3); lr_output_message(">>>>>>>>>> MyString2 = %s",MyString2); // Catenate MyString2 to MyString1 // strcat(MyString1,MyString2); lr_output_message(">>>>>>>>>> MyString1 = %s",MyString1); // Cstring is converted to integer Cint // lr_output_message(">>>>>>>>>> Cstring = %s",Cstring); Cint = atoi(Cstring); lr_output_message(">>>>>>>>>> Cint = %d",Cint); // Cint is converted to string Cint = 100; itoa(Cint,Cstring,10); lr_output_message(">>>>>>>>>> Cstring = %s",Cstring); return 0; }
LoadRunner字符串比較的常見錯誤 最近在論壇上看到有人提問LoadRunner如何對兩個字符串進行比較,其腳本中兩個字符串進行比較結果總是不一樣的。我把問題整理了一下以便注意這個容易被忽略的錯誤。 腳本如下: ... lr_save_string( "Hello World!","string1" ); lr_save_string( "Hello World!","string2" ); result = strcmp("string1","string2"); if ( result == 0 ) { lr_output_message("the result is 0."); } else { lr_output_message("the result is not 0."); } 大家可以看出腳本那里錯了嗎? 問題錯在result = strcmp("string1","string2");這個上,這樣變成了對字符串"string1"和"string2"的比較,而不是對變量的值進行比較,因此比較結果肯定是不一樣的。 正確的寫法有兩種: result = strcmp(&string1,&string2); result = strcmp(lr_eval_string("{string1}"),lr_eval_string("{string2}"));
Loadrunner的字符串處理函數
1)strcat編輯本段回目錄 char *strcat ( char *to, const char *from ); 功能:鏈接兩個字符串。 例子: 這個例子是用strcat鏈接字符串:Cheers_Lee和 @hotmail.com 腳本如下: char test[1024], *a = "@hotmail.com"; strcpy(test, "Cheers_Lee"); strcat(test, a); lr_output_message("We can see %s",test); 運行后在executon log中看到如下語句: Starting action Action. Action.c(16): We can see Cheers_Lee@hotmail.com 2)strchr編輯本段回目錄 char *strchr ( const char *string, int c ); 功能:返回字符串中指定字符后面的字符串。 例子: 這個例子是返回第一個出現e字符以后所有的字符,和最后一次出現e字符以后所有的字符。 腳本如下: char *string = "Cheers is a tester"; char *first_e, *last_e; first_e = (char *)strchr(string, 'e'); lr_output_message("We can see the first occurrence of e: %s",first_e); last_e = (char *)strrchr(string, 'e'); lr_output_message("We can see the last occurrence of e: %s", last_e); 運行后在executon log中看到如下語句: Starting action Action. Action.c(12): We can see the first occurrence of e: eers is a tester Action.c(14): We can see the last occurrence of e: er 3)Strcmp&stricmp編輯本段回目錄 int strcmp ( const char *string1, const char *string2 );大小寫敏感。 int stricmp ( const char *string1, const char *string2 );大小寫不敏感。 功能:比較字符串。 例子: 按是否區分大小寫對比兩個字符串,並打印出它們的大小關系。 腳本如下: int result; char tmp[20]; char string1[] = "We can see the string:Cheers"; char string2[] = "We can see the string:cheers"; result = strcmp( string1, string2 ); if( result > 0 ) strcpy( tmp, "大於" ); else if( result < 0 ) strcpy( tmp, "小於" ); else strcpy( tmp, "等於" ); lr_output_message( "strcmp: String 1 %s string 2", tmp ); result = stricmp( string1, string2 ); if( result > 0 ) strcpy( tmp, "大於" ); else if( result < 0 ) strcpy( tmp, "小於" ); else strcpy( tmp, "等於" ); lr_output_message( "stricmp: String 1 %s string 2", tmp ); 運行后在executon log中看到如下語句: Starting action Action. Action.c(22): strcmp: String 1 小於 string 2 Action.c(33): stricmp: String 1 等於 string 2 4)strcpy編輯本段回目錄 char *strcpy ( char *dest, const char *source ); 功能:復制一個字符串到另一個字符串中。 例子: 復制一個字符串到字符數組中,並打印出來。 腳本如下: char test[1024]; strcpy(test, "what can we see?"); lr_output_message("%s", test); 運行后在executon log中看到如下語句: Starting action Action. Action.c(10): what can we see? 5)Strdup& strlwr編輯本段回目錄 char *strdup ( const char *string ); 功能:復制一個字符串。 char *strlwr ( char *string ); 功能:轉換成小寫字母。 例子: 在這個例子中,Vuser的組名被轉換為小寫字母。但是lr_whoami把組名作為靜態buffer返回。這樣的buffer不能被操作。如果有操作需要,就復制這個靜態buffer。 腳本如下: int id; char *groupname_static, *groupname; lr_whoami(&id, &groupname_static, NULL); lr_output_message("groupname=%s", groupname_static); groupname = (char *)strdup(groupname_static); groupname = (char *)strlwr(groupname); lr_output_message("lower case groupname=%s", groupname); free(groupname); 上述腳本用vugen保存為:CHANGE 在controller中運行(設置為總是發送消息) 運行后在log中看到如下語句: Starting action Action. [MsgId: MMSG-15919] Action.c(11): groupname=CHANGE [MsgId: MMSG-17999] Action.c(16): lower case groupname=change [MsgId: MMSG-17999] 6)Strlen編輯本段回目錄 size_t strlen ( const char *string ); 功能:返回字符串長度(bytes). 例子: 這個例子很簡單,就是得到一個字符串中的字符的個數。然后打印出來。 腳本如下: Starting action Action. [MsgId: MMSG-15919] Action.c(11): groupname=CHANGE [MsgId: MMSG-17999] Action.c(16): lower case groupname=change [MsgId: MMSG-17999] 運行后在log中看到如下語句: Action.c(13): The sentence has 18 letters 7)Strncat編輯本段回目錄 char *strncat ( char *to_string, const char *from_string, size_t n ); 功能:把一個字符串連接到另一個字符串后面。 例子: 在這里,我隨便寫了兩個字符串,用此函數把他們連接起來,並打印出來。 腳本如下: char str1[]="Cheers is "; char str2[]="a tester."; lr_output_message("What can we see?"); lr_output_message("The str1 is %s.",str1); strncat(str1,str2,20); lr_output_message("The str1 is %s.",str1); 運行后在log中看到如下語句: Action.c(9): What can we see? Action.c(10): The str1 is Cheers is . Action.c(13): The str1 is Cheers is a tester.. 注:我們可以看到,沒有連接前的str1是:Cheers is,連接后的字符串是:Zee is a tester。也可以看看strcat函數。 8)strncmp編輯本段回目錄 int strncmp ( const char *string1, const char *string2, size_t n ); 功能:對比兩個字符串的前n位。 例子: 對比兩個字符串,並把對比結果打印出來。這里我和上面的strcmp一起寫。 腳本如下: char result; char str1[]="Cheers is a tester."; char str2[]="Cheers is a tester."; char str3[]="Cheers is a tester?"; result = strcmp(str1,str2); if(result > 0) lr_output_message("str1 is greater than str2."); else if(result < 0) lr_output_message("str1 is less than str2."); else lr_output_message("str1 is equal to str2."); result = strncmp( str1, str3 , 30); if(result > 0) lr_output_message("str1 is greater than str3."); else if(result < 0) lr_output_message("str1 is less than str3."); else lr_output_message("str1 is equal to str3."); 運行后在log中看到如下語句: Starting iteration 1. Starting action Action. Action.c(18): str1 is equal to str2. Action.c(28): str1 is less than str3.
loadrunner比較有用的字符串函數 strcat的串連兩個字串。 strchr返回指向第一次出現的字符串中的字符。 STRCMP比較兩個字符串來確定的字母順序。 STRCPY一個字符串復制到另一個地方。 strdup重復一個字符串。 stricmp執行區分大小寫的比較兩個字符串。 strlen的返回一個字符串的長度。 strlwr將字符串轉換為小寫。 strncat函數串連?從一個字符串到另一個字符。 STRNCMP比較兩個字符串的前n個字符。 strncpy一個字符串的前n個字符復制到另一個地方。 strnicmp執行區分大小寫的比較n個字符串。 strrchr查找的字符串中的字符的最后一次出現。 strset一個特定的字符填充一個字符串。 strspn返回一個指定的字符串中包含的字符串中的前導字符的長度。 strstr返回一個字符串第一次出現在另一個
把字符看成ASII的值 , 和數字比較大小一般,
if( strcmp(A,B) > 0 ) 串A > 串B
if( strcmp(A,B) == 0 ) 相同的串
if(strcmp(A,B) < 0 ) 串A < 串B
int strcmp(char *str1, char *str2);
比較字符串str1和str2是否相同。如果相同則返回0;
如果不同,在不同的字符處如果str1的字符大於str2的字符,則返回1,否則返回-1
比如:
char a[]="abcd";
char *b="abcd";
char *d="abcde";
int d=strcmp(a,b); //那么d的值是0
d=strcmp(b,d); //d的值是-1 因為 '\0' 比'e' 小
d=strcmp(d,b); //d的值是1,因為 'e' 比'\0'大
{
break;
}
LR中常用的C函數
char test[1024], *a = "slo@hotmail.com";
strcpy(test, "zee");
strcat(test, a);
lr_output_message("We can see %s",test);
|
Starting action Action.
Action.c(16): We can see zeeslo@hotmail.com
|
char *string = "Zee is a tester";
char *first_e, *last_e;
first_e = (char *)strchr(string, 'e');
lr_output_message("We can see the first occurrence of e: %s",first_e);
last_e = (char *)strrchr(string, 'e');
lr_output_message("We can see the last occurrence of e: %s", last_e);
|
Starting action Action.
Action.c(12): We can see the first occurrence of e: ee is a tester
Action.c(14): We can see the last occurrence of e: er
|
int result;
char tmp[20];
char string1[] = "We can see the string:ZEE";
char string2[] = "We can see the string:zee";
result = strcmp( string1, string2 ); /*區分大小寫,比較字符串 */
if( result > 0 )
strcpy( tmp, "大於" );
else if( result < 0 )
strcpy( tmp, "小於" );
else
strcpy( tmp, "等於" );
lr_output_message( "strcmp: String 1 %s string 2", tmp );
result = stricmp( string1, string2 ); /* 不區分大小寫,比較字符串 */
if( result > 0 )
strcpy( tmp, "大於" );
else if( result < 0 )
strcpy( tmp, "小於" );
else
strcpy( tmp, "等於" );
lr_output_message( "stricmp: String 1 %s string 2", tmp );
|
Starting action Action.
Action.c(22): strcmp: String 1 小於 string 2
Action.c(33): stricmp: String 1 等於 string 2
|
char test[1024];
strcpy(test, "what can we see? ");
lr_output_message("%s", test);
|
Starting action Action.
Action.c(10): what can we see?
|
int id;
char *groupname_static, *groupname;
/* 從VuGen中得到組名 */
lr_whoami(&id, &groupname_static, NULL);
lr_output_message("groupname=%s", groupname_static);
/*復制這個靜態組名以便我們可以操作它 */
groupname = (char *)strdup(groupname_static);
groupname = (char *)strlwr(groupname);
lr_output_message("lower case groupname=%s", groupname);
free(groupname);
|
Starting action Action. [MsgId: MMSG-15919]
Action.c(11): groupname=CHANGE [MsgId: MMSG-17999]
Action.c(16): lower case groupname=change [MsgId: MMSG-17999]
|
char *str = "Zee is a tester";
unsigned int len;
len = strlen(str);
lr_output_message("The sentence has %d letters",len);
|
Action.c(13): The sentence has 15 letters
|
char str1[]="Zee is ";
char str2[]="a tester.";
lr_output_message("What can we see?");
lr_output_message("The str1 is %s.",str1);
strncat(str1,str2,20);
lr_output_message("The str1 is %s.",str1);
|
Action.c(9): What can we see?
Action.c(10): The str1 is Zee is .
Action.c(13): The str1 is Zee is a tester..
|
char result;
char str1[]="Zee is a tester.";
char str2[]="Zee is a tester.";
char str3[]="zee is a tester?";
result = strcmp(str1,str2);
if(result > 0)
lr_output_message("str1 is greater than str2.");
else if(result < 0)
lr_output_message("str1 is less than str2.");
else
lr_output_message("str1 is equal to str2.");
result = strncmp( str1, str3 , 30);
if(result > 0)
lr_output_message("str1 is greater than str3.");
else if(result < 0)
lr_output_message("str1 is less than str3.");
else
lr_output_message("str1 is equal to str3.");
|
Starting iteration 1.
Starting action Action.
Action.c(18): str1 is equal to str2.
Action.c(28): str1 is less than str3.
|
字符串判斷用strcmp
請一下判斷lr_eval_string("{test}")是否為空怎么寫呢?
一樣的,你定義一個空值字符串,然后用取到的值進行比較。
char * mystr=" ";
char *str="";
int result;
result=strcmp(mystr,str);
lr_output_message("result is %d",result);
前邊已經發了不少關於Loadrunner中腳本編寫的文章,現在發一個帖子,作為Loadrunner中C腳本編寫一些該注意問題的帖子,作為對腳本編寫知識的進一步鞏固。
1.全局變量和局部變量
vuser_init() { //Allocates a block of memory. char * p = (char * )malloc(1000 * sizeof(char)); return 0; } ------------------------------------------ Action() { return 0; } ------------------------------------------ vuser_end() { //Frees a block of memory. free(p); return 0; } |
如上腳本所示:
最初的思路是在 vuser_init中定義指針p,並為其malloc函數申請1000個字節的內存空間,為了避免內存泄露,用戶試圖在vuser_end中釋放p指向的內存空間,但free(p),由於變量p是在vuser_init中定義的,其作用域僅局限於vuser_init,離開了vuser_init,在vuser_end編譯是會報錯“p變量未被定義”。
這樣我們的問題就產生了,那如何在vuser_init()、Action()、vuser_end()中使用全局變量呢?
這里我們就要用到全局變量,它是在函數外部定義的變量。它不屬於哪一個函數,它屬於一個源程序文件,其作用域是整個源程序。
在Loadrunner的HTTP協議錄制的web系統時,會生成一個globals.h文件,在這里定義的變量相當於;Loadrunner腳本的全局變量,可以在vuser_init()、Action()、vuser_end()中被使用。
在globals.h文件中,添加全局變量的方法如下:
#ifndef _GLOBALS_H #define _GLOBALS_H //-------------------------------------------------------------------- // Include Files #include "lrun.h" #include "web_api.h" #include "lrw_custom_body.h" //-------------------------------------------------------------------- // Global Variables 包含全局變量 char * p; #endif // _GLOBALS_H |
注意:紅色部分為添加的全局變量的位置;
然后,執行腳本,腳本就可以通過了,呵呵!
2.lr_whoami() 使用的一點說明;
說明:lr_whoami()在VU中運行返回的值是:-1
舉例:
Action() { int id, scid; char *vuser_group; lr_whoami(&id, &vuser_group, &scid); lr_message( "Group: %s, vuser id: %d, scenario id %d", vuser_group, id, scid); return 0; } |
執行腳本結果如下:
Virtual User Script started Starting action vuser_init. Web Turbo Replay of LoadRunner 9.0.0 for WINXP; WebReplay82 build 5727 [MsgId: MMSG-27143] Run-Time Settings file: "C:\Documents and Settings\Administrator\Local Settings\Temp\noname3\\default.cfg" [MsgId: MMSG-27141] Ending action vuser_init. Running Vuser... Starting iteration 1. Starting action Action. Group: None, vuser id: -1, scenario id 0 Ending action Action. Ending iteration 1. Ending Vuser... Starting action vuser_end. Ending action vuser_end. Vuser Terminated.
這里需要說明的是:lr_whoami()在VU中運行返回的值是:-1(見結果綠色部分顯示),只有在conctroller中多用戶並發的時候才會輸出正確的值。
3.多個action()邏輯排序。
比如說,我們的一個腳本中有多個action,我們想改變執行順序,我們可以這樣來操作。
在VU菜單欄,Vuser - Run-Time Settings...- Run Logic中,通過 move up 、move down 改變action()執行的順序。
4.Loadrunner中檢查點判斷執行那些操作;
web_reg_find("Text=ABC", "SaveCount=abc_count", LAST); web_url("Step", "URL=...", LAST); if (strcmp(lr_eval_string("{abc_count}"), "0") == 0) Action A else Action B |
5.利用數組做冒泡排序法例子
Action() { int a[]={1,2,3,4,5}; int i; int j; int temp; for (i=0;i<5;i++) for (j=i+1;j<5;j++) if (a[i]>a[j]) { temp=a[i]; a[i]=a[j]; a[j]=temp; } for (i=0;i<5;i++) { lr_message("%d",a[i]); } return 0; } |
腳本:
vuser_init()
{
int result;
char string1;
char string2;
lr_save_string( "We can see the string:zee","string1" );
lr_save_string( "We can see the string:zee","string2" );
lr_output_message("the string1 is %s.",lr_eval_string("{string1}"));
lr_output_message("the string2 is %s.",lr_eval_string("{string2}"));
result = strcmp(lr_eval_string("{string1}"),lr_eval_string("{string1}"));
if ( result == 0 )
{
lr_output_message("the result is 0.");
}
else
{
lr_output_message("the result is not 0.");
}
return 0;
}
結果:
Starting action vuser_init.
Web Turbo Replay of LoadRunner 8.1.0 for WINXP; Web build 4788 [MsgId: MMSG-27143]
Run-Time Settings file: "C:\Documents and Settings\Zee\Local Settings\Temp\noname26\\default.cfg" [MsgId: MMSG-27141]
vuser_init.c(10): the string1 is We can see the string:zee.
vuser_init.c(11): the string2 is We can see the string:zee.
vuser_init.c(16): the result is 0.
Ending action vuser_init.
Running Vuser...