发布新日志

  • 【转载】loadrunner函数web_reg_find学习记录

    2013-04-08 14:49:06

    先说明一下,下面的这些内容是loadrunner函数手册中的内容,今天重点学习web_reg_find/

    web_find

     语法:
     int web_find (const char *StepName, <Attributes and Specifications list>, char *searchstring, LAST );

    参数:
     1、StepName:步骤名称,在Tree视图中出现。

    2、Attributes and Specifications list:

    支持的属性有:

    Frame:在多Frame的情况下,定义要查找Frame的范围。

    Expect:定义在什么情况下函数检查成功:找到了指定的搜索标准或者没有找到。例如说,可以检查指定的错误信息是否出现在web页面中。合法的值有2个:found和notfound。默认值是“found”。

    Matchcase:指定搜索是否区分大小写。

    Repeat:指定当第一次发现要查找的字符串时,搜索是否继续。当一个web页面中包含多个被查找的字符串时,此参数是非常有用的。合法的值有2个:yes,no。默认值是“yes”。

    Report:指定在什么情况下,VuGen在执行日志中显示此函数的检查结果。合法的值有:success,failure,always。默认值是“always”。

    Onfailure:此参数决定在函数检查失败后,Vuser是否中断。参数值是abort。如果指定了Onfailure=abort,当函数检查失败时,不论在运行时设置中的error-handling是什么,脚本都会中断。

    如果没有指定Onfailure=abort,那么运行时设置中error-handling将会起作用。

    支持的特性有:RightOf, LeftOf (不支持7.x及更高版本)。

    RightOf:要查找的字符串右边的内容。

    LeftOf:要查找的字符串左边的内容。

    3、Searchstring:需要查找的字符串,格式为“What=stringxyz”。此搜索不区分大小写。

    4、LAST:属性列表结束符。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)。

    说明
     此函数的作用是在HTML页面中查找指定的字符串。

    此函数只能在基于HTML录制的脚本中使用。当指定的HTML请求全部完成以后,开始执行搜索过程,比web_reg_find要慢。

    web_find 函数在C语言的脚本中已经被web_reg_find所替代,web_reg_find运行速度比较快,而且在HTML-based和URL-based 的录制方式中都可以使用。 在C语言脚本中,web_find是向后兼容的。Java和Visual Basic脚本中不再支持它。

    运行在HTTP模式下的WAP用户都和运行在WSP回放模式下的WAP用户都不支持此函数。

    web_global_verification

     语法:
     int web_global_verification (<List of Attributes>, LAST );

    参数:
     List of Attributes:

    1、Text:此属性是一个非空的,以NULL结尾的字符串,表示要查找的内容。语法是”Text=string”。还可以使用text flags自定义字符串。

    2、TextPfx:没有指定Text的情况下使用此属性。要查找的字符串的前缀。语法是” TextPfx =string”。还可以使用text flags自定义字符串。

    3、TextSfx:没有指定Text的情况下使用此属性。要查找的字符串的后缀。语法是” TextSfx =string”。还可以使用text flags自定义字符串。

    4、Search:可选项,在哪里查找字符串。可选的值是:Headers,Body,NORESOURCE或All。默认值是NORESOURCE。语法是“Search=value”。

    5、Fail:当字符串找不到时的处理选项:Found (默认值)或NotFound。Found表示当找到对应的字符串时发生了错误(例如“Error”)。NotFound表示当找不到字符串时发生了错误。语法是“Fail=value“。

    6、ID:在日志文件中标识当前函数。

    LAST:属性列表结束符。

    注:text flags:/IC表示忽略大小写;/BIN表示指定的是二进制数据。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)。

    说明
      web_global_verification属于注册函数,注册一个在web页面中搜索文本字符串的请求,与web_reg_find只在下一个 Action函数中执行搜索不同的是,它是在之后所有的Action类函数中执行搜索的。可以搜索页面的body,headers,html代码或者是整 个页面。

    在检测一些应用程序级别(不通过http状态码来表现)的错误时,web_global_verification是非常有用的。如果要定位通过HTTP状态码表现的错误时,使用web_get_int_property。

    查找范围:all:这个HTML页面;Headers:页面的头;body:页面的体,包含所有的资源但不包含头;NORESOURCE(默认选项):仅仅包含页面的体,把包括头和资源。

    如果不知道要查找的精确的文本,或者要查找的多个文本不是完全相同的,可以使用前缀和后缀来表示。这时需要用到TextPfx和TextSfx属性。这2个属性必须同时指定,一旦指定了其中一个,就不能指定Text属性了。

    注意:web_global_verification在WAP协议下不能运行。

    web_image_check

     语法:
     int web_image_check(const char *CheckName, <List of Attributes>, <"Alt=alt"|| "Src=src">, LAST );

    参数:
     1、CheckName:名称,在Tree视图中出现。

    2、List of Attributes:

    支持的属性有:Frame(在多Frame的情况下,定义要查找Frame的范围)。

    支持的选项有:expect, matchcase, repeat, report, onfailure。

    Tip:选项跟属性的区别,大部分选项都只允许设置预定义的值,其他的值都是无效的。

    3、Alt:检查图象的ALT标记。不允许空值。

    4、Src:检查图象的SRC标记。不允许空值。

    5、LAST:参数列表结束的指示符。

    返回值
     整型。

    说明
     web_image_check检查指定的图象是否在HTML页面中出现。

    Alt或者Src两者必须有一个在参数列表中出现。如果两项都通过,那么检查成功。

    此函数仅仅支持基于HTML的脚本。

     web_reg_add_cookie

     语法:
     int web_reg_add_cookie(const char * cookie, const char * searchstring, LAST );

    参数:
     1、Cookie:定义需要增加或修改的Cookie。

    Cookie的参数格式为:<name>=VALUE; (required);domain=DOMAIN_NAME;(required);expires=DATE;path=PATH;(default path is "/");secure。

    此参数中的cookie元素和HTTP响应头中的Set-Cookie是相同的。例如“Session=1234;domain=sanditon.com”,在这里,“Session”是cookie的名称。

    2、Searchstring:要查找的文本字符串。字符串不能为空,以null结尾。格式为“Text=string”。

    3、LAST:属性列表的结束符。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)。

    说明
     web_reg_add_cookie是注册类型的函数。它首先注册一个搜索文本字符串的请求。检查动作在后续的Action函数之后进行。如果字符串被找到,就添加到cookie中。

    需 要注意,尽管web_reg_add_cookie在功能上跟HTTP Set_Cookie头相似,它们还是有个明显的区别。 根据HTTP标准,domain属性在Set-Cookie头中是可选的。如果没有指定,默认的domain的值是产生cookie的服务器的host name。当使用web_reg_add_cookie函数时,服务器的hostname对于压力测试的机器来说是不可用的,所以domain属性是必选项。

    此函数在HTML-based 和URL-based的脚本中都可以使用。(参照录制选项的录制标签页)。此函数是在服务器内容到达客户端之前注册搜索请求的,所以当所请求的内容一到就会执行搜索操作,脚本会比较高性。

    web_reg_add_cookie是用户手动添加的,无法录制。

    web_reg_find

     语法:
     int web_reg_find (const char *attribute_list, LAST);

    参数:
     1、attribute_list:

    通过Name=Value对来传递参数。例如“Text=string”。Text,TextPfx,TextSfx三个必须有一个出现。其他的属性是可选的。

    a) Text:要搜索的字符串,字符串必须非空,以NULL结尾。可以使用text flags自定义搜索字符串。

    b) TextPfx:要搜索的字符串的直接前缀。

    c) TextSfx:要搜索的字符串的直接后缀。

    d) Search:搜索的范围。可选的值是:Headers 、Body(在请求体中搜索)、Noresource (仅仅在HTML请求体中搜索,不包括头和资源)、ALL (在请求体、头和资源中搜索),默认值是“BODY”。

    e) SaveCount:匹配的个数。

    f) Fail:设置函数检查在什么状态下失败。

    g) ID:日志文件中标识此函数的一个字符串。

    h) RelFrameId:相关联的FrameId。注意:此参数在GUI级别的脚本中不受支持。

    2、LAST:属性列表结束的标记符。

    返回值
     整型。 成功时返回LR_PASS(0),失败时返回LR_FAIL (1)。

    说明
     web_reg_find属于注册函数,注册一个在web页面中搜索文本字符串的请求,在接下来的Action(象web_url)类函数中执行搜索。

    通过查找期望的字符是否存在来验证是否返回了期望的页面。例如,通过查找“Welcome”来检查主页是否完全打开了。也可以查找“Error”检查浏览器是否发生错误。还可以使用此函数注册一个请求来统计特定字符串出现的次数。

    如果检查失败,在接下来的Action类的函数中会报告错误。此函数仅仅注册请求,并不执行。函数的返回值只表明注册是否成功,并不表示检查的结果。

    此函数不仅能够查找text,还能查找到围绕着text的strings。不要同时指定text和前缀后缀。

    Fail,处理选项,可以是“Found或“NotFound”。默认是“NotFound”。

    “Fail=Found” 指示当对应的字符找到时,函数检查失败。例如,查找单词“Error”,如果找到了,说名web请求没有成功,你想把函数检查设置为失败。

    “Fail=NotFound”指示当对应的字符找不到时,函数检查失败。如果查找的是web请求成功时出现的字符串时,需要使用NotFound。

    SaveCount参数指示保存到参数中的匹配的字符串的个数。使用这个属性,需要指定“SaveCount=param”。检查操作被执行后,param 的值是null结尾的数字类型的值。

    如果指定了SaveCount,且没有使用Fail参数,检查不会失败,无论需要查找的字符串是否找到。通过检查SaveCount的值确定字符串是否被找到。 如果param是0,说明没有找到对应的字符串。

    如果同时指定了SaveCount和Fail,指定的错误处理选项和SaveCount协同工作。 handling option specified works together with the SaveCount. Thus,如果指定了SaveCount且指定了“Fail=NotFound” ,但是字符串被找到,SaveCount被赋值为字符串出现的次数,检查成功。如果字符串找不到,SaveCount被赋值为0,检查失败(注意,参数的 0值只在运行时设置中Continue on error 选中时才有意义)。

    此函数在HTML-based和URL-based的脚本中都可以使用。此函数是在所请求内容到达之前注册搜索请求的,所以当所请求内容一到达后就会执行搜索,产生的脚本比较高效。

    web_reg_find和 web_find的不同之处是web_reg_find是先注册,后查找;而web_find是查找前面的请求结果。

    web_find和web_reg_find函数两者是有一些差别的:

      (1)web_reg_find先注册的优势是脚本能够一边接收Server的数据缓冲,一边进行查找,提高了查找的效率。

      (2)web_reg_find的参数与web_find并不完全一样,其中有个参数叫做 SaveCount,它能够记录查找匹配的次数。而web_find的机制是一旦查找匹配成功,就立即返回,并不继续查找和记录匹配次数。

      (3)VU run time设置中的 “enable image and text check”对 web_find有效,而对web_reg_find无效。

    自己写的代码:

    #include "web_api.h"

    Action()
    {
    web_reg_find("Search=Body","Text=空间","SaveCount=abc_count",LAST);

    web_url("19楼",
        "URL=http://www.19lou.com/",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=",
        "Snapshot=t1.inf",
        "Mode=HTML",
        EXTRARES,
        LAST);
    if(atoi(lr_eval_string("{abc_count}"))>0)                   //判断是否查找成功
    {
       lr_output_message("Log on successful.");                  //atoi是C语言的函数,将字符型变量转成整数型  
    }
    else{
       lr_error_message("Log on failed");                        //lr_eval_message取得参数值
       return(0);
       }
    lr_output_message(lr_eval_string("{abc_count}"));    //输出统计的次数

    return 0;
    }

    运行结果:

    Action.c(7): Registered web_reg_find successful for "Text=空间" (count=21) [MsgId: MMSG-26364]
    Action.c(7): web_url("19楼") was successful, 764227 body bytes, 23422 header bytes [MsgId: MMSG-26386]
    Action.c(18): Log on successful.
    Action.c(24): 21

     

    来源:http://hi.baidu.com/dcwang/blog/item/6f45aa188df4bd0e34fa412d.html

  • 转帖:Loadrunner中对中文进行UTF-8转码的探索

    2011-10-18 15:00:36

    本文来自于fox的日志:http://testingtop.com/space.php?uid=7&do=blog&id=225

    这是一个HTTP接口测试中经常会碰到的问题,目前的服务器采用的都是UTF-8编码方式,而我们的客户机Windows系统一般默认采用的编码方式是GBK,这正是我们采用录制方式的时候会发现许多中文乱码的原因。

    Loadrunner录制的时候可以通过在Virtual User Gen的Tools->Recoding Options -> Advanced -> Support charset -> UTF-8的设置规避(其实也只是部分规避),下面我们讨论在手写测试脚本时如何解决UTF-8转码的问题。

    实践一:在脚本中直接采用中文明文进行请求

      web_custom_request("web_custom_request",
      "URL=http://172.16.4.191/list?id=环球影院",
      "Method=GET",
      "TargetFrame=",
      "Resource=0",
      "Referer=",
      "Body=",
      LAST);
    结果:服务端返回404错误,找不到相应的资源id,明显服务端不能正确响应非UTF8编码方式的请求。

    实践二:

    为解决这个问题,最关键的是要把本地GBK编码的汉字转换成UTF-8编码格式的信息,为此我们引进loadrunner自带的编码函数lr_convert_string_encoding

    lr_convert_string_encoding

    Converts a string to a different encoding.

    C Language

    intlr_convert_string_encoding( const char *sourceString, const char *fromEncoding, const char *toEncoding, const char *paramName);

    Example       See Also

    sourceString
    The string to convert
    fromEncoding
    The encoding of the sourceString
    toEncoding
    The encoding to convert of the string saved in parameterparamName
    paramName
    The name of the parameter in which the destination string will be saved

    lr_convert_string_encodingconverts a string encoding between the following encodings: System locale, Unicode, and UTF-8.The function saves the result string, including its terminating NULL, in the parameterparamName.

    lr_convert_string_encodingis added manually to a script. when needed. It is not recorded.

    Possible values for 'fromEncoding' and 'toEncoding' :

    Constant
    Value
    LR_ENC_SYSTEM_LOCALE
    NULL
    LR_ENC_UTF8
    "utf-8"
    LR_ENC_UNICODE
    "ucs-2"
     
     
    根据函数说明,我们编写测试脚本如下
     lr_convert_string_encoding( "环球影院",
      LR_ENC_SYSTEM_LOCALE,
      LR_ENC_UTF8,
      "str" );
     web_custom_request("web_custom_request",
      "URL=http://172.16.4.191/list?id={str}",
      "Method=GET",
      "TargetFrame=",
      "Resource=0",
      "Referer=",
      "EncType=text/xml;charset=UTF-8",
      "Body=",
      LAST);
     
    使用lr_convert_string_encoding函数,将中文转换成UTF-8编码以后,作为参数传递给请求,并发送。
    测试结果:仍然返回404错误,查看loadrunner日志信息“环球影院”已经正确转换成UTF8编码方式,那为什么还是请求失败呢?
    再次查看日志如下
    Action.c(7): t=825ms: 223-byte request headers for "http://172.16.4.191/list?id=鐜悆褰遍櫌" (RelFrameId=1)
    Action.c(7):     GET /list?id=鐜悆褰遍櫌\x00 HTTP/1.1\r\n
    Action.c(7):     Content-Type: text/xml;charset=UTF-8\r\n
    Action.c(7):     User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows)\r\n
    Action.c(7):     Accept-Encoding: gzip, deflate\r\n
    Action.c(7):     Accept: */*\r\n
    Action.c(7):     Connection: Keep-Alive\r\n
    Action.c(7):     Host: 172.16.4.191\r\n
    Action.c(7):     \r\n
    发现在请求地址“/list?id=鐜悆褰遍櫌”后面还带了一个\x00,这正是lr_convert_string_encoding函数说明中标红的说明:The function saves the result string, including its terminating NULL, in the parameterparamName.
    也就是说,我转换成UTF-8之后,如果直接作为变量传到代码之中的话,在最后的字符串之中,会多出来一个“NULL”,C语言中NULL是一个字符串的结束,而正是这个null字节的存在导致了服务端识别id出错。
     
    实践三:
     char tmp[50];
     lr_convert_string_encoding( "环球影院",
      LR_ENC_SYSTEM_LOCALE,
      LR_ENC_UTF8,
      "str" );  
     strcpy(tmp,lr_eval_string("{str}"));
    lr_log_message("str is %s",tmp);
     lr_save_string(tmp,"sorvalue");
     web_custom_request("web_custom_request",
      "URL=http://172.16.4.191/list?id={sorvalue}",
      "Method=GET",
      "TargetFrame=",
      "Resource=0",
      "Referer=",
      "Body=",
      LAST);
    通过lr_eval_string函数取参数值时会自动去掉\x00,测试结果正常,正确返回HTTP响应内容。
  • 转帖:Loadrunner中web_reg_save_param函数使用详解

    2010-10-22 16:05:46

    Loadrunner中web_reg_save_param函数使用详解

    * 应用范围

    在使用Loadrunner进行性能测试时,经常遇到一种情况,需要通过web页面修改某事务的状态。于是需要首先读出当前的事务的状态,再进行修改,此时便可以使用到web_reg_save_param了。可以通过它先将事务的状态读出写入一个自定义的变量中,根据变量的值来决定下一步的动作。

    * 简要说明

    语法:

    int web_reg_save_param(const char *ParamName, <list of Attributes>, LAST);

    参数说明:

    * ParamName: 存放得到的动态内容的参数名称
    * list of Attributes: 其它属性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。属性值不分大小写
    o Notfound: 当在返回信息中找不到要找的内容时应该怎么处理
    o Notfound=error: 当在返回信息中找不到要找的内容时,发出一个错误讯息。这是缺省值。
    o Notfound=warning: 当在返回信息中找不到要找的内容时,只发出警告,脚本也会继续执行下去不会中断。
    o LB( Left Boundary ) : 返回信息的左边界字串。该属性必须有,并且区分大小写。
    o RB( Right Boundary ): 返回信息的右边界字串。该属性必须有,并且区分大小写。
    o RelFrameID: 相对于URL而言,欲查找的网页的Frame。此属性质可以是All或是数字,该属性可有可无。
    o Search : 返回信息的查找范围。可以是Headers,Body,Noresource,All(缺省)。该属性质可有可无。
    o ORD : 说明第几次出现的左边界子串的匹配项才是需要的内容。该属性可有可无,缺省值是1。如为All,则将所有找到的内容储存起来。
    o SaveOffset : 当找到匹配项后,从第几个字元开始存储到参数中。该属性不能为负数,缺省值为0。
    o SaveLen :当找到匹配项后,偏移量之后的几个字元存储到参数中。缺省值是-1,表示一直到结尾的整个字串都存入参数。
    o Convert : 可取的值有以下两种:

    HTML_TO_URL : 将 HTML-encoded 资料转成 URL-encoded 资料格式

    HTML_TO_TEXT : 将 HTML-encoded 资料转成纯文字资料格式

    * 实例讲解

    目的:取得页面中的商品状态,如果状态是正常态就改为注销态,否则改为正常态。

    录制脚本使用的是URL based script

    将返回的数据记录到日志

    * 直接手工访问页面,检查URL

    该页面上点击右键,选择属性

    看到URL,对照录制下的脚本中有:
    web_url("modifyOfferingStatePage.do",
    "URL={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
    282172&offeringSpecId=1&offeringSpecName=普通宽带(ADSL/LAN)&customerName=
    {clientname}&nodeId=260000&pos1=定购管理&pos2=修改商品状态",

    "Resource=0",
    "RecContentType=text/html",
    "Referer={url}/web/businessAccept/order/orderMenu.do",
    "Snapshot=t23.inf",
    "Mode=HTTP",
    LAST);
    于是在这段代码前添加注册函数:
    web_reg_save_param("oldstate",
    "LB/IC=原有商品状态:</td>",
    "RB/IC=</td>",
    "Search=body",
    "Ord=1",
    "RelFrameId=1",
    "SaveOffset=57",
    "SaveLen=4",
    LAST);
    web_url("modifyOfferingStatePage.do",
    "URL={url}/web/businessAccept/order/modifyOfferingStatePage.do?offeringId=
    282172&offeringSpecId=1&offeringSpecName=
    普通宽带(ADSL/LAN)&customerName={clientname}&nodeId=
    260000&pos1=定购管理&pos2=修改商品状态",

    "Resource=0",
    "RecContentType=text/html",
    "Referer={url}/web/businessAccept/order/orderMenu.do",
    "Snapshot=t23.inf",
    "Mode=HTTP",
    LAST);

     函数的一些使用技巧:
            1、web_reg_save_param必须在获取返回值的操作前面注册,在获取返回值的操作后面使用
            2、保存参数最大不能超过256字节,如果超过256字节请使用int web_set_max_html_param_len (const char *length )函数扩大参数保存范围
            例如:web_set_max_html_param_len ("1024"); //扩大参数最大保存范围为1024字节
            3、LB和RB后面跟着"/ic",则边界大小写都匹配(不加,也就是默认是大小写敏感的)
            例如:web_reg_save_param("IsRight","LB/ic=cache-control: private\r\n\r\n","RB/ic=|",LAST);

  • 转帖:LoadRunner里如何实现连接几个很长的字符串呢?

    2010-10-22 16:03:35

    char str[1024];
    char *str1="slJnVtsMOdItZ5dTdNJrturuyhrthKjnyUQb7ni85p76ntizLkQk";
    char *str2=":<?xml version="1.0" encoding="utf-8"?><antiphishing><appinfo><appname>dgdg</appname></appinfo><phishs><phish><url><![CDATA[http://www.baidu.com/abc.html]]></url><action>gjgj</action><sync>ghjg</sync><extraattr keyname="ghj" value="uytyu"/><extraattr keyname="app_name" value="vesfee"/></phish></phishs></antiphishing>
    ";
    char *str3="slJnVtsMOdItZ5dTdNJrturuyhrthKjnyUQb7ni85p76ntizLkQk";

    strcpy(Str,Str1) ;
    strcat(Str,Str2);
    strcat(Str,Str3);


    lr_output_message("%s",str1);

  • 转帖:url 模式录制脚本web_concurrent_start和web_concurrent_end是起到什么作用呀

    2010-10-22 16:00:16

    Zee:

    很多地方都没有把这个东西解释清楚。其实比较容易理解的。就是并发组这个概念把人说晕了。

    简单的说:
    这两个函数是在URL中标记一个页面请求的,注意:这里我说的是页面(page),并不是请求。
    在LR请求一个页面里,由于使用URL的方式录制,会把一个页面中的元素分成几个web函数做处理。所以,LR中实现了web_concurrent_start和web_concurrent_end。实现的作用是:
    从web_concurrent_start开始标记,当脚本运行到web_concurrent_start时,后续的脚本都不会立即被执行,直到web_concurrent_end出现。才把这中间的所有的脚本一起执行。
    所谓并发组也是指把这一组函数一起执行起来。

    如果你用 lr_start_transaction和 lr_end_transaction来替换,脚本完全可以跑通。中间的脚本是从上到下执行的,而不是一起执行的。
    其他的没有作用。

  • 转帖:loadrunner录制下载文件

    2010-10-22 15:57:06

    本文关键字

    loadrunner录制下载文件,文件如何保存,如何获得服务器返回的文件名,保存文件时如何随机生成文件名

            在录制脚本的过程中,我们把下载文件的请求单独放到一个action中,我们先简单的分析一下录制下载文件的脚本,在脚本中只能看到这样一个下载的请求:
    web_url("download.php",
              "URL=http://211.147.208.141/cn/resources/download.php?id=386",
              "Resource=1",
              "RecContentType=application/force-download",
              "Referer=",
              LAST);

    对于如何保存到本地,loadrunner是无法记录的,执行脚本时客户端发出这个请求,服务器端响应后,loadrunner接收到了服务器响应的文件内容(我们可以在日志中看到文件的内容,不过是乱码),既然loadrunner可以接收到文件内容,那么我们完全可以使用关联函数来获得该内容,在通过C语言的文件函数把获得的内容写在本地。

            那现在遇到这样一个问题,使用关联函数如何定义获得服务器响应内容的左右边界呢?因为我们把这个请求写在了一个单独的action中,所以在这里我们只要把服务器响应的所有内容均获取下来写到本地,也就完成了下载文件的保存。

            下面看代码: 
    Action()
            {
                int flen;        //定义一个整型变量保存获得文件的大小
                long filedes;    //保存文件句柄
                char file[256]="\0";  //保存文件路径及文件名


                web_set_max_html_param_len("2000000");//设置页面接收最大的字节数,该设置应大于下载文件的大小

             web_concurrent_start(NULL);

     

    //使用关联函数获取下载文件的内容,在这里不定义左右边界,获得服务器响应的所有内容          

    web_reg_save_param("filecontent",
              "LB=",
              "RB=",
              "Search=BODY",
              LAST);

    web_reg_save_param("file",
              "LB=filename=\"",
              "RB=\"",
              "Search=all",
              LAST);

         //使用关联函数在服务器响应的头文件中获取下载文件名

              web_url("download.php",
              "URL=http://211.147.208.141/cn/resources/download.php?id=386",
              "Resource=1",
              "RecContentType=application/force-download",
              "Referer=",
              LAST);

            //发出下载请求

              web_concurrent_end(NULL);


             strcat(file,"c:\\");    //将“c:\\”这个路径保存到file中
             strcat(file,lr_eval_string("{file}"));//将获得的文件名拼接在file这个变量字符串之后


            flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE); //获得文件大小

                if(flen > 0)
                {
                 if((filedes = fopen(file, "wb")) == NULL)
                 {
                  lr_output_message("Open File Failed!", lr_eval_string("{filecontent}"));
                  return -1;
                 }
                 fwrite( lr_eval_string("{filecontent}"),flen,1,filedes );
                 fclose( filedes );
            }

             return 0;
            }


            好了,运行这段脚本完成文件下载并写到本地的操作

            如果我们需要重复保存这个文件到本地,如何解决重名问题呢,下面这段代码可以随机生成文件名

                 char file[256]="\0";
                char * chNumber

                chNumber=lr_eval_string("{Random}");  //生成随机数

                strcat(file,"c:\\test");
                strcat(file,chNumber);
                strcat(file,".rar");

            此时file中保存着一个随机生成的文件名,然后使用文件函数以该文件名保存文件

  • 转帖:Loadrunner中参数和变量的使用

    2010-10-22 15:26:06

    //字符串复制
    strcpy(str,"Hello ") ;

    //字符串连接
    strcat(str,"World !");
    lr_message("str: %s",str);

    //变量转为参数,将变量str的值存到参数Param中
    lr_save_string(str,"Param");

    //参数复制
    lr_save_string(lr_eval_string("{Param}"),"Param_1");

    //参数转为变量
    strcpy(str1,lr_eval_string("{Param_1}"));
    lr_message("str1: %s",str1);

    //参数名称格式化输出到变量中
    sprintf(str2,"{Param_%d}",1);
    lr_message("str2: %s",lr_eval_string(str2));

    在web系统中 参数一般通过web_reg_save_param获取

    语法:

    int web_reg_save_param(const char *ParamName, <list of Attributes>, LAST);

    参数说明:

    • ParamName: 存放得到的动态内容的参数名称
    • list of Attributes: 其它属性,包括:Notfound, LB, RB, RelFrameID, Search, ORD, SaveOffset, Convert, SaveLen。属性值不分大小写
      • Notfound: 当在返回信息中找不到要找的内容时应该怎么处理
      • Notfound=error: 当在返回信息中找不到要找的内容时,发出一个错误讯息。这是缺省值。
      • Notfound=warning: 当在返回信息中找不到要找的内容时,只发出警告,脚本也会继续执行下去不会中断。
      • LB( Left Boundary ) : 返回信息的左边界字串。该属性必须有,并且区分大小写。
      • RB( Right Boundary ): 返回信息的右边界字串。该属性必须有,并且区分大小写。
      • RelFrameID: 相对于URL而言,欲查找的网页的Frame。此属性质可以是All或是数字,该属性可有可无。
      • Search : 返回信息的查找范围。可以是Headers,Body,Noresource,All(缺省)。该属性质可有可无。
      • ORD : 说明第几次出现的左边界子串的匹配项才是需要的内容。该属性可有可无,缺省值是1。如为All,则将所有找到的内容储存起来。
      • SaveOffset : 当找到匹配项后,从第几个字元开始存储到参数中。该属性不能为负数,缺省值为0。
      • SaveLen :当找到匹配项后,偏移量之后的几个字元存储到参数中。缺省值是-1,表示一直到结尾的整个字串都存入参数。
      • Convert : 可取的值有以下两种:

    HTML_TO_URL : 将 HTML-encoded 资料转成 URL-encoded 资料格式

    HTML_TO_TEXT : 将 HTML-encoded 资料转成纯文字资料格式

    注:可以将ORD设置成ALL看看效果,然后充分挖掘

    付:

    字符串处理主要是对字符串操作和比较。

    函数名 介绍
    strcat 连接两个字符串
    strchr 返回字符串第一次出现后的所有字符
    strcmp 区分大小写字母比较 
    strcpy 复制一个字符串到另一个 
    strdup 复制字符串
    stricmp 不区分大小写字母比较
    strlen 返回字符串长度
    strlwr 转化字符串为小写字母
    strncat 一个字符串连接另一个字符串到第n个的字符 
    strncmp 比较两个字符串从第一到n个字符
    strncpy 复制一个字符串从第一到n个字符到另一个字符串 
    strnicmp 比较两个字符串的n个字符 
    strrchr 返回字符最后出现后的所有字符
    strset 为字符串填充特殊字符
    strspn 返回字符串中包含特殊字符的个数 
    strstr 返回一个字符串在另一个中第一出现的位置数 
    strtok 返回特殊标记分割的字符 
    strupr 转化字符串为大小字母

  • 根据web_reg_find 页面内容查找结果,进行不同的操作

    2010-10-21 18:01:54

    以下代码含义:

    在网页中查找一个字符串,若未找到,让页面自动循环执行刷新(即点击网页上的Refresh按钮),直到页面出现该字符串(后台操作完成后,此字符串才能显示)后,再接着执行其它操作。

    aa: 
     //在下一个操作(即刷新)的返回页面中查找字符串“完成下载”
     web_reg_find("Text=完成下载",
         "SaveCount=i_Count",
         LAST);

     web_link("Refresh",
      "Text=Refresh",
      "Snapshot=t23.inf",
      LAST);

     //判断如“完成下载”字符串出现次数等于0,则再次刷新,直到此字符串出现
     if(strcmp(lr_eval_string("{i_Count}"),"0")==0)
     {
      lr_error_message("未完成");
      goto aa;
     }

     else
     {
      lr_error_message("已完成批下载");
     }

    //以下内容为字符串显示后的其它操作

    ......

    ......

  • 用LoadRunner测试MMS流媒体

    2010-07-01 18:16:28

    步骤

    内容

    具体操作

    1

    协议选择

    协议包用Global或Web都可以,选用Media PlayerMMS)协议。(MMS协议无法录制,只能通过手工编写)

    2

    脚本编写

    mms_play( "test1.wmv",

                    "URL=mms://202.106.xxx.xxx/1/test1.wmv",

                    "duration=-1",

                    "starttime=0",

                    LAST );

    //lr_think_time(2000);

    //mms_close();

    return 0;

    3

    wmload.asf文件添加

    拷贝至发布点根目录。比如:所发布文件的文件位于d:\media\1\d:\media\2\两个文件夹下,则发布点的根目录为d:\media

    (网上资料说应拷贝到服务器C:\wmpub\wmrootC为系统盘。不过根据本次测试经验,应该不用这样做。)

    4

    并发访问

    LR的控制器里面设置并发,运行后,到服务器的流媒体服务界面(如下图),看当前已连接的客户数和当前分配带宽是否有变化。若没有变化,可尝试重新启动流媒体服务,再次运行并观察。

    测试中发现:

    1. 访问流媒体服务器时,无论是用LR的控制器并发访问,还是用IE产生单个的访问需求,只要当前程序(控制器/IE)不关闭,即使已经终止播放,上图中的“已连接的单播客户端数”也不会减少。只有当关闭当前程序(控制器/IE)时,“已连接的单播客户端数”才会响应减少或归零。但是,若当前程序(控制器/IE)中的流媒体文件已经不再播放,会从上图中的“当前分配的带宽”项的减少或归零看出来。

     

    2. 用200个vu并发访问,发现第一次运行时,服务器端“已连接的单播客户端数”最大达到198;而第二次运行以及以后几次运行时,已连接的单播客户端数”越来越少,只有50%左右。而且,如果此时用IE直接访问mms://202.106.xxx.xxx/1/test1.wmv,服务器端“已连接的单播客户端数”根本不变化(理论上应该增加1)。怀疑由于运行次数多,视频文件已经完全在PC机内存/硬盘中,于是每次访问不再访问网络,直接从本机内存/硬盘中读取,所以服务器端的参数不变化。针对这种情况,只需清一下IE的内存即可。

     

  • 安装HP LoadRunner 9.1碰到的问题

    2010-07-01 10:13:10


    在一个新的XP系统中装HP LoadRunner 9.10,点击安装后提示“Setup has determined that a previous installation has not completed.
    You should restart the system in order to complete this process.”

    重启电脑后问题还存在,用网上下的deletelicense.exe和优化大师清处注册表信息也不行。 后来从网上找到一种可以解决的方法,那就是:

    1. 打开临时文件夹,开始—>运行—>输入%temp%
    2. 找到“Prereq_Mgr.HP_LoadRunner_9.10.log”文件,这个文件记录着不能安装的原因。

    我的这个日志文件记录如下:
    [04/23/09 12:58:31] INFO: (IsRebootRequired) The registry value [PendingFileRenameOperations] exists under [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager] and cannot be ignored

    3、删除注册表项(如果要操作注册表,最好要把注册表备份好,防止误操作)
    把注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager下的项PendingFileRenameOperations删除。

    再安装HP LoadRunner 9.10就可以正常安装了!

  • LR运行百分比设置

    2009-01-09 14:43:11

    使用loadrunner时,在“运行时设置—>运行逻辑”中设置多个操作的运行百分比时,我把两个操作分别
    设为40%和60%,迭代10次,运行后发现这两个操作各运行了5次;
    设为20%和80%时,两个操作分别运行了3次和7次;
    设为50%和50%时,两个操作分别运行了4次和6次
    设为30%和70%时,两个操作分别运行了1次和9次

    这是怎么回事呢?为什么运行结果和设置不同呢?

    咨询了刘专家,得到这样的回答:
    对于运行百分比设置,只是一个随机概率的设置,所以迭代次数少的时候可能会有偏差,而且相同配置两次执行时也会不同。一般真正测试的时候都不会执行这么少的迭代的,建议迭代100次看看是否合配置相符。

  • web_find 与 web_reg_find

    2008-12-25 19:57:14

    使用lr中sample的订票网站,登录后,页面出现“Welcome, ww, to the Mercury Tours reservation pages.”


    录制时,我在页面上选中这行字,并设置了检查点,lr自动生成的脚本语句是
    web_find("Text Check", "What=Welcome, ww, to the Mercury Tours reservation pages.", "LAST");

    我在别的页面也设置了检查点,但lr自动生成的脚本语句是 web_reg_find(......)

    我很奇怪,都是检查点,为什么生成的脚本不一样?于是就把web_find语句改成了
    web_reg_find("Text=Welcome, ww, to the Mercury Tours reservation pages.",LAST);
    考虑到这是reg注册函数,还把它放在了相应页面之前,但是重播时,不出意外地失败了

    试来试去,发现如果写成以下的样子就是成功的:
    web_reg_find("Text=Welcome",LAST);

    web_reg_find("Text=ww",LAST);

    我想啊想,突然发现,其实这行字的字体不完全一样,其中ww是黑体,于是改成以下语句,就重播成功啦
    web_reg_find("Text=Welcome, <b>ww</b>, to the Mercury Tours reservation pages.",LAST);

    太开心啦!web_find函数查找目标时竟然可以忽略字体的不同
    同时赞叹lr的“聪明”,当它发现选中文字的字体不同时,就用web_find函数代替web_reg_find,真不错啊!

  • 软件测试模型总结

    2008-12-16 10:15:40

    从各种资料上找到以下几种测试模型,拷贝粘贴,内容并非本人原创,只是为了方便学习和记忆。总结如下:

    1. V模型

        在软件测试方面,V模型是最广为人知的模型,尽管很多富有实际经验的测试人员还是不太熟悉V模型,或者其它的模型。V模型已存在了很长时间,和瀑布开发模型有着一些共同的特性,由此也和瀑布模型一样地受到了批评和质疑。V模型中的过程从左到右,描述了基本的开发过程和测试行为。V模型的价值在于它非常明确地标明了测试过程中存在的不同级别,并且清楚地描述了这些测试阶段和开发过程期间各阶段的对应关系。

       

    2. W模型

        V模型的局限性在于没有明确地说明早期的测试,无法体现“尽早地和不断地进行软件测试”的原则。在V模型中增加软件各开发阶段应同步进行的测试,演化为W模型(如下图)。在模型中不难看出,开发是“V”,测试是与此并行的“V”。基于“尽早地和不断地进行软件测试”的原则,在软件的需求和设计阶段的测试活动应遵循IEEE1012-1998《软件验证与确认(V&V)》的原则。 
        W模型由Evolutif公司提出,相对于V模型,W模型更科学。W模型是V模型的发展,强调的是测试伴随着整个软件开发周期,而且测试的对象不仅仅是程序,需求、功能和设计同样要测试。测试与开发是同步进行的,从而有利于尽早地发现问题。

       

        W模型也有局限性。W模型和V模型都把软件的开发视为需求、设计、编码等一系列串行的活动,无法支持迭代、自发性以及变更调整。

    3. X模型

        X模型也是对V模型的改进,X模型提出针对单独的程序片段进行相互分离的编码和测试,此后通过频繁的交接,通过集成最终合成为可执行的程序。

        X模型的左边描述的是针对单独程序片段所进行的相互分离的编码和测试,此后将进行频繁的交接,通过集成最终成为可执行的程序,然后再对这些可执行程序进行测试。己通过集成测试的成品可以进行封装并提交给用户,也可以作为更大规模和范围内集成的一部分。多根并行的曲线表示变更可以在各个部分发生。由图中可见,X模型还定位了探索性测试,这是不进行事先计划的特殊类型的测试,这一方式往往能帮助有经验的测试人员在测试计划之外发现更多的软件错误。但这样可能对测试造成人力、物力和财力的浪费,对测试员的熟练程度要求比较高。

    4. H模型

        H模型中, 软件测试过程活动完全独立,贯穿于整个产品的周期,与其他流程并发地进行,某个测试点准备就绪时,就可以从测试准备阶段进行到测试执行阶段。软件测试可以尽早的进行,并且可以根据被测物的不同而分层次进行。

        这个示意图演示了在整个生产周期中某个层次上的一次测试“微循环”。图中标注的其它流程可以是任意的开发流程,例如设计流程或者编码流程。也就是说, 只要测试条件成熟了,测试准备活动完成了,测试执行活动就可以进行了。
        H模型揭示了一个原理:软件测试是一个独立的流程,贯穿产品整个生命周期,与其他流程并发地进行。H模型指出软件测试要尽早准备, 尽早执行。不同的测试活动可以是按照某个次序先后进行的,但也可能是反复的,只要某个测试达到准备就绪点,测试执行活动就可以开展。

    5. 前置模型

        前置测试模型则体现了开发与测试的结合,要求对每一个交付内容进行测试。前置测试模型是一个将测试和开发紧密结合的模型,此模型将开发和测试的生命周期整合在一起,随项目开发生命周期从开始到结束每个关键行为。

    前置测试模型体现了以下的要点:
    (一)开发和测试相结合
        前置测试模型将开发和测试的生命周期整合在一起,标识了项目生命周期从开始到结束之间的关键行为。并且表示了这些行为在项目周期中的价值所在。如果其中有些行为没有得到很好的执行,那么项目成功的可能性就会因此而有所降低。如果有业务需求,则系统开发过程将更有效率。在没有业务需求的情况下进行开发和测试是不可能的。而且,业务需求最好在设计和开发之前就被正确定义。


    (二)对每一个交付内容进行测试
        每一个交付的开发结果都必须通过一定的方式进行测试。源程序代码并不是唯一需要测试的内容。在图中的绿色框表示了其它一些要测试的对象,包括可行性报告、业务需求说明,以及系统设计文档等。这同V模型中开发和测试的对应关系是相一致的,并且在其基础上有所扩展,变得更为明确。

    前置测试模型包括2项测试计划技术:
        其中的第一项技术是开发基于需求的测试用例。这并不仅仅是为以后提交上来的程序的测试做好初始化准备,也是为了验证需求是否是可测试的。这些测试可以交由用户来进行验收测试,或者由开发部门做某些技术测试。很多测试团体都认为,需求的可测试性即使不是需求首要的属性,也应是其最基本的属性之一。因此,在必要的时候可以为每一个需求编写测试用例。不过,基于需求的测试最多也只是和需求本身一样重要。一项需求可能本身是错误的,但它仍是可测试的。而且,你无法为一些被忽略的需求来编写测试用例。
        第二项技术是定义验收标准。在接受交付的系统之前,用户需要用验收标准来进行验证。验收标准并不仅仅是定义需求,还应在前置测试之前进行定义,这将帮助揭示某些需求是否正确,以及某些需求是否被忽略了。
        同样的,系统设计在投入编码实现之前也必须经过测试,以确保其正确性和完整性。很多组织趋向于对设计进行测试,而不是对需求进行测试。Goldsmith 曾提供过15项以上的测试方法来对设计进行测试,这些组织也只使用了其中很小的一部分。在对设计进行的测试中有一项非常有用的技术,即制订计划以确定应如何针对提交的系统进行测试,这在处于设计阶段并即将进入编码阶段时十分有用。

    (三)在设计阶段进行计划和测试设计
        设计阶段是做测试计划和测试设计的最好时机。很多组织要么根本不做测试计划和测试设计,要么在即将开始执行测试之间才飞快地完成测试计划和设计。在这种情况下,测试只是验证了程序的正确性,而不是验证整个系统本该实现的东西。
        测试有2种主要的类型,这2种类型都需要测试计划。在V模型中,验收测试最早被定义好,并在最后执行,以验证所交付的系统是否真正符合用户业务的需求。与V模型不同的是,前置测试模型认识到验收测试中所包含的3种成份,其中的2种都与业务需求定义相联系:即定义基于需求的测试,以及定义验收标准。但是,第三种则需要等到系统设计完成,因为验收测试计划是由针对按设计实现的系统来进行的一些明确操作定义所组成,这些定义包括:如何判断验收标准已经达到,以及基于需求的测试已算成功完成。
        技术测试主要是针对开发代码的测试,例如V模型中所定义的动态的单元测试,集成测试和系统测试。另外,前置测试还提示我们应增加静态审查,以及独立的QA测试。QA测试通常跟随在系统测试之后,从技术部门的意见和用户的预期方面出发,进行最后的检查.同样的还有特别测试。我们取名特别测试,并把该名称作为很多测试的一个统称,这些测试包括负载测试、安全性测试、可用性测试等等,这些测试不是由业务逻辑和应用来驱动的。
        对技术测试最基本的要求是验证代码的编写和设计的要求是否相一致。一致的意思是系统确实提供了要求提供的,并且系统并没有提供不要求提供的。技术测试在设计阶段进行计划和设计,并在开发阶段由技术部门来执行。

    (四)测试和开发结合在一起
        前置测试将测试执行和开发结合在一起,并在开发阶段以编码-测试-编码-测试的方式来体现。也就是说,程序片段一旦编写完成,就会立即进行测试。普通情况下,先进行的测试是单元测试,因为开发人员认为通过测试来发现错误是最经济的方式。但也可参考X模型,即一个程序片段也需要相关的集成测试,甚至有时还需要一些特殊测试。对于一个特定的程序片段,其测试的顺序可以按照V模型的规定,但其中还会交织一些程序片段的开发,而不是按阶段完全地隔离。
        在技术测试计划中必须定义好这样的结合。测试的主体方法和结构应在设计阶段定义完成,并在开发阶段进行补充和升版。这尤其会对基于代码的测试产生影响,这种测试主要包括针对单元的测试和集成测试。不管在哪种情况下,如果在执行测试之前做一点计划和设计,都会提高测试效率,改善测试结果,而且对测试重用也更加有利。

    (五)让验收测试和技术测试保持相互独立
        验收测试应该独立于技术测试,这样可以提供双重的保险,以保证设计及程序编码能够符合最终用户的需求。验收测试既可以在实施阶段的第一步来执行,也可以在开发阶段的最后一步执行。
        前置测试模型提倡验收测试和技术测试沿循2条不同的路线来进行,每条路线分别地验证系统是否能够如预期的设想进行正常工作。这样,当单独设计好的验收测试完成了系统的验证, 我们即可确信这是一个正确的系统。

    (六)反复交替的开发和测试
        在项目中从很多方面可以看到变更的发生,例如需要重新访问前一阶段的内容,或者地跟踪并纠正以前提交的内容,修复错误,排除多余的成分,以及增加新发现的功能,等等。开发和测试需要一起反复交替地执行。模型并没有明确指出参与的系统部分的大小。这一点和V模型中所提供的内容相似。不同的是,前置测试模型对反复和交替进行了非常明确的描述。

    (七)发现内在的价值
        前置测试能给需要使用测试技术的开发人员、测试人员、项目经理和用户等带来很多不同于传统方法的内在的价值。与以前的方法中很少划分优先级所不同的是,前置测试用较低的成本来及早发现错误,并且充分强调了测试对确保系统的高质量的重要意义。前置测试代表了整个对测试的新的不同的观念。在整个开发过程中,反复使用了各种测试技术以使开发人员、经理和用户节省其时间,简化其工作。
        通常情况下,开发人员会将测试工作视为阻碍其按期完成开发进度的额外的负担。然而,当我们提前定义好该如何对程序进行测试以后,我们会发现开发人员将节省至少20%的时间。虽然开发人员很少意识到他们的时间是如何分配的,也许他们只是感觉到有一大块时间从重新修改中节省下来可用来进行其它的开发。保守地说,在编码之前对设计进行测试可以节省总共将近一半的时间,这可以从以下方面体现出来:
      针对设计的测试编写是检验设计的一个非常好的方法,由此可以及时避免因为设计不正确而造成的重复开发及代码修改。通常情况下,这样的测试可以使设计中的逻辑缺陷凸显出来。另一方面,编写测试用例还能揭示设计中比较模糊的地方。总的来说,如果你不能勾画出如何对程序进行测试,那么程序员很可能也很难确定他们所开发的程序怎样才算是正确的。
        测试工作先于程序开发而进行,这样可以明显地看到程序应该如何工作,否则,如果要等到程序开发完成后才开始测试,那么测试只是查验开发人员的代码是如何运行的。而提前的测试可以帮助开发人员立刻得到正确的错误定位。
      在测试先于编码的情况下,开发人员可以在一完成编码时就立刻进行测试。而且,她会更有效率,在同一时间内能够执行更多的现成的测试,她的思路也不会因为去搜集测试数据而被打断。
        即使是最好的程序员,从他们各自的观念出发,也常常会对一些看似非常明确的设计说明产生不同的理解。如果他们能参考到测试的输入数据及输出结果要求,就可以帮助他们及时纠正理解上的误区,使其在一开始就编写出正确的代码。
      前置测试定义了如何在编码之前对程序进行测试设计,开发人员一旦体会到其中的价值,就会对其表现出特别的欣赏。前置方法不仅能节省时间,而且可以减少那些令他们十分厌恶的重复工作。

  • 破解LR-安装成功

    2008-11-18 14:07:28

    昨天小熊在这里开了空间,今天终于装好了LR,很开心,特此纪念一下。

    51testing上的好东西真多啊,小熊在这不但找到了破解版LR和中文包,还有详细的破解方法。经过两次努力,十分钟前终于搞定!打开Controller,不再有恼人的到期提醒,爽啊!

    就像刘姥熊进了大观园,网上的内容让俺眼花缭乱,看着高手熊们的长篇大论,小熊心里很着急,啥时候俺也能成为一名测试高熊啊?

    小熊暗下决心,一定要努力!世上无难事,只怕有心熊!fighting!

Open Toolbar