LR字符串处理



Action()
{

strchr和strrchr:
 //strchr:查找指定字符在一个字符串中第一次出现的位置,然后返回指向该位置的指针。
 //char *strchr(const char *string,int c);
 //strrchr:查找指定字符在一个字符串中最后一次出现的位置,然后返回指向该位置的指针。
 //char *strrchr(const char *string,int c);
 /*
    char *string ="I am a young soul in this very strange world.";
    char *first_a,*last_a;
    first_a = (char *)strchr(string,'a');
    lr_output_message("The first occurrence of a:%s",first_a);

 last_a = (char *)strchr(string,'a');
    lr_output_message("The first occurrence of a:%s",first_a);
 */

strcpy和strncpy:

 //strcpy:将一个字符串复制到另一个字符串中。
 //char * strcpy (char *dest,const char * source)
 // dest是目标字符串,source是源字符串。
 //strncpy:将一个字符串中指定长度复制到另一个字符串中。
 //char * strcpy (char *dest,const char * source,size_t n);
 // dest是目标字符串,source是源字符串,n是要复制的长度。
/*
 char test[50];
 char ntest[50];
 strcpy(test,"Copies one string to anther.");
 lr_output_message("%s",test);

 strncpy(ntest,"Copies one string to anther.",10);
 lr_output_message("%s",ntest);
*/

strcmp和stricmp
 //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[]="He is a test";
 char string2[]="He is a TEST";
 result = strcmp(string1,string2);
 if(result>0){
  strcpy(tmp,"greater than");
 }else if(result <0){
  strcpy(tmp,"less than");
 }else{
  strcpy(tmp,"equal to");
 }
 lr_output_message("strcmp:String1 is %s string2",tmp);

 result = stricmp(string1,string2);
 if(result>0){
  strcpy(tmp,"greater than");
 }else if(result <0){
  strcpy(tmp,"less than");
 }else{
  strcpy(tmp,"equal to");
 }
 lr_output_message("strcmp:String1 is %s string2",tmp);
*/

strcat和strncat
 //strcat:字符串连接函数。全部内容复制到另一个字符串的后面;
 //char *strcat(char *to_string,const char *from_string);
 //to_string是目标字符串,form_string是源字符串。
 //strncat:字符串连接函数。把字符串的指定长度复制到另一个字符串的后面。
 //char *strncat(char *to_string,const char *from_sring,size_t n);
/*
 char str1[]="This is ";
 char str2[]="a ";
 char str3[]="strcat&strncat ";
 char str4[]=" test!";
 lr_output_message("The str1 is:%s",str1);

 strcat(str1,str2);
 lr_output_message("The str1 is:%s",str1);

 strncat(str1,str3,6);
 lr_output_message("The str1 is:%s",str1);

 strncat(str1,str4,5);
 lr_output_message("The str1 is:%s",str1);
*/
 return 0;
}

 

