【转载】LoadRunner字符集与检查点的探讨

  很多人在loadrunner测试脚本中加入中文检查点的时候会出现检查失败的情况,究竟是为什么呢?其实是被测试系统与loadrunner字符集之间的转换出现了问题。下面我们来一一解释。我们知道loadrunner在录制选项中有一个字符集的设置:Recording Options>>Advanced>>Support charset,在这里可以设置loadrunner支持的字符集。那么被测试系统的字符集与loadrunner字符集会有什么样的关系呢?下面我们以百度、Google为例子加以说明。  

  首先分别查看百度、Google网站的字符集是什么?打开相应的网站,通过右键查看源文件来获取它们的字符集。百度的字符集为?:gb2312,源文件代码中内容为:<!doctype html><html><head><meta http-equiv="Content-Type" content="text/html;charset=gb2312">;Google的字符集为:UTF-8,源文件代码中内容为:<!doctype html><html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8">。

1、在录制百度的测试脚本的时候不设置loadrunner字符集,脚本如下:

 Action()
{
web_reg_find("Search=body",
"SaveCount=times",
"Text=百度",
LAST); web_url("www.baidu.com",
"URL=http://www.baidu.com/",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
EXTRARES,
"Url=/img/i2.png", ENDITEM,
"Url=/img/arr.gif", ENDITEM,
"Url=/js/bdsug.js?v=1.0.3.0", ENDITEM,
"Url=/cache/hps/js/hps-1.0.js", ENDITEM,
LAST); if(atoi(lr_eval_string ("{times}"))>)
lr_output_message("search successful");
else
lr_error_message("search failed"); return ;
}

运行测试脚本,检查点可以通过。

2、设置loadrunner的字符集为:UTF-8,再次录制一个百度的测试脚本,测试脚本同上。这时运行测试脚本,会发现检查点没有通过,日志信息显示:Action.c(26): Error: search failed。

  为什么没有设置loadrunner的字符集的检查点可以通过,而设置loadrunner的字符集为:UTF-8的检查点却不能通过呢?我们来看下这两个脚本所产生的代码生成日志信息,在测试脚本的data目录下的CodeGenerationLog.txt文件中。这时我们可以在两个文件中搜索检查点“百度”关键字,可以发现在没有设置loadrunner字符集的这个文件中可以搜索到“百度”关键字而在设置loadrunner的字符集为:UTF-8的这个文件中却搜索不到“百度”关键字。这是因为设置loadrunner的字符集为:UTF-8会把测试脚本所生成的信息会强制将gb2312转换为UTF-8。所以对于被测试系统字符集是gb2312的网站,loadrunner中又将字符集设置为:UTF-8,中文关键字作为检查点的时候可能失败。

再以google为例:

1、在录制google的测试脚本的时候不设置loadrunner字符集,脚本如下:

 Action()
{
web_reg_find("Search=body",
"SaveCount=times",
"Text=地图",
LAST); web_url("www.google.com.hk",
"URL=http://www.google.com.hk/",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t2.inf",
"Mode=HTML",
EXTRARES,
"Url=/extern_js/f/CgV6aC1DThICaGsrMEU4ACwrMFo4ACwrMA44ACwrMBc4ACwrMDw4ACwrMFE4ACwrMAo4AUACLCswFjgALCswGTgAmgICc2gsKzAlOAAsKzBAOAAsKzBNOAAsKzBOOAAsKzBUOAAsKzBpOAAsKzAYOAAsKzAmOAAsgAJJkAJC/-1wqCmgtU-M.js", ENDITEM,
"Url=/images/srpr/nav_logo73.png", ENDITEM,
"Url=/csi?v=3&s=webhp&action=&e=17259,17315,23628,28505,28936,29561,29810,30348,30760,31090,31127,31267,52921&ei=RTkHTtGwDYHEvgPK1firDQ&expi=17259,17315,23628,28505,28936,29561,29810,30348,30760,31090,31127,31267,52921&imc=1&imn=1&imp=1&rt=xjsls.47,prt.62,xjses.3922,xjsee.3953,ol.4000,iml.984,xjs.4109", ENDITEM,
"Url=/complete/search?hl=zh-CN&client=hp&xhr=t&q=n&cp=1", ENDITEM,
"Url=/complete/search?hl=zh-CN&client=hp&xhr=t&q=nb&cp=2", ENDITEM,
LAST); if(atoi(lr_eval_string ("{times}"))>)
lr_output_message("search successful");
else
lr_error_message("search failed"); return ;
}

运行测试脚本,检查点没有通过,日志信息显示:Action.c(31): Error: search failed。

