`
solem
  • 浏览: 34300 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

LR 关联高级篇

 
阅读更多
3.7.6  关联函数的高级使用
上面详细介绍了关联的作用和关联函数的详细选项,那么在工作中除了要使用关联函数获得服务器返回以外,还能做什么呢?

例如论坛一个版面中有20个帖子,如何实现随机单击其中某一个帖子的操作呢?回想一下关联选项Ord=All的时候关联出来的结果是不是一个参数数组?既然是参数数组,怎么从参数数组中取出一个随机的值呢?

在不同的LoadRunner版本中处理这个问题使用不同解决方法,现在来分别了解一下具体的方案(这里关联后的参数名为link,设置Ord为All)。

LoadRunner 9系列

在LoadRunner 9中做这个操作非常简洁,因为有了参数数组函数,所以只需要这样写就可以了:

char * siteval;

siteval =lr_paramarr_random(link)

即直接从参数数组link中取一个随机的值。

问题:如果需要随机选择前10个帖子怎么办?

Lr_paramarr_random()函数的随机范围其实是根据lr_paramarr_len()决定的。比如数组长度是20,随机值介于1~20之间,现在手动将这个参数数组设置得小一些,问题就解决了:

char * siteval;

lr_save_string("10","link_count");

siteval =lr_paramarr_random(link);

思考:如果需要随机获取关联结果中的第5至第10个对象,该如何处理呢?

在这种情况下,需要引入随机数,生成随机值为5~10的正整数,再调用lr_paramarr_idx()函数进行处理即可。

如果使用的是LoadRunner9以前的版本,没有这个参数数组函数怎么办?

LoadRunner 8以前的版本

假设存在关联后的参数数组为{link},数组记录总个数为20,需要取得其中的一个随机关联值可以这样写:

char linkname[100],num[100];

int randnum;

//关联和请求操作省略

randnum=rand()%atoi(lr_eval_string("{link_count}"))+1;//获得关联参数数目内的随机数字

strcpy(linkname,"{link_");

//lr_error_message("%s",linkname);

itoa(randnum,num,10);

strcat(linkname,num);

strcat(linkname,"}");

//lr_error_message"%s",linkname);

lr_save_string(lr_eval_string(linkname),"temp");

这段代码看起来是比较头疼的,因为涉及了很多新的函数。

atoi()类型强制转换函数的作用是将字符串型的内容转化为整数型。

atoi(字符串);

由于使用求余操作是对一个数字进行操作,所以需要使用atoi将参数转化为正整数。

使用Rand()%atoi(lr_eval_string("{link_count}")可以得到0~19的随机正整数。

strcpy()字符复制函数就是将一个字符串复制到一个变量中去。

strcpy(变量名,需要复制的字符串内容);

所以strcpy(linkname,"{link_"}的作用是将"{link_"这个内容保存到变量linkname中。

itoa()也是一个强制类型转换函数,和atoi()相反,它是将整数型内容转化为字符串型。

itoa(数字型,字符串,转化格式);

这里转化格式使用的是十进制。为了拼接参数数组,需要生成"{link_2}"这样的参数,通过前面的随机函数已经生成1~20的随机正整数,现在需要把这个数字拼接上去,这里使用strcat()来实现,由于strcat()必须使用字符串,所以需要将随机整数randnum转化成字符串型的num。

strcat()是一个字符添加函数,它将一个字符串附加在一个变量后。

strcat(变量名,字符串);

接着将上面生成的字符串继续拼接到linkname变量中。

这样就拼接出了linkname="{link_2}",在讲述参数化的时候提到过参数和变量的调用,当变量这样写的时候就可以直接读取到参数名的值。所以使用lr_eval_string()可以将这个变量对应的参数值取出,再通过lr_save_string()将值存放到另一个参数temp中去,最后参数temp就存放了{link_2}参数所对应的值了。

如果需要得到1~10的随机记录呢?这个时候只需要在随机数生成的时候做点手脚就行了。

rndnum=rand()%atoi(lr_eval_string("{link_count}"))+1;//获得关联参数数目内的随机数字

把这段代码修改为:

rndnum=rand()%10+1;//得到1~10的随机数字

在这里最好先做一个判断,避免出现帖子少于10个的问题。

如果需要得到5~10的随机记录呢?这个时候还是随机数生成的操作,如何生成一个范围内的随机数呢?通过公式rand()%(max-min+1)+min能生成从最小值到最大值之间的随机数,所以只需要写为以下形式即可:

Rndnum=rand()%(10-5+1)+5;

LoadRunner 8系列

到了LoadRunner 8.x系列,VuGen提供了一个新的函数来帮助我们快捷地处理类似的类型转化操作。这个函数就是sprintf(),sprintf()和C语言中的printf()函数十分相似,使用它可以生成带格式的字符串,从而帮助我们快捷地完成一个特殊格式拼接过程。

sprintf(变量名,格式,值)

例如可以这样写:

    char temp[100];

    sprintf(temp,"welcome %dtesting",51);

    lr_error_message(temp);

可以看到结果是"welcome 51testing",通过这个函数将数字51拼接到了这个字符串中。

还是前面的脚本,看看在LoadRunner 8.x中怎么写,现在可以将脚本改为以下形式:

char linkname[100];

int randnum;

randnum=rand()%atoi(lr_eval_string("{link_count}"))+1;//获得关联参数数目内的随机数字

    sprintf(linkname,"{link_%d}",rndnum);

lr_save_string(lr_eval_string(linkname),"temp");

这样直接就把随机的rndnum变量放在了linkname变量中,并且生成linkname= "{link_2}"这样的变量。后面的按照LoadRunner 7系列的做法就行了,是不是方便了      很多呢?

通过上面的方法就能处理常见的一些在关联后需要进行随机处理的情况。例如:现在需要这样的脚本,访问论坛首页,登录后检查所有在线用户,然后随机给所有的在线普通会员发一条广告短信息,那么这个脚本怎么去做呢?

分析一下业务:作为一个用户,首先要登录系统,然后查看到所有的在线用户,依次给在线的用户发送短信息。录制一个用户执行以上操作的脚本。如何获得在线的用户信息?在首页的最下面可以看到在线用户的信息,通过HTML代码可以发现普通用户和管理员的区别在于用户名前的图片名。

<li><img src="images\groupicons\member.gif" />

<a href="userinfo-8409.aspx" target="_blank" title="时间: 2009/3/19 9:52:16

操作: ">admin00011</a>

</li>

普通用户使用的图片是member.gif,而管理员使用的是admin.gif,所以可以通过这个信息来做一个关联操作,得到所有用户信息前是member.gif的用户id。

web_reg_save_param("member",

        "LB=member.gif\" /><a href=\"userinfo-",

        "RB=.aspx",

        "Ord=ALL",

        "Search=NoResource",

        LAST);

web_url("fristpage","URL=http://192.168.0.200",LAST);

按照代码填写关联的边界,运行后会发现关联失败,原因来自于member.gif" />和<a href=中其实还有一些符号,遇到这种无法直接写出左右边界的情况,应该先将边界设置得更大一点,修改关联函数。

web_reg_save_param("member",

        "LB=<img src=\"images\\groupicons\\member.gif\" />",

        "RB=.aspx",

        "Ord=ALL",

        "Search=NoResource",

        LAST);

web_url("fristpage","URL=http://192.168.0.200",LAST);

现在再运行一下这个脚本,可以得到对应的关联内容。

Action.c(10): Notify: Saving Parameter "member_1 = \r\n\t\t\t\t\t\t\t<a href="userinfo-8409"

通过这个关联结果,进一步尝试补全整个左边界。

web_reg_save_param("member",

    "LB=member.gif\" />\r\n\t\t\t\t\t\t\t<a href=\ "userinfo-",

    "RB=.aspx",

    "Ord=ALL",

    "Search=NoResource",

    LAST);

web_url("fristpage","URL=http://192.168.0.200",LAST);

通过这个代码,就可以将所有是在线的普通用户id通过关联函数保存到member这个参数数组中。

解决了上面的问题后,还有一个问题就是怎么发送短信息,录制的脚本中可以看到下面的内容。

web_submit_data("usercppostpm.aspx",

        "Action=http://192.168.0.200/usercppostpm.aspx?msgtoid=1",

        "Method=POST",

        "TargetFrame=",

        "RecContentType=text/html",

        "Referer=http://192.168.0.200/usercppostpm.aspx?msgtoid=1",

        "Snapshot=t14.inf",

        "Mode=HTML",

        ITEMDATA,

        "Name=msgto", "Value=admin", ENDITEM,

        "Name=subject", "Value=广告测试", ENDITEM,

        "Name=message", "Value=广告测试", ENDITEM,

        "Name=sendmsg", "Value=立即发送", ENDITEM,

        LAST);

这个请求是发送短信的请求,在这里可以看出,给用户发送短消息的关键是在Action属性中的msgtoid=1和ITEMDATA属性中的"Name=msgto","value=admin"这两个值上面,通过测试可以发现系统是以msgto的值作为最终发送人的确认方式来实现发送消息的,那么前面通过关联得到用户id怎么才能获得用户名呢?

1.用前面的strtok()进行关联拆分。

2.另一种做法是,得到了用户id后再通过用户id去获得用户名。

这里使用第2种做法,所以可以得到下面的最终代码。

Action()

{

int i;



web_reg_save_param("member",

    "LB=member.gif\" />\r\n\t\t\t\t\t\t\t<a href=\ "userinfo-",

    "RB=.aspx",

    "Ord=ALL",

    "Search=NoResource",

    LAST);



web_submit_data("login.aspx",

        "Action=http://192.168.0.200/login.aspx?loginsubmit=true",

        "Method=POST",

        "TargetFrame=",

        "RecContentType=text/html",

        "Referer=http://192.168.0.200/",

        "Snapshot=t11.inf",

        "Mode=HTML",

        ITEMDATA,

        "Name=referer", "Value=index.aspx", ENDITEM,

        "Name=username", "Value=admin", ENDITEM,

        "Name=password", "Value=51testing", ENDITEM,

        "Name=userlogin", "Value=&nbsp;登录&nbsp;", ENDITEM,

        EXTRARES,

LAST);



for(i=1;i<=atoi(lr_eval_string("{member_count}"));i++)

    {

lr_output_message("paramarr %d 's values %s",i,lr_ paramarr_idx("member", i));

    lr_save_string(lr_paramarr_idx("member",i),"userid");

      

    web_reg_save_param("username",

        "LB=<td class=\"navname\">",

        "RB=</td>",

        "Ord=1",

        "Search=NoResource",

        LAST);



    web_url("userinfo","URL=http://192.168.0.200/userinfo-{userid}.aspx",LAST);



    web_submit_data("usercppostpm.aspx",

            "Action=http://192.168.0.200/usercppostpm.aspx?msgtoid={userid}",

            "Method=POST",

            "TargetFrame=",

            "RecContentType=text/html",

            "Referer=http://192.168.0.200/usercppostpm.aspx?msgtoid=1038",

            "Snapshot=t14.inf",

            "Mode=HTML",

            ITEMDATA,

            "Name=msgto", "Value={username}", ENDITEM,

            "Name=subject", "Value=广告测试", ENDITEM,

            "Name=message", "Value=广告测试", ENDITEM,

            "Name=sendmsg", "Value=立即发送", ENDITEM,

            LAST);

    }

Return 0;

}


转自《性能测试进阶指南》---云层老师
  • w1.rar (3.4 MB)
  • 下载次数: 6
分享到:
评论

相关推荐

    HP_LoadRunner_12.02_Community_Edition_T7177-15059.rar

    用户可以通过录制用户操作生成性能测试脚本,然后通过参数化、关联等高级技术进行脚本优化,以模拟真实用户的复杂行为。同时,LoadRunner的强大分析工具可以帮助用户对测试结果进行深度解读,找出系统性能瓶颈,从而...

    loadrunner 培训ppt(入门和进阶)

    本培训资料将深入探讨LoadRunner的基础知识和高级技巧,帮助用户从入门到精通,充分理解并掌握这款强大的测试工具。 一、LoadRunner简介 LoadRunner的核心理念是“早发现,早解决”,它通过模拟大量并发用户执行...

    基于决策树、逻辑回归和改进神经网络的几种慢性病的危险因素分析研究(英文).pdf

    【慢性病危险因素分析】 ...未来的研究可能需要进一步探索更高级的机器学习模型,如深度学习,以提高风险预测的精确性和预测能力,同时结合临床专业知识,为慢性病的预防和控制提供更为精准的支持。

    性能测试从零开始LoadRunner入门与提升

    本篇将从零开始,深入探讨LoadRunner的入门与提升。 首先,理解性能测试的基本概念是必不可少的。性能测试旨在模拟真实用户对系统的操作,以检查系统在不同负载下的响应时间、吞吐量和资源利用率等关键指标。...

    loadrunner面试题 软件测试 精选

    使用LR的关联功能来处理,如Web_reg_save_param()函数,确保每次回放时参数值的正确性。 三、场景设计与执行 1. Controller的主要任务是什么? Controller负责创建和管理测试场景,设置虚拟用户数、运行时间、负载...

    loadrunner基础学习与深入体系统文档

    本篇文档将详细介绍LoadRunner的基础知识以及深入体验,帮助你从入门到精通。 一、LoadRunner组件介绍 1. VUGen(Virtual User Generator):这是创建脚本的工具,支持多种协议,如Web HTTP/HTML、FTP、Oracle、SQL...

    经典LoadRunner性能测试实战讲解

    - **LR_start_transaction() 和 LR_end_transaction()** - 用于定义事务的开始和结束,便于分析事务性能。 **3.6 本章小结** - 总结了脚本录制与开发的关键技术点,为接下来的场景设计奠定基础。 --- ##### 第4...

    基于vc的数字图像的读取

    本篇文章将深入探讨如何使用Visual C++(简称VC++)进行数字图像的读取操作,并结合具体代码实例来解析两种主要的图像格式——设备依赖位图(Device-Dependent Bitmap,简称DDB)和设备独立位图(Device-Independent...

Global site tag (gtag.js) - Google Analytics