美文网首页工作生活
Loadrunner性能测试(三):关联函数、检查点、事务、思考

Loadrunner性能测试(三):关联函数、检查点、事务、思考

作者: 零下的雨 | 来源:发表于2019-07-04 16:16 被阅读0次

    关联函数:

    image.png

    该函数的功能很强大:
    1、用#代表任何数字

    image.png
    2、使用^代表通配符
    image.png
    3、获取匹配到的第几个值
    image.png
    4、找不到时报error还是报警,建议报警,这样程序还能继续执行
    image.png
    5、搜索范围,建议选择全部
    image.png
    6、类似 java中的substring方法,从第10个字符开始截取到第50个字符
    image.png
    7、忽略重定向
    image.png

    关联数组

    要实现的一个需求是进入csdn首页,能够随机点击左侧导航栏进入到相应的栏目中。

    image.png
    比如进入程序人生:
    image.png
    链接是https://www.csdn.net/nav/career,每个栏目的域名相同,后面部分不同,要从首页的源码中查看每个栏目后面的部分信息,然后提取到一个数组中:
    image.png

    脚本已经录制完成,在脚本中添加步骤添加函数:


    image.png

    要给 引号加转义符


    image.png
    image.png

    打印:
    lr_output_message(lr_eval_string("{getitems}"));
    因为是数组所以打印结果是:


    image.png

    打印出第二个:
    lr_output_message(lr_eval_string("{getitems_2}"));


    image.png
    image.png

    获取全部的值:

        //获取数组的长度的函数lr_paramarr_len("getitems")
        //lr_paramarr_idx("getitems",i)根据下标索引获取数组中的数据
        for(i=1;i<=lr_paramarr_len("getitems");i++){
            lr_output_message(lr_paramarr_idx("getitems",i));
        }
    

    随机获取一个值

    r_output_message(lr_paramarr_random("getitems"));
    

    使用sprintf给一个变量赋值:

         //sprintf(myurlstring,"{getitems_%d}",i); 是把"{getitems_%d}"的值赋值给myurlstring,myurlstring是char数组,必须用数组才行要不然会报错,并打印出来
         for(i=1;i<=lr_paramarr_len("getitems");i++){
            sprintf(myurlstring,"{getitems_%d}",i);
            lr_output_message(lr_eval_string(myurlstring));
         }
    

    //保存参数的函数lr_save_string(第一个参数是参数值,第二个参数是参数名称可以随意设置),这个参数testurl可以被下面的函数使用

        lr_save_string(lr_paramarr_random("getitems"),"testurl");
        lr_output_message(lr_eval_string("{testurl}"));
    

    拼接参数并关联应用到下面的函数中

        //拼接要访问的url
        sprintf(askurlstring, "https://www.csdn.net%s", lr_paramarr_random("getitems"));
        lr_output_message(askurlstring);//打印变量查看变量有没有拼接成功
        //把拼接的url保存到一个变量中这样才能被下面的函数应用
        lr_save_string(askurlstring,"askurlstring");
        
        //访问拼接的url
            web_url("career", 
            "URL={askurlstring}", 
            "TargetFrame=", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=", 
            "Snapshot=t113.inf", 
            "Mode=HTML", 
            LAST);
    

    下面的代码实现的是打开csdn的首页,然后随机选中一个栏目,再进入栏目中随机点击一篇文章。

    Action_Allcode()
    {
        //变量的声明必须放到前面,开始执行代码后不能声明变量
        
        //声明一个变量,必须放到首行这个位置才行
        int i;
        
        //声明一个char变量,用来存放拼接的URL地址
        char* urlstring="https://www.csdn.net";
        
        //声明一个长度为1024的char数组,下面没有用到
        char myurlstring[1024];
        //声明一个长度为1024的char数组,应用到下面的url中
        char askurlstring[1024];
        
        //声明一个char变量,用于存放栏目的名称
        char *askurltitle;
        
    
        web_set_sockets_option("SSL_VERSION", "TLS1.1");
    
        web_add_cookie("Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_19814196820-1526528487575-539618; DOMAIN=www.csdn.net");
    
        web_add_cookie("uuid_tt_dd=10_19814196820-1526528487575-539618; DOMAIN=www.csdn.net");
    
        web_add_cookie("dc_tos=ptyfw6; DOMAIN=www.csdn.net");
    
        web_add_cookie("dc_session_id=10_1526528487575.516753; DOMAIN=www.csdn.net");
    
        web_add_cookie("Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1561970163; DOMAIN=www.csdn.net");
    
        web_add_cookie("TY_SESSION_ID=47e865f3-1857-4c8d-8791-ab14094f7f4f; DOMAIN=www.csdn.net");
    
    
    
        web_reg_save_param("getitems",
            "LB/ALNUMLC=<li class=\"\"><a href=\"",
            "RB=\">",
            "Ord=ALL",
            LAST);
    
        
        
    //  web_reg_save_param_regexp(
    //      "ParamName=getitems",
    //      "RegExp= <li class=\"\"><a href=\"/nav/.*\">.*</a></li>",
    //      "Group=0",
    //      SEARCH_FILTERS,
    //      LAST);
        
        
    
        web_url("www.csdn.net", 
            "URL=https://www.csdn.net/", 
            "TargetFrame=", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=", 
            "Snapshot=t109.inf", 
            "Mode=HTML", 
            EXTRARES, 
            "Url=/images/icon_close_big.png", ENDITEM, 
            "Url=/images/is_top_big.png", ENDITEM, 
            "Url=/favicon.ico", "Referer=", ENDITEM, 
            "Url=/images/icon_close_hover_big.png", ENDITEM, 
            LAST);
        
    //  //打印出数组的第二个值,数组的下标是从1开始的,所以第二个是2
    //      lr_output_message(lr_eval_string("{getitems_2}"));
    //              
    //      
    //  //获取数组的长度的函数lr_paramarr_len("getitems")
    //  //lr_paramarr_idx("getitems",i)根据下标索引获取数组中的数据
    //  for(i=1;i<=lr_paramarr_len("getitems");i++){
    //      lr_output_message(lr_paramarr_idx("getitems",i));
    //  }
            
        
         //lr_paramarr_random("getitems")随机获取数组中的数据
    //     lr_output_message(lr_paramarr_random("getitems"));
        
      
         
         
         //sprintf(myurlstring,"{getitems_%d}",i); 是把"{getitems_%d}"的值赋值给myurlstring,myurlstring是char数组,必须用数组才行要不然会报错,并打印出来
    //     for(i=1;i<=lr_paramarr_len("getitems");i++){
    //      sprintf(myurlstring,"{getitems_%d}",i);
    //      lr_output_message(lr_eval_string(myurlstring));
    //     }
        
        
        //保存参数的函数lr_save_string(第一个参数是参数值,第二个参数是参数名称可以随意设置),这个参数testurl可以被下面的函数使用
    //    lr_save_string(lr_paramarr_random("getitems"),"testurl");
    //    lr_output_message(lr_eval_string("{testurl}"));
        
         
        //拼接要访问的url
        sprintf(askurlstring, "https://www.csdn.net%s", lr_paramarr_random("getitems"));
        lr_output_message(askurlstring);//打印变量查看变量有没有拼接成功
        //把拼接的url保存到一个变量中这样才能被下面的函数应用
        lr_save_string(askurlstring,"askurlstring");
        
        //多次迭代web_url的名称都一样,本来想实现名称要根据点击的url变化,web_url的名称不能用变量参数
        //从字符串后面开始搜索'/',找到后直接截取包含'/'的后面的内容
        askurltitle=(char *)strrchr(askurlstring,'/');        
        lr_save_string(askurltitle,"askurltitlestring");//保存到askurltitlestring中并打印查看结果
        lr_output_message(lr_eval_string("{askurltitlestring}"));
        
        //添加一个关联参数,从随机进入的栏目返回的结果中获取文章url
            web_reg_save_param("articleurl",
            "LB=data-track-view='{\"mod\":\"popu_459\",\"con\":\",",
            "RB=,",
            "Ord=ALL",
            LAST);
        
        //访问拼接的url
            web_url("career", 
            "URL={askurlstring}", 
            "TargetFrame=", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=", 
            "Snapshot=t113.inf", 
            "Mode=HTML", 
            LAST);
        
        
        
    //  //打印输出获取到的articleurl值
    //  lr_output_message(lr_eval_string("{articleurl}"));
    //  
    //  //打印输出关联数组中的每一个值,并存到变量中
    //  for(i=1;i<=lr_paramarr_len("articleurl");i++){
    //      lr_output_message(lr_paramarr_idx("articleurl",i));
    //  }
        
        
        //从访问的栏目url中随机取一个articleurl值并存到变量中
        lr_save_string(lr_paramarr_random("articleurl"),"articleurlstring");
        lr_output_message(lr_eval_string("{articleurlstring}"));
        
        
                          
        web_url("89089809", 
            "URL={articleurlstring}", 
            "TargetFrame=", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=https://www.csdn.net/nav/career", 
            "Snapshot=t118.inf", 
            "Mode=HTML", 
            EXTRARES, 
            "Url=https://www.csdn.net/favicon.ico", "Referer=", ENDITEM, 
            "Url=https://pagead2.googlesyndication.com/pagead/js/r20190626/r20190131/show_ads_impl.js", ENDITEM, 
            "Url=https://pagead2.googlesyndication.com/pub-config/r20160913/ca-pub-1076724771190722.js", ENDITEM, 
            "Url=https://www.googletagservices.com/activeview/js/current/osd.js?cb=%2Fr20100101", ENDITEM, 
            "Url=https://entry.baidu.com/rp/bwordcom?di=&user=&page_url=https%3A%2F%2Fblog.csdn.net%2FPx01Ih8%2Farticle%2Fdetails%2F89089809&logid=111&title=%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%AE%97%E6%B3%95%20-%20ConcurrentHashMap%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%20-%20%3Csdffdsfsdfdfs%3Esfsfsfsdfsdffds%3C%2FsdfsDS%3EFsd%20-%20CSDN%E5%8D%9A%E5%AE%A2&jsonp=baidu_bw_1562048038258", ENDITEM, 
            LAST);
        
        
        return 0;
    }
    

    loadrunner还有其他的关于字符串的函数没有用到,可以参考:
    https://www.cnblogs.com/qmfsun/p/4900562.html

    事务

    统计每一个请求或者每一批请求的响应时间,评估系统的处理速度。
    统计事务的成功率:评估系统的稳定性。
    自动事务有两个选项:按每一个操作action为一个事务、按每一个步骤为一个事务


    image.png

    保存action,创建controller场景,运行查看按每一个action为一个事务的执行情况:


    image.png

    运行完毕,点击事务响应时间查看结果,显示最大值、最小值、平均值等信息:


    image.png

    再设置按每一个步骤为一个事务查看响应时间:


    image.png

    可以不勾选自动事务,也可以勾选,不冲突,手动设置事务:


    image.png
    image.png

    手动定义三个事务,进入controller场景中运行查看事务响应时间:


    image.png

    在事务中写其他代码也会产生浪费时间,可以把这部分时间减去,代码如下:

    Action_wastertime()
    {
        
        double time_elapsed;//定义double类型的变量,用来存储时间
        merc_timer_handle_t timer;//定义timer 用来接收开始时间
        int i;//定义一个整型变量,可以做循环
        char b[50];//定义一个char数组,用来把double类型的时间转换成char类型,可以打印出来
        
        lr_start_transaction("testing");//开始事务
        
        web_url("www.baidu.com", 
            "URL=http://www.baidu.com/", 
            "TargetFrame=", 
            "Resource=0", 
            "RecContentType=text/html", 
            "Referer=", 
            "Snapshot=t1.inf", 
            "Mode=HTML", 
            EXTRARES, 
            "Url=/favicon.ico", "Referer=", ENDITEM, 
            LAST);
    
    
        
        timer=lr_start_timer();//开始计算时间
        
        for(i=0;i<1000;i++){
            lr_output_message("消耗时间");
        }
        
        time_elapsed=lr_end_timer(timer);//结束计算时间
        
        lr_wasted_time(time_elapsed*1000);//从毫秒换算成秒后加入浪费时间中
        
        lr_end_transaction("testing", LR_AUTO);//结束事务,事务会自动减去浪费时间
    
        
        sprintf(b,"%2f",time_elapsed);//把double类型的浪费时间变量转换成char类型数组,并赋值给b变量
        lr_save_string(b,"time_elapsedpara");//把变量转换成参数
        lr_output_message("浪费的时间是:%s",lr_eval_string("{time_elapsedpara}"));//打印浪费时间
    
        return 0;
    }
    
    

    检查点

    loadrunner结束事务中的LR_AUTO只是通过状态码来区分事务是否成功,比如登录时密码错误,能正常返回界面告诉用户密码错误请重新输入密码,对loadrunner来说检测到服务器返回是200的状态码,所以检测到事务成功了,但是从业务角度来说并没有成功,所以需要通过检查点来判断事务是否真正的成功。

    插入函数,函数要放到请求之前,可以按文本去查也可以按字符串去查:


    image.png

    根据统计次数大于等于1判断请求成功。


    image.png

    也可以使用函数自定义修改事务的状态:
    lr_set_transaction_status_by_name(LR_FAIL,"protectcar");
    lr_set_transaction_status_by_name(LR_PASS,"protectcar");

    勾选和不勾选这个对注册检查点web_reg_find()函数无效。


    image.png

    思考时间

    image.png
    image.png

    思考时间就是模拟用户暂停发请求的时间,为了让loadrunner模拟真实的场景,是需要使用思考时间的。


    image.png
    思考时间定为5秒,按最小值50%,最大值200%随机选取思考时间:
    image.png

    集合点01

    集合点适用场景是并发测试,主要关注大用户量的并发。分为两种情况:1、所有用户都在并发请求,请求的模块可能是不同的 2、所有用户都在提交同一个请求。

    集合点是不能模拟真实场景,至少不能很绝对的模拟,因为不可能达到绝对的并发,服务器接收到请求也是有先后顺序的,处理请求也是需要队列处理,所以达不到绝对意义的并发。

    并发测试:相对严格的并发,并没有绝对严格的并发测试。并发测试属于压力测试的一个子集。

    压力测试:关注系统最大的瓶颈是多少,系统在什么时候会发生崩溃,系统在什么样的场景下会发生崩溃。并发测试属于压力测试的一个子集。做压力测试时不需要设置思考时间,直接压测就行。

    负载测试:评估性能指标,当系统有100个人、1000个人、10000个人访问的时候系统的处理情况是什么,cpu、内存、数据库等的表现是什么样的。

    稳定性测试:系统在标准用户数、最佳状态下的长时间的一种运行,比如cpu利用率在70%~80%左右,资源充分利用并且还有上升的空间的一种状态。

    系统的最大用户数:是指某一个指标出现极限时的一种状态,不可能所有指标都出现极限状态,比如内存到达极限,或者cpu到达极限等等。

    容量测试:模拟系统长时间运行后的性能状态,目前流行的关系型数据库中都有自己的存储引擎,比如使用索引、关键字等可以很快速的查询出数据。比如查询1000条和查询1亿条时数据库的处理速度是什么样的,sql语句是否要优化等的测试。

    集合点02

    先创建一个事务,再创建一个集合点就会出现事务统计的时间不准确的情况,因为因为集合点是要等所有用户到达后统一去发起下一个请求,所以集合点中有一个等待的时间,暂停的时间是要统计到事务的时间中的,所以集合点不能放到事务里面要放到外面,这样事务统计的时间才准确。

    模拟场景一:集合点放在事务里面,查看统计时间

    image.png

    每隔10秒会释放5个用户:


    image.png

    事务的响应时间:


    image.png

    模拟场景二:集合点放在事务外面,查看统计时间

    image.png
    前5秒先运行5个用户,其他用户等待状态:
    image.png
    到时间再释放5个
    image.png
    全部释放开始运行
    image.png
    事务响应时间:
    可见最大时间比上一个场景的时间小,最后一个运行时间也变小了
    image.png

    模拟场景三:上两个场景持续运行时间太长,导致一些虚拟用户迭代失败,现在改成持续运行3分钟
    可以看出后到集合点的用户已用时间短:

    image.png

    了解场景中的集合

    image.png

    每隔10秒释放5个用户,在场景中设置当运行的用户到达时就可以开始发出请求


    image.png

    第一个选项是说当所有的虚拟用户都到达时才发出请求,与设置的每隔10秒释放5个用户是有冲突的,这样每隔10秒释放5个用户,释放后用户要等待,等待所有的用户都被释放后才发出请求


    image.png

    vuser之间的超时值设置为10秒,是说当选中第一个选项时,在用户还没到达但是已经超时了就不再等待用户了,直接发出请求,这样不浪费时间


    image.png

    这个配置是说当有1个用户到达时就发出请求:


    image.png

    一般使用默认的配置就可以:


    image.png

    模拟场景四,设置等所有用户到达时才发起请求

    image.png
    不太明显。

    函数总结:
    lr_output_message(lr_eval_string("{参数名称}"))
    打印结果是否获取成功
    web_reg_save_param_ex()关联参数
    web_reg_save_param()关联函数
    lr_paramarr_len("getitems")获取数组的长度
    lr_paramarr_idx("getitems",i)根据下标索引获取数组中的数据
    lr_paramarr_random("getitems")随机获取数组中的数据
    sprintf(myurlstring,"{getitems_%d}",i); 是把"{getitems_%d}"的值赋值给myurlstring,myurlstring是char数组,必须用数组才行要不然会报错
    lr_save_string(lr_paramarr_random("getitems"),"testurl");//lr_save_string(第一个参数是参数值,第二个参数是参数名称可以随意设置)
    web_reg_find检查点函数,要放到请求之前
    lr_log_message("要打印的日志内容");
    lr_get_attrib_string("在运行时设置中其他属性的参数名称")
    web_custom_request()发送自定义请求,与web_url,web_sumbit_data()一样
    web_add_header("content_type","application/json")增加请求头,如果接口中需要在header中传token,也可以用这个函数把token加到请求头中,因为token会随着登录的变化而变化,所以需要先使用关联函数获取到token然后再把token放到header中供下面的接口使用。
    web_get_int_property(HTTP_INFO_RETURN_CODE)获取上一个请求的返回码,返回类型是int,可以赋值给变量,用于判断请求结果。
    lr_load_dll("md5.dll");加载md5.dll 加密方法放到loadrunner的bin目录下,直接引用dll,然后就可以直接用他里面的加密方法了。测试中也可能是其他的加密方法,可以找开发要。
    lr_convert_string_encoding()转换字符类型,下面会讲解具体使用方法。
    web_reg_save_param_xpath()接口返回内容是xml时可以通过这个关联函数获取参数,查询路径是xpath路径
    web_reg_save_param_xpath(
    "ParamName=error_code",
    "QueryString=/response/error_code",
    SEARCH_FILTERS,
    LAST);

    事务相关函数
    lr_start_transaction("testing");//开始事务
    timer=lr_start_timer();//开始计算时间
    //浪费时间的代码
    time_elapsed=lr_end_timer(timer);//结束计算时间
    lr_wasted_time(time_elapsed*1000);//从毫秒换算成秒后加入浪费时间中
    lr_end_transaction("testing", LR_AUTO);//结束事务,事务会自动减去浪费时间

    自定义事务状态函数:
    lr_set_transaction_status_by_name(LR_FAIL,"protectcar");

    补充函数总结:
    lr_get_attrib_string("在运行时设置中其他属性的参数名称")

    image.png
    image.png

    lr_continue_on_error(1);//出现错误继续执行
    //中间可以放要执行的代码
    lr_continue_on_error(0);//出现错误不继续执行,关闭开关,与运行时设置的遇到错误继续执行是一样的。

    web_get_int_property(HTTP_INFO_RETURN_CODE)获取上一个请求的返回码

    image.png

    web_add_header();
    登录成功后获取token,下面其他的接口都需要在header中添加token,所以在下面所有的接口前增加web_add_header增加token。

    image.png

    lr_convert_string_encoding("A", NULL, LR_ENC_UTF8, "stringInUnicode");
    参数分别是sourceString,fromEncoding,toEncoding ,paramName
    fromEncoding和toEncoding有三种:LR_ENC_SYSTEM_LOCALE 、LR_ENC_UTF8 、LR_ENC_UNICODE
    该函数返回0是转换成功,返回-1是转换失败。
    下图中是把参数转换字符类型,打印结果后面会带\x00

    image.png
    image.png

    相关文章

      网友评论

        本文标题:Loadrunner性能测试(三):关联函数、检查点、事务、思考

        本文链接:https://www.haomeiwen.com/subject/lyqgcctx.html