2、设置loadrunner的字符集为:UTF-8,再次录制一个google的测试脚本,测试脚本同上。这时运行测试脚本,会发现检查点通过。

  为什么没有设置loadrunner的字符集的检查点不能通过,而设置loadrunner的字符集为:UTF-8的检查点却能够通过呢?我们来看下这两个脚本所产生的代码生成日志信息,在测试脚本的data目录下的CodeGenerationLog.txt文件中。这时我们可以在两个文件中搜索检查点“地图”关键字,可以发现在没有设置loadrunner字符集的这个文件中搜索不到“地图”关键字而在设置loadrunner的字符集为:UTF-8的这个文件中却能够搜索到“地图”关键字。这是因为没有设置loadrunner的字符集为:UTF-8,不会自动把测试脚本所生成的信息转换为UTF-8而是转换为其他的Encode。所以对于被测试系统字符集是UTF-8的网站,loadrunner中必须将字符集设置为:UTF-8,中文关键字作为检查点的时候才能通过。

  附:录制脚本后,切换到树视图中,打开相应的脚本页面。在右侧的PageView中录制的脚本呈现中文版式,但是当切换到Server Response中,所有的中文全部换成的乱码,如“勌缞仫訆”,原因是服务器端没有把响应的编码设置为gb2312,可以找到Web.Config文件,在<system.web>….</system.web>节点加入<globalization requestEncoding="gb2312" responseEncoding="gb2312" fileEncoding="gb2312"/>后再次录制脚本,乱码变中文。(gb2312:中国大陆制订了简体汉字的字符集)

--------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------

  以上为网上装载的文章,因为平时在性能测试脚本调试时经常遇到有关LR的编码的问题,所以对于经常忽略的编码问题引起了重视。首先对于以上文章,有几点可能不是很准确,在我的机器上(WIN7+IE8)上面,百度和谷歌网站编码都是UTF-8的。而且发现大部分的网站都是UTF-8编码,平时我在录制这些网站时,loadrunner中的字符集也设置为了UTF-8录制完后LR的tree视图中的HTML视图中中文都被显示为乱码,生成和回放日志中的中文也为乱码,中文检查点会失败。(偶有发现有些机器也是WIN+IE8(详细配置是否一致未知),进行录制这些网站脚本时,HTML视图中也显示为乱码,但是生成和回放日志中的中文不是乱码而显示正常,并且直接使用中文检查点也可以成功)

中文检查点问题

对于中文检查点(或是关联边界)失败的问题是有其解决办法的,即在检查中文时,先使用lr_convert_string_encoding函数将中文从本地编码转换成UTF-8编码。再作为检查点,另外注意lr_convert_string_encoding将原字符串转换为UTF-8后会在字符串的最后面加\x00,这个需要使用lr_save_string(lr_eval_string("{str_param}"),"str_param")来处理或使用C的字符串截断函数strtok来截取掉。

总结为:当发现LR的tree视图中的HTML视图中你所看到的是什么样的,那么脚本中检查点检查的内容就要写成什么样的,比如需要检查的内容是:涓佷紵,那么脚本中检差点函数中检查的内容写:涓佷紵就可以检查通过,当然我们肯定不知道这样的乱码究竟对应的中文是什么,一般情况下,这种乱码的编码格式是UTF-8的,如果要看到的它的真实面貌就需要将“涓佷紵”通过lr_convert_string_encoding从UTF-8编码转换成本地编码(一般为gb2312)再看。比如该例为:丁伟,所以反过来,我们在添加检查点时应该是先将中文丁伟通过lr_convert_string_encoding从本地编码转换成UTF-8编码,然后作为检查点的内容,关联的边界也是同样的道理。例子如下:

     //将中文从本地编码转到UTF8编码
lr_convert_string_encoding( lr_eval_string("{PPMname}"),
LR_ENC_SYSTEM_LOCALE,
LR_ENC_UTF8,
"para_tstring" );
//lr_output_message("Notify: para_tstring:%s",lr_eval_string("{para_tstring}")); //置于变量中
strcpy( para_string,
lr_eval_string("{para_tstring}") ); //去掉末尾的\x00
para_str = (char *)strtok(para_string,"\\");
//lr_output_message("Notify:para_str:%s",para_str); //置于参数中
lr_save_string( para_str,
"para_str" ); //检查点
web_reg_find("Fail=NotFound",
"Search=Body",
"SaveCount=countxx",
//"Text=2012 涓蒋iNOC PDU",
"Text={para_str}",
LAST); //用作右边界 PPMid 0cf6478f-cc83-45a4-9f28-e7396b72d66e
web_reg_save_param_ex(
"ParamName=correlation_PPMid",
"LB=option value=\\\'",
"RB=\\\' title=\\\'{para_str}",
"Ordinal=1",
SEARCH_FILTERS,
"Scope=BODY",
LAST);