Action()
{

sprintf:
 //sprintf:把一个字符串格式化后输入到另一个字符串中,与printf区别是sprintf输出结果到指定的字符串中。
 //int sprintf (char *string,const char *format_string[,args]);
 //string要写入的目标字符串,format_string是格式化的字符串,args是一系列的变量表达式。
/*
 char test[30];
    int a=2,b=8;
    sprintf(test,"Add Test:a=%d,b=%d,a+b=%d.\0",a,b,a+b);
    lr_output_message(test);
*/

strlwr和strupr:
 //strlwr:把字符串全部变成小写。
 //char *strwr(char *string);
 //strupr:把字符串全部变成大写。
 //char *strupr(char *string);
 //注意:源字符串已经变成小写或者大写,发生了内容改变,函数返回的是指向源字符串的指针,不是一个新的字符串。
/* int id;
 char str[]="ThIS is A TeST";
 char *lowerstr,*upperstr;
 lowerstr =(char *)strlwr(str);
 lr_output_message("lowerstr=%s",lowerstr);
 lr_output_message("str=%s",str);

 upperstr =(char *)strupr(str);
 lr_output_message("lowerstr=%s",upperstr);
 lr_output_message("str=%s",str);
*/

atoi和itoa:
 //atoi:把字符串转换为一个整数。
 //char *atoi(const char *string);
/* int j;
 char *s="aaa 111 bbb 222";
 j=atoi(s);
 lr_output_message("Result:%d",j);//对于以非数字开始的字符串,不能转换时,返回0。

 s = "111 bbb 222";
 j=atoi(s);
 lr_output_message("Result:%d",j);//对于前半部分以数字开始,后半部分以非数字字符结束的,能把开始的一部分数字转换为整数。
*/
 //itoa:把整数转换为一个字符串。
 //char *itoa(int value,char *string,int radix);
 //value是要转换的整数,string是用来保存转换结果的字符串,radix是转换的进制。
/* int i=56;
 char str_int[10],str_hex[10];
 itoa(i,str_int,10);
 lr_output_message("New file name %s",str_int);

 itoa(i,str_hex,16);
 lr_output_message("New file name %s",str_hex);
*/
 return 0;
}

 

Action()
{
strlen:
 //strlen:用于返回指定字符串的字符个数。注意:计算长度遇到“\0”就会停止计算。
    //因此Socket脚本中不能使用strlen来计算可能包含"\0"的数据包长度。
    //char *strlen(const char *string);
/*
    char *str = "This is a test!";
    unsigned int len;
    len = strlen(str);
    lr_output_message("The sentence has %d letters",len);

 str ="This is a test!\0abcde";
 len =strlen(str);
 lr_output_message("The sentence has %d letters",len);
*/
memcpy:
 //memcpy:内存缓冲区复制数据,可以复制二进制数据。而strncpy是复制字符串,不能复制中间存在的“\0”的数据。
 //void *memcpy(void *dest,const void *src,size_t n);
/*
 char src[]="AAAAA \0 This is a test.\0";
 char memcpy_str[25];
 char strncpy_str[25];
 memcpy(memcpy_str,src,25);
 strncpy(strncpy_str,src,25);
 lr_output_message("memcpy_str: %s",memcpy_str);
 lr_output_message("strncpy_str: %s",strncpy_str);

 lr_output_message("memcpy_str: %s",memcpy_str+8);
 lr_output_message("strncpy_str: %s",strncpy_str+8);
*/
memset:
 //memset:对数据对象做初始化工作。
 //void *memset(void *buffer,int c,size_t n);
 //把buffer执向的某一块内存中的每个字节的内容全部设置为参数C所指定的ASCII值,块得大小由第三个参数n来指定。
/*
 char buffer[]="This is a test!\n";
 lr_output_message("Buffer before memset:%s",buffer);
 memset(buffer,'a',strlen(buffer) - 1);
 lr_output_message("Buffer after memset:%s",buffer);
*/
sizeof:
 //sizeof:返回指定表达式、变量或指定数据类型在内存中所占有的字节数。
 //size_t sizeof expression
 //size_t sizeof (type)
/*
 char test[10];
 struct str_test{
  char str[10];
  int i;
 };
 struct str_test mystr;
 lr_output_message("\"abcde\"size=%d",sizeof "abcde");
 lr_output_message("\"12345\"size=%d",sizeof (12345));
 lr_output_message("\"test\"size=%d",sizeof test);
 lr_output_message("\"mystr\"size=%d",sizeof (mystr));
*/
 return 0;
}

 

 

 LoadRunner中常用的字符串操作函数有:

               strcpy(destination_string, source_string);

               strcat(string_that_gets_appended, string_that_is_appended);

               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 equal

对各函数的定义:

             strcpy( ):拷贝一个字符串到另一个字符串中.

             strcat( ):添加一个字符串到另一个字符串的末尾。

            strcmp( ):比较两个字符串,如果相等返回0。

            atoi():转换一个ASCII字符串为一个整型。

            itoa():根据给定的进制,转换一个整型数据为ASCII字符串

 

