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.

原文地址:https://www.cnblogs.com/jingzaixin/p/13601168.html