URL和HTML编码:

关于编码问题,在LR的脚本中可能还会有这样的一个问题,就是有时发现录制的脚本中会有很多含有很多%的ASCII码串,比如下面这个函数:

 web_custom_request("ServiceCall_3",
"URL=http://w3scm-uata.huawei.com/scm/scmui/issui/webengine/huawei/wpf/frame/base/ServiceCall",
"Method=POST",
"Resource=0",
"RecContentType=text/html",
"Referer=http://w3scm-uata.huawei.com/scm/scmui/issui/webengine/huawei/wpf/Framework#/!0/!C000000000028588/!./!./!./!./!./!1384247116426",
"Snapshot=t113.inf",
"Mode=HTTP",
"Body=name=iss.sch.mrmatch.SeachDashbordDetail&applicationID=&sub_app_id=&params="
"%7B%22wpf_dup_token%22%3A%22-19613772761384247117836%22%2C%22sessionData%22%3A%22%7B%5C%22tag_data%5C%22%3A%7B%5C%22currentModel%5C%22%3A
   
LAST);

这种含有%的串又是什么呢?如果要对这种串进行参数化该怎么实现?

发现这种串为URL编码格式,因为URL只能使用ASCII码,所以有很多特殊字符都需要转码为URL的编码,关于URL编码对照表可以参考:HTML URL 编码

这种编码可能有两类,一类是诸如双引号”这种特殊字符被转为了%串,如:%22;另一类就是有的中文被转成了这种格式。

URL编码   URL只能使用ASCII字符集来通过因特网进行发送。由于URL常常会包含ASCII集合之外的字符,URL必须转换为有效的ASCII格式。URL编码使用"%"其后跟随两位的十六进制数来替换非ASCII字符。常见例子:
1)+ 表示空格(在 URL 中不能使用空格) %20
2)/ 分隔目录和子目录 %2F
3)? 分隔实际的 URL 和参数 %3F
4)% 指定特殊字符 %25
5)# 表示书签 %23
6)& URL中指定的参数间的分隔符 %26

HTML特殊符号编码   由于HTML的语法特点,有些字符需要使用特殊的符号串来表示,比如HTML本身语法中就包含有<、>等,所以当要显示这两个字符时就要使用特殊的符号串。常见例子:
HTML 原代码 显示结果 描述
&lt; < 小于号或显示标记
&gt; > 大于号或显示标记
&amp; & 可用于显示其它特殊字符
&quot; “ 引号
&reg; ® 已注册
&copy; © 版权
&trade; ™ 商标
&ensp;   半个空白位
&emsp;   一个空白位
&nbsp; 不断行的空白
<sub></sub> H2O 下标标签
<sup></sup> X2 上标标签

注意:URL或HTML的转码都发生在字符编码例如UTF-8等之上的,即在发送时是先经过URL或HTML的转码再经过字符编码后再发送的,而在解码时是先进行字符编码对应的解码再进行URL或HTML的反解码的。所以对于脚本中这种串的参数化问题,可以使用LR提供的web_convert_param函数来进行编码转换来实现,例如中文:丁伟, 录制的脚本中为:%E4%B8%81%E4%BC%9F,那么参数化就应该是将中文丁伟转成%E4%B8%81%E4%BC%9F,一般为先把中文丁伟转成UTF-8编码,再转成URL格式就刚好对应上了。例如:

 lr_save_string("丁伟","para_tstring");  ---(注意:实际使用时会添加参数para_tstring,并设置多个值,这里只是为简化例子)
lr_output_message("Notify:para_tstring:%s",lr_eval_string("{para_tstring}"));

lr_convert_string_encoding(lr_eval_string("{para_tstring}"),LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8,"para_tstring");
lr_output_message("Notify:LOCALE-->UTF8 para_tstring:%s",lr_eval_string("{para_tstring}")); web_convert_param("para_tstring", "SourceEncoding=PLAIN",
"TargetEncoding=URL", LAST );
lr_output_message("Notify:PLAIN-->URL para_tstring:%s",lr_eval_string("{para_tstring}")); Starting iteration .
Starting action Action.
Action.c(): Notify:para_tstring:丁伟
Action.c(): Notify:LOCALE-->UTF8 para_tstring:涓佷紵
Action.c(): web_convert_param was successful [MsgId: MMSG-]
Action.c(): Notify:PLAIN-->URL para_tstring:%E4%B8%%E4%BC%9F%
Ending action Action.
Ending iteration .
函数web_convert_param详见在线帮助文档,直观/感性认识:

HTML                        URL                           Plain Text
&lt;mytag&gt;&amp;   %3Cmytag%3E%26      <mytag>&

以下FAQ可供参考:

Q1、录制的脚本乱码?
LR录制的脚本中可能会有乱码,主要是当URL中有中文时。
通过如下问题可以解决此问题:
a) Go to Vugen -> Tools -> Recording Options -> Advanced
b) Check the option that reads "Support Charset" and select "UTF-8"

Q2、回放乱码?
有一类乱码问题是:IE访问页面一切正常,但是LR回放时在run viewer中显示的页面为乱码。这一问题一般是由于页面保存时的编码格式和页面中的charset格式不一致引起的(html头中通常会有<meta. http-equiv="Content-Type" c>)。遇到这类问题,只需要将页面做另存为,将保存的编码格式和页面中的charset格式统一起来就可以了。引起问题的原因是:IE浏览器解码时会优先考虑文件的保存编码格式,而后考虑页面中的charset格式,(正常情况下两者是一致的),而run viewer是直接使用页面中的charset格式打开的。

例如:charset=gb2312,但是文件的保存的编码格式是UTF-8,IE访问时会以UTF-8解码,而run viewer却是以GB2312格式解码,以GB2312解UTF-8自然是乱码。出现乱码的原因和解决办法很可能不全面,请大家补充。说到底,还是run viewer功能比较简单引起的。run viewer中的乱码不影响测试结果。

Q3、LR中乱码相关设置和用法?

1)vugen的Tools -> Recoding Options -> Advanced -> Support charset -> UTF-8

2)Vuser-->运行时设置-->浏览器-->浏览器仿真-->更改-->使用浏览器-->语言下来选择 “中文(中国)”

3)在LoadRunner中,为我们提供了一个字符串编码转换的函数lr_convert_string_encoding,用法如下:
int lr_convert_string_encoding ( const char *sourceString, const char *fromEncoding, const char *toEncoding, const char *paramName);”
例子:
lr_convert_string_encoding(lr_eval_string("{NewParam_1}"),LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8,"str");
strcpy(tmp,lr_eval_string("{str}"));

4)修改代码,增加请求头字段:
web_add_header("Content-Type", "text/xml; charset=UTF-8");

------------------------------------------------------------------------------------分割线------------------------------------------------------------------------------

以上关于LR中乱码问题的解决方法基本可以解决大部分的转码问题了,但在某些情况下可能需要将发送的数据中某些符号转换成其他的形式,比如将"+"号转换成"%2B"等等,这里提供一个通用的C语言函数来处理该类问题,该函数可以把一个原始字符串中的某个字符串(单个或多个字符)替换为指定的字符串(单个或多个字符)。代码如下:

char *ReplaceStr(char *sSrc,char *sMatchStr,char *sReplaceStr)
{
int StringLen;
char caNewString[];
char *FindPos;
FindPos =(char *)strstr(sSrc, sMatchStr);
if( (!FindPos) || (!sMatchStr) )
{
return sSrc;
}
while( FindPos )
{
memset(caNewString, , sizeof(caNewString));
StringLen = FindPos - sSrc;
strncpy(caNewString, sSrc, StringLen);
strcat(caNewString, sReplaceStr);
strcat(caNewString, FindPos + strlen(sMatchStr));
strcpy(sSrc, caNewString);
FindPos =(char *)strstr(sSrc, sMatchStr);
}
free(FindPos);
return sSrc;
}

使用方法:

在脚本的“globals.h”中或Action()函数之上,复制上面代码,然后在Action()函数脚本中,用这个函数替换其中的特殊符号,例如:

     char *str = NULL;
str = ReplaceStr(lr_eval_string("{para}"),"+","%2B");
lr_output_message("Notify:str:%s",str);

  上面调用ReplaceStr的代码的意思是,把关联函数获取的值{para}参数中的“+”号替换为“%2B”,并放入变量str 中,后面使用变量str即可。有多个替换的把函数调用多遍。需要注意

注意:上面函数中定义的局部变量caNewString数组大小,但传入的原字符串sSrc很大时,caNewString的空间可能不足,此时就应该将1024换成更大的值。

---------------------------------------------附:

关于字符编码:字符集和字符编码(Charset & Encoding)

