• lr脚本语言架构


    Action介绍:

    1.一个Actions就是一个函数包,将用户操作根据类型存放在不同的函数中,当脚本生成的时候,会在对应的目录下生成:

      vuser_init.c

      Action.c

      vuser_end.c

      三个action.

      每个action是一组功能的集合,默认的action包含独立的3个函数为vuser_init(),vuser_action()、vuser_end().

      还有一个gloabls.h文件,用于存放全局变量,头文件内容等

    2. action函数结尾处都有一个return 0 的命令,这是用来退出当前函数的。Return 0 说明该函数正常的结束,如果是非0值,可能表示非正常退出。

    3.

      Vuser_init函数:

        一般将用户初始化的操作放在里面,如登录操作,分配内存等。

      Action函数:

        是虚拟用户要做的业务。用户的业务操作,也就是测试内容的主体。可以写多个action.c文件来作为业务操作流程

      Vuser_end函数:

        与Vuser_init相对应,Vuser_end做收尾工作,复位环境重置等。

    4.通过运行结果我们可以想象LR的实现是这样的:

      int vuser_init(){

      }

      int action(){

      }

      int vuser_end(){

      }

    5.数据类型:

      类型                              bit数                     范围

      Unsigned char               8bit                      0--255

      char                               8bit                      -128--127                         字符类型

      Unsigned int                  32bit                    0--4294967295

      Short int                        16bit                     -32768--32767

      double                           64bit                     1.7e-308--1.7e308

      int                                  32bit                     -2147483648--2147483647    整型

      unsigned long               32bit                     0--4294967295

      float                               32bit                     3.4e-38--3.4e38                    浮点型

    6. c语言无字符串的概念,只有字符类型

    7.表达式:

      1.#define 定义常量: 宏定义一个常量,常量的值是不可变化的

      例如: #define COUNT 100

      2.表达式语句

        表达式语句由表达式加上分号“;”组成

        例如: 

          Action()

          {

            int x,y,z;

            x=20;

            y=30;

            z=x+y;

            lr_output_message("%d+%d=%d",x,y,z);

            lr_output_message("%d",z*COUNT);

            return 0 ;

          }

       其中lr_output_message()函数为输出打印信息函数

           %d表示整型数据

    8.函数的调用语句

      函数的调用语句由函数名,实际参数加上分号“;”组成

      例如:

    int sum(a,b)
    {
        int x,y,z;
        x=a;
        y=b;
        z=x+y;
        return z;
    }
    
    
    Action()
    {
        lr_output_message("sum = %d",sum(20,30));
        return 0;
    }

    9.条件语句

      Action()

      {

        int random;

        random = rand()%3+1;

        switch(random)

        {

          case 1:

            lr_output_message("random = %d",random);

            break;

          case 2:

            lr_output_message("random = %d",random);

            break;

          default:

            lr_output_message("random = %d",random);

        }

      }

      其中random = rand()%3+1;中rand()为一个随机函数,%3取得是0,1,2;%3+1取得就是0,1,2,各加1为1,2,3;所以rand()%3+1表示取1,2,3;

      例子:使用随机函数从1,2,3,4中随机随处一个数字做判断,如果为1则做加法,为2则做减法,为3则做乘法,为4则做除法,代码如下:

    Action()
    {
        int x=0,y,z;
        x = rand()%4+1;   //rand()%4表示使用rand()函数随机出现四个数,0,1,2,3;+1表示各个随机数加1,为1,2,3,4
                          //如果需要随机出3个数,则为%3
        y = 4;
        z = 2;
        lr_output_message("x=%d",x);
        switch(x)
        {
            case 1:
                    lr_output_message("执行加法运算");
                    lr_output_message("%d+%d=%d",y,z,y+z);
                    break;
            case 2:
                    lr_output_message("执行减法运算");
                    lr_output_message("%d-%d=%d",y,z,y-z);
                    break;
            case 3:
                    lr_output_message("执行乘法运算");
                    lr_output_message("%d*%d=%d",y,z,y*z);
                    break;
            default:
                    lr_output_message("执行除法运算");
                    lr_output_message("%d/%d=%d",y,z,y/z);
        }
        
        return 0;
    }

    10.循环语句

    switchaction()
    {
        int i=1,sum=0;
        int count;
        do{
            sum = sum+i;
            i++;
        }while(i<=10);
        lr_output_message("1到10之间和为:%d",sum);
        return 0;
    }

    11.for循环

    forAction()
    {
        int i=1,sum=0;
        for(i=1;i<=10;i++)
        {
            sum = sum+i;
        }
        lr_output_message("1到10之间和为:%d",sum);
        return 0;
    }

     12.字符串

      C语言里没有字符串类型的数据,可以用字符数组来表示一个字符串。

      例如 char test[] = "abcdefg";

      示例:

    charAction()
    {
        char test1[]={'a','b','c'};
        lr_output_message("test1 = %s",test1);
        return 0;
    }

      正确语法:

    charAction()
    {
        char test1[]={'a','b','c'};
    
        char test2[]="This is a test!";
        
        lr_output_message("test1 = %s",test1);
        lr_output_message("test2 = %s",test2);
        return 0;
        
    }

      错误语法:

    charAction()
    {
        char test1[]={'a','b','c'};
        lr_output_message("test1 = %s",test1);
        char test2[]="This is a test!";
        lr_output_message("test2 = %s",test2);
        return 0;
        
    }

      需要先定义完所有变量后,再运行往下,否则会报错误

    13.

      c语言中数组的名字代表某个元素的首地址

      %s表示字符串的占位符

    14.结构体

    struct student
    {
        int num;   //学号
        char name[20]; //姓名
        int score; //成绩
    };
    
    jiegouttiAction()
    {
        struct student stu[2]=
        {
            {101,"jack",100},
            {102,"tom",90}
        };
        int i;
        for(i=0;i<2;i++)
        {
            lr_output_message("-----------------------------------------");
                
            lr_output_message("第%d个学生的信息:",i+1);
                
            lr_output_message("学号%d",stu[i].num);
                
            lr_output_message("姓名%s",stu[i].name);
            lr_output_message("成绩%d",stu[i].score);
        }
        return 0;
    }

    15.指针

      指针:一个变量的地址

      指针变量:专门存放变量地址的变量叫指针变量

      指针变量的定义:

        一般形式:[存储形式]数据类型*指针名;

        例如: int *p1,*p2,float *q;

        &含义:取指针的地址&和*运算符

        *含义:取指针所在变量的内容

    zhizhenAction()
    {
        char test1='a',test2='d';
        char *p1 = &test1; //给指针赋值
        char *p2; //定义一个指针,未赋值
        lr_output_message("p1=%c",*p1); //输出指针p1指向地址的内容
        p2=&test1;
        lr_output_message("p2=%c",*p2); //输出指针p2指向地址的内容
        *p2 = 'b';
        lr_output_message("p1=%c,p2=%c,test1=%c",*p1,*p2,test1); 
        test2 = *p2;
        lr_output_message("test2=%c",test2);
        return 0;
    }

    16.其他的编程语言中是没有指针的,只有C语言中有

    17.头文件

    gloabls.h如下:

    #ifndef _GLOBALS_H
    #define _GLOBALS_H
    
    //--------------------------------------------------------------------
    // Include Files
    #include "lrun.h"
    #include "web_api.h"
    #include "lrw_custom_body.h"
    
    //--------------------------------------------------------------------
    // Global Variables
    
    #endif // _GLOBALS_H

      #include,#ifndef这些都是预处理。

      所谓预处理是指对一个源程序进行编译时,系统将首先自动引用预处理程序对源程序中的预处理部分进行处理,处理完毕后再自动进入源程序的编译。

      预处理是C语言的重要功能,define宏定义也是预处理。

      Include是把指定的文件与当前源文件连成一个文件。

      Ifndef,define和endif是为了防止头文件被重复调用。

    18.变量位置决定变量使用范围:

      1.局部变量

      例如再某个action中的某个函数中定义一个变量,则只能在该函数中引用,如下的变量i,sum等:

    switchaction()
    {
        int i=1,sum=0;
        int count;
        do{
            sum = sum+i;
            i++;
        }while(i<=10);
        lr_output_message("1到10之间和为:%d",sum);
        return 0;
    }

      2.全局变量,但是只能在定义此变量之后的使用,在此变量之前,不能使用,如下的变量ddaccountcsrfmiddlewaretoken,x等:

    add_account()
    {
    
        lr_think_time(15);
        web_reg_save_param("addaccountcsrfmiddlewaretoken","LB='csrfmiddlewaretoken' value='","RB=' />",LAST);
       int x=0;
        web_url("add", 
            "URL=http://192.168.1.102:8000/users/userprofile/add/", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=http://192.168.1.102:8000/users/userprofile/", 
            "Snapshot=t11.inf", 
            "Mode=HTML", 
            EXTRARES, 
            "Url=/static/xadmin/vendor/font-awesome/fonts/fontawesome-webfont.eot?", ENDITEM, 
            LAST);
    
        return 0;
    }

      3.全局变量,在整个Action代码中都可以使用,如下x变量(变量必须是放在gloabls.h文件中):

      gloabls.h文件内容:

    #ifndef _GLOBALS_H
    #define _GLOBALS_H
    
    //--------------------------------------------------------------------
    // Include Files
    #include "lrun.h"
    #include "web_api.h"
    #include "lrw_custom_body.h"
    int x=0;
    //--------------------------------------------------------------------
    // Global Variables
    
    #endif // _GLOBALS_H

    19.全局变量与局部变量

      局部变量

        局部变量也称为内部变量,它是在函数内定义的,其作用域仅限于函数内部,离开该函数后不可以使用。虚拟用户脚本中的局部变量应该定义在vuser_init(),action(),vuser_end(),新创建的用户action及用户自定义函数的内部。

      全局变量

        全局变量也称为外部变量,它是在函数外部定义的变量,在定义位置后的所有脚本中都可以调用。虚拟用户脚本中的全局变量应该定义在vuser_init(),action(),vuser_end(),新创建的用户action及用户自定义函数的外部。

        演示实例

          在头文件globals.h中定义一全局变量 int sum =10;然后在vuser_init,Action,vuser_end三个函数中加入语句

            lr_output_message("sum2 = %d", sum);正常运行

          如果只在Action中定义int sum =10,而vuser_init与vuser_end没定义,运行时就会报错

     20.脚本的调试

      脚本的提示对于脚本的编写非常重要

      断点设置技术时脚本开发中最重要的开发技术

        当预期结果与实际结果不一致时,可以在怀疑有问题的代码前插入断点,当程序运行到断点的时候,就会停下来,这时候可以通过日志,定位问题。

      设置断点的四种方式

        点击右键选Toggle Breakpoint 

        或者点击菜单栏的insert->Toggle Breakpoint 

        或者按F9设置断点

        或者在代码行,左击添加或撤去断点

      单步跟踪

        每执行一条语句,程序就会听下来,可以结合日志分析脚本

        方法:

          按F10

          或者运行 run step by step按钮

          或者 Replay->Run Step by Step

      Bookmarks设置标签

        按ctrl+F2可以在代码行上设置一个标签,通过按F2与shift+F2,可以往前往后切换代码行。

      代码折叠

        录制出来的代码比较长,可以设置折叠,方便查看,鼠标右键,找到菜单expand/collapse,可以设置脚本为折叠模式。

      代码日志定位

        如果需要找到代码所对应的日志位置,可以在函数上单击右键,选Go to Step in Replay log 命令

      快速打开代码目录

        单击右键,选open script directory 命令就可以打开代码所在的目录

    21.脚本模板使用

      如何使用模板

        性能测试脚本如果很多,要规范脚本,就需要模板功能。

        先创建一个空脚本,在脚本中说明维护信息,保存为模板,然后打开file下的“保存为模板”(File->User-Defined Template->Export to Template...),以后每次开发的时候,就可以使用模板的形式,统一规范某些内容。

    22.脚本的导入与导出

      VuGen的脚本有很多文件组成,运行后还会产生日志文件与测试结果,要管理好这些,可以通过打包的方式保存以便管理与使用:

        File->Manage Zip Files->Export to zip

          Runtime files(运行时文件):只包含运行脚本的基本内容,比较小

          All files(所有文件):整个脚本目录,包括日志与运行结果,比较大

    23.在脚本中加载dll函数

      Loadrunner提供了加载DLL的函数

      lr_load_dll(char*library_name).通过在参数中给出dll文件的地址,可以将已经用visucalc++开发好的DLL文件加载到loadrunner的执行空间中.dll加载成功之后,可以调用dll中定义的任何导出函数,而无须在脚本中对其进行声明。

        例如: Lr_load_dll("my_dll");

            Myfunc();//本函数在my.dll中定义,在加载my.dll后,可以立即调用。

      Lr_load_dll函数主要用在基于C语言解释器的虚拟用户中。

      在函数的参数中可以指定调用Dll的完整路径,也可以只提供其文件名,脚本将会按照系统的默认路径来查找Dll。

      在windows平台下如果不指定路径,则按照visualc++的loadlibrary函数的查找对应的Dll文件。

    24.Vuser常用函数

      lr_end_sub_transaction: 标记子事务的结束以便进行性能分析

      lr_end_transaction_instance:标记事务实例的结束以便进行性能分析

      lr_fail_trans_with_error:将打开事务的状态设置为LR_FAIL并发送错误消息

      lr_get_trans_instance_duration:获取事务实例的持续时间(由它的句柄指定)

      lr_get_trans_instance_wasted_time:获取事务实例浪费的时间(由它的句柄指定)

      lr_get_transaction_duration:获取事务的持续时间(按事务的名称)

      Lr_get_transaction_think_time:获取事务的思考时间(按事务的名称)

      Lr_get_transaction_wasted_time:获取事务的浪费时间(按事务的名称)

      Lr_save_string()函数用于把一个字符串保存到参数中。

        函数语法结果如下:

          Int Lr_save_string(const char *param_value,const char *param_name)

          param_value:是将要保存的字符串,

          char *param_name:是将要保存的参数名称,

        例如:

          Lr_save_string("abcdefg","param");

          执行后,将把字符“abcdefg”保存到param中,然后脚本就可以直接通过{param}来使用参数param

      Lr_save_var用来把字符串中的一部分内容保存为参数,函数语法如下

        Lr_save_var(const char *param_value,unsigned long const value_len,unsigned long const option,const char*param_name);

        param_value:是将要进行截取的字符串

        value_len:是将要截取的长度

        option:是留参数,可设为0

        param_name:是保存的参数名称

        例如:

          lr_save_var("abcdefg",5,0,"paramstr");

          执行后,将把字符串“abcdefg”中前5个,即“abcde”保存到参数paramstr,然后脚本中就可以直接通过{paramstr}来使用参数paramstr

      Lr_eval_string函数的使用非常广泛,主要是用来返回参数中的实际内容,也可以返回一个包含参数的字符串的实际内容,语法结构如下:

        Char *lr_eval_string(const char*instring);

        instring:是参数或包含参数的字符串

        例如:

          lr_save_string("abcdefgh","paramstr");

          Lr_output_message("paramstr=%s",lr_eval_string("{paramstr}"));

          执行以上两语句后,将输出“paramstr=abcdefgh”

    25.

  • 相关阅读:
    基于nginx+tomcat部署商城系统并连接数据库
    nginx防DDOS、cc、爬虫攻击
    nginx企业级优化
    基于nginx结合openssl实现https
    nginx打包成rpm
    产品运营3部曲:引量、留存、活跃
    从赢利前和赢利后分析 提高美国市场APP安装量的技巧
    APP海外优质推广渠道(三):海外ASO服务/工具汇总
    APP海外优质推广渠道(二):海外广告联盟/平台汇总
    关于O2O项目的个人看法
  • 原文地址:https://www.cnblogs.com/jingzaixin/p/13601168.html
Copyright © 2020-2023  润新知