明确LoadRunner可以输出的结果

最近刚刚忙完一个项目的测试,又开始闲了起来,还是琢磨琢磨一些东西,给大家一些参考!

PS:本人在51testing和sina blog上的文章全部为原创,转载请注明出处!!

 

我们都知道软件的功能其实就是输入和输出,有了输入就有输出;例如你做了一个操作,可能返回一个提示,也可能打开一个新的窗口;而测试,其实就是组合输入,确认各种输出的正确性,就像测试一个函数,你组合不同的输入参数值,达到遍历函数的所有路径,并返回对应的值。

熟知loadrunner可以输出哪些结果,对我们对整个测试过程把握非常重要,当然也是测试分析中很重要的数据

Loadrunner脚本的执行也是一种测试输入,我们通常可以获得那些输出呢?(这些只是我总结的,实际可能不只这些哈!)

先说说脚本回放过程:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1、message系列函数
详见:《message函数详细分析》
http://www.51testing.com/?6343/action_viewspace_itemid_13643.html

2、写log文件
    写log文件主要是使用c语言的函数来进行,涉及的函数有fopen、fclose、fprintf这三个;      
    写一个例子给大家:
========================================================
Action()
\\先在D盘根目录创建一个文件夹,名为:“lr_log”
{
    char *address="D:\\lr_log\\01.log"; //定义log文件输出的地址和名称
    long filename;//定义存储文件指针的变量
    int i;
    if ((filename=fopen(address,"a+"))==NULL)//打开文件
    {
        lr_error_message("can not open this file,address=%s",address);
        return -1;
    }
    for (i=1;i<11;i++)
    {
        fprintf(filename,"我的第%d条log...\n",i);
    }
    fclose(filename);//关闭文件
    return 0;
}
=======================================================
脚本回放完毕去D盘lr_log文件夹下打开01.log文件,得到结果:
我的第1条log...
我的第2条log...
我的第3条log...
我的第4条log...
我的第5条log...
我的第6条log...
我的第7条log...
我的第8条log...
我的第9条log...
我的第10条log...

3、被测试程序的实际输出
   这个就不难理解了,查看是否输出了具体的值或者执行的操作; :)

 


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
场景监视过程:
1、vuser的log
   Loadrunner场景监视过程中,是可以查看某个vuser运行的log的;
   具体的操作步骤:
   A、打开vuser信息窗口(双击用户组中运行的vuser即可打开窗口)
   B、选择你要查看的vuser的信息,右键选择Show vuser log
   C、可以查看vuser的log了,这里的log不能显示lr_message、lr_log_message输出的log
   适当的增强脚本的log输出,可以让我们在vuser执行脚本出现问题时,准确的定位问题的位置;
   例如,在使用参数化用户名和密码登录某系统,脚本中使用lr_output_message打印出当前的参数值,如果登录失败,那么用手动去登录试试,这样就能检查出是否是参数的数据有问题了;如果结合返回的错误来进行判断,那就更完美了。举个例子吧:

我输入一个网址,网址中包含若干参数(ID、password),网址提交后IE返回登录结果(A\X\Z\D);返回A代表登录成功,返回X代表登录失败,返回Z和D是其他情况;
/*********************************
  * Author:qiguojie
  * object:software login
  * date:2007-5-28
***********************************/
Action()
{
//变量定义区
    typedef long time_t;       //定义一个时间变量
    time_t t;        //定义一个时间变量
    web_reg_save_param("IsRight","LB=Cache-control: private\r\n\r\n","RB=|",LAST);  //保存返回值
    time(&t);        //获取当前时间
    web_url("abclogin.asp",
        "URL=http://192.168.1.9/soft/abclogin.asp?U={user}&P={password}&L=0&H=3HS28QKH",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=",
        "Snapshot=t1.inf",
        "Mode=HTML",
        LAST);
    lr_output_message("%s,随机数是%d,",ctime(&t),n);
    lr_output_message("用户是:%s,密码是:%s,",lr_eval_string("{user}"),lr_eval_string("{password}"));
//判断返回值,输入对应日志
    if (strcmp(lr_eval_string ("{IsRight}"),"A") == 0)//如果返回值是A
    {
        lr_output_message("success:用户登录成功,返回值是:%s",lr_eval_string("{IsRight}"));
    }
    else if (strcmp(lr_eval_string ("{IsRight}"),"X") == 0) //如果返回值是X
    {
        lr_output_message("failed:用户登录失败,返回值是:%s\n",lr_eval_string("{IsRight}"));
    }
    else if (strcmp(lr_eval_string ("{IsRight}"),"Z") == 0)//如果返回值是Z
    {
        lr_output_message("success_others:登录特殊页成功,返回值是:%s\n",lr_eval_string("{IsRight}"));
    }
    else //如果返回值是D
    {
        lr_output_message("success_free:登录免费用户成功,返回值是:%s\n",lr_eval_string("{IsRight}"));
    }
    return 0;
}


2、事务执行情况
   在controllor里执行场景时,是可以即时监视事务的执行情况的,单击Run选项卡里Passed或Failed Transactions后面的放大镜图标,就可以打开;
   可以监视的参数如下:
   A、不同事务的tps
   B、不同事务的Passed、Failed以及Stopped状态数
   TPS(Transactions per second):每秒事务数,衡量目前场景执行过程中的事务处理速度,越大说明目前事务执行效率越高;当然,你的事务中包含多个函数还是只有web_url一个函数,这个tps肯定是不同的,所以我只拿这个指标做监视用;


3、ERROR
   在controllor里执行场景时出现错误,是可以即时查看错误信息的,,单击Run选项卡里的Errors后面的放大镜图标,可以打开;另外还可以通过菜单view-show output来打开
   具体的功能大家就自己发掘吧,呵呵

当然,结果分析(Analysis)是lr最重要的输出,具体也就不介绍了;论坛和博客里有很多帖。

 

 

 

最近在论坛上看到有人提问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}"));  

 

 

strcmp() 用来比较字符串(区分大小写),其原型为:
    int strcmp(const char *s1, const char *s2);

strcmp

C/C++函数,比较两个字符串
设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1>str2,则返回正数;
若str1<str2,则返回负数。
 
当s1<s2时,返回为负数
当s1=s2时,返回值= 0
当s1>s2时,返回正数
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如:
"A"<"B" "a">"A" "computer">"compare"
特别注意:strcmp(const char *s1,const char * s2)这里面只能比较字符串,即可用于比较两个字符串常量,或比较数组和字符串常量,不能比较数字等其他形式的参数。
ANSI标准规定,返回值为正数,负数,0 。而确切数值是依赖不同的C实现的。
【参数】s1, s2 为需要比较的两个字符串。

 字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和'b'(98)的差值(-33)。

 【返回值】若参数s1 和s2 字符串相同则返回0。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。

 注意:strcmp() 以二进制的方式进行比较,不会考虑多字节或宽字节字符;如果考虑到本地化的需求,请使用 strcoll() 函数。

 【实例】对 4 组字符串进行比较。






#include <string.h>
main()
{ char *a = "aBcDeF"; char *b = "AbCdEf"; char *c = "aacdef"; char *d = "aBcDeF"; printf("strcmp(a, b) : %d\n", strcmp(a, b)); printf("strcmp(a, c) : %d\n", strcmp(a, c)); printf("strcmp(a, d) : %d\n", strcmp(a, d)); } 输出结果: strcmp(a, b) : 32 strcmp(a, c) :-31 strcmp(a, d) : 0

 

posted @ 2015-05-06 09:59  Agoly  阅读(1150)  评论(0编辑  收藏  举报