LR中的编码问题的更多相关文章

  1. python语言中的编码问题

    在编程的过程当中,常常会遇到莫名其妙的乱码问题.很多人选择出了问题直接在网上找答案,把别人的例子照搬过来,这是快速解决问题的一个好办法.然而,作为一个严谨求实的开发者,如果不从源头上彻底理解乱码产生的 ...

  2. LR中的时间戳函数web_save_timestamp_param

    以前真没注意过后面看某个群有人说到这个函数一查,还真有,那么处理时间戳就简单很多了,我们经常在各种网站上看到类似于这样的时间戳 51Testing软件测试网"d bLq!uR&am ...

  3. WebGIS中GeoHash编码的研究和扩展

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 1.1普通地理编码流程 将采集的POI入库后,数据库里保存有 ...

  4. 理清Java中的编码解码转换

    1.字符集及编码方式 概括:字符编码方式及大端小端 详细:彻底理解字符编码 可以通过Charset.availableCharsets()获取Java支持的字符集,以JDK8为例,得到其支持的字符集: ...

  5. 聊聊python 2中的编码

    为什么需要编码: 计算机可以存储和处理二进制,那么从文字到计算机可以识别的二进制之间需要对应的关系,于是便有了ASCII,ASSCII使用7位字符,由于1byte=8bit,所以最高位补一个0,使用8 ...

  6. python中的编码问题:以ascii和unicode为主线

      1.unicode.gbk.gb2312.utf-8的关系 http://www.pythonclub.org/python-basic/encode-detail 这篇文章写的比较好,utf-8 ...

  7. 中文在unicode中的编码范围

    以前写过一篇贴子是写中文在unicode中的编码范围 unicode中文范围,但写的不是很详细,今天再次研究了下unicode,并给出详细的unicode取值范围. 本次研究的unicode对象是un ...

  8. LR中的C语言问题

    今天在调试LR的脚本(C)时遇到了几个甚是头痛得问题,下面简单总结下: 1.首先LR中的C编译器遵循C90标准,规定在一个函数中,变量定义必须放在所有的执行语句之前!一旦在运行语句之间再有定义的话,会 ...

  9. LR中日志设置和日志函数

    LR中日志参数的设置与使用 1.Run-Time Setting日志参数的设置 在loadrunner的vuser菜单下的Run-Time Setting的General的LOG选项中可以对在执行脚本 ...

随机推荐

  1. 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))

    解决办法:在项目属性里设置“生成”=>“目标平台”为x86而不是默认的ANY CPU.

  2. matlab参数查询

    nargout nargout的作用是在matlab中定义一个函数时, 在函数体内部, nargout指出了输出参数的个数(nargin指出了输入参数的个数). 特别是在利用了可变参数列表的函数中, ...

  3. hadoop2.2.0部署

    hadoop2.2.0部署 下载安装包 hadoop-2.2.0-cdh5.0.0-beta-1.tar.gz 解压 tar zxvf hadoop-2.2.0-cdh5.0.0-beta-1.tar ...

  4. ISODATA算法

    ISODATA算法是在k-均值算法的基础上,增加对聚类结果的'合并'和'分裂'两个操作,并 设定算法运行控制参数的一种聚类算法. 全称:Iterative Selforganizing Data An ...

  5. MySQL删除更新数据时报1175错误的问题

    今天删除mysql数据库中的一条记录的时候,一直不能删除,提示错误信息如下: Error Code: 1175. You are using safe update mode and you trie ...

  6. RGB

    一,介绍 RGB色彩模式是工业界的一种颜色标准,是通过对红(R).绿(G).蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的, RGB即是代表红.绿.蓝三个通道的颜色,这个标准几 ...

  7. java操作FTP,实现文件上传下载删除操作

    上传文件到FTP服务器: /** * Description: 向FTP服务器上传文件 * @param url FTP服务器hostname * @param port FTP服务器端口,如果默认端 ...

  8. Sea.js创始人玉伯的前端开发之路

    在Web应用程序的用户体验越来越被重视的今天,前端开发的地位也上升到了前所未有的高度,而随之而来的也有更多的挑战. 为了将前端开发者繁重的工作变得简单,框架应运而生.国内也不乏一些非常优秀的前端开发框 ...

  9. 两个List,第二个List根据第一个List排序

    /// <summary> /// 协同排序 /// </summary> /// <param name="sod"></param&g ...

  10. 如何使用数据库保存session的方法简介

    使用数据库保存session的方法 php的session默认是以文件方式保存在服务器端,并且在客户端使用cookie保存变量,这就会出现一个问题,当一个用户由于某种安全原因关闭了浏览器的cookie ...