-
Key
2009-09-03 11:13:54
global 100user
AEAMAUIK-YAFEKEKJJKEEA-BCJGI
10000 web clients
AEABEXFR-YTIEKEKJJMFKEKEKWBRAUNQJU-KBYGB
500 VU的LoadRunner 8.0 Global licence
licence:
BGAUGLIX-AJGI-AEIEKEKJJKEAFJP-BDFHW
Valid until 31. 十月 2003 -
Loadrunner登录脚本认证失败的原因分析和解决方法
2009-04-02 13:36:08
测试对象:某Web即时通讯系统(以下称WebIM)
开发语言:XML
数据通讯协议: Web(HTTP/HTML)协议、Windows Sockets协议
底层数据库:Mysql
服务器操作系统:Redhad 4
脚本实现功能:登入系统后,再退出系统。
问题1:录制开发的脚本可以成功回放,但是数据库的logout表里却查不到“登出”的用户?
分析:录制的时候只选用了单协议:Web(HTTP/HTML)协议,而WebIM的实现不只用到了Web(HTTP/HTML)协议,也用到了Windows Sockets协议。在定位了问题的"原因"之后,笔者尝试录制多协议的脚本,结果回放失败。回放失败是因为Webim在登录的过程中有个加密验证的过程。脚本回放时提交了上一次的经过Sha1加密后的密文,而此时服务器端的Sha1密文已经发生了改变。从而导致了失败。
解决方法:a、使用双协议录制脚本
b、开发Sha1算法的DLL文件并在脚本中调用。
问题2:录制的脚本中并没有捕获到服务器返回的Session ID?
分析和方案:Webim的开发用到了XML和Windows Sockets协议,因此按照正常的思路,Loadrunner在录制脚本时,也应该采用XML和Windows Sockets协议,但实际情况是这样的,录制的脚本中并没有捕获到服务器返回的Session ID。既然公司内网的Jabberd服务器有专门的测试客户端,笔者决定通过这个客户端录制脚本,由于这个客户端和服务器的通信协议是Windows Sockets,因此录制协议也采用了这个最底层的协议。这一次,录制的脚本中捕获到了服务器返回的Session ID。为了保证脚本回放时能够动态的获取到这个Session ID,需要做“关联”操作,笔者使用了lrs_save_searched_string()函数,对脚本做了处理。
问题3:如何调用Dll来对服务器返回的序列和Password加密,以产生Sha1的密文?
分析和方案:脚本中加载了Dll库文件后,在调用库文件中的加密函数对Session ID+Password字符序列加密时,必须采用如下格式endes(a,b),其中的a代表源序列,b代表密文。经过这样的步骤处理后,调试脚本,就可以看到密文了。
问题4:Buf中参数化密文后,脚本还是不能编译通过,存在语法错误?
分析和方案:发现Loadrunner参数化,是按照它内置的机制执行的,符合这个机制,编译就能通过。后来在Gen中的Tools—>general option中找到了可以更改这个机制的地方,修改完了之后,脚本再次编译,这次OK了。
问题5:错误提示:没有足够的虚拟用户分配给这个NewPara?
分析和方案:loadrunner中在对用户名和密码或其他数据参数化了以后,不要将参数删除后,重新参数化,否则就会出现上述问题。笔者决定重新录制脚本,重新参数化,重新修改脚本。事实证明这样做是正确的,编译运行后,5个虚拟用户的脚本正确无误的通过。
-
修改 File 参数 100 为 1000【图例】
2009-01-06 10:16:51
如图
-
LR 进程机制
2008-12-25 18:19:17
今天测试了下 LR 的进程机制
记录下
一个进程:21M
一个进程:50用户
一个进程:54个线程^_^
-
修改换行符错误小技巧
2008-12-08 17:54:23
有时当你改了 N 次参数内容后还是提示换行符错误你可以在错误提示窗口里找到没有提示错误的脚本然后将正确的覆盖有错误提示的脚本里两字:“好使”错误提示:-13874 Error: missing newline in d:\test\a.dat -
错误为:27796 的解决方法
2008-12-08 15:22:34
负载机注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters里有如下两个键值:TcpTimedWaitDelayMaxUserPort1,这里的TcpTimedWaitDelay默认值应该中是30s,所以这里,把这个值调小为5s(按需要调整)。2,也可以把MaxUserPort调大(如果这个值不是最大值的话)。【Zee 原创】 -
[论坛] 如何发送 Byte 数组
2008-12-08 15:17:36
请教大侠们
现在遇到一个难道
如何通过 Sokets 发送 data.ws 里的 buf 发送数组数据
数组内容:
byte bytes[5];
bytes[0] = 0;
bytes[1] = 0;
bytes[2] = 0;
bytes[3] = 170;
bytes[4] = 0;
本人已快发疯
知道的仁兄告知下
感激不尽 -
脚本编写
2008-06-25 15:47:03
VuGen脚本文件的开发过程
1。定义测试项目的目标,环境,脚本,测试数据,硬件等。脚本应该符合编码规范或编码习惯。
2。创建一个版本文件夹来保存被测应用程序相关的各种不同资源,例如截获的.png/.gif图形文件,录制过程保存的html文件,录制中的所有html源文件和VuGen的录制日志。
3。列出(在表里)每一个手动操作业务过程需要的实际步骤
1)截取每一个屏幕图像(screen image )。
2)为每一个屏幕(screen)分配一个唯一的事务名称。
3)为处理的每一个步骤使用的技术组件(URL或者方法和函数)做注释。
4。创建一个版本文件夹。
注:我不喜欢使用默认位置,我喜欢把所有脚本相关的文件放到一个相同的文件夹中。不幸的是,这意味着如果我在不同的测试间互相交换录制,那我每次都得记住修改默认的设置。
注:当录制一个新的脚本时,我喜欢选择多协议而不是单个协议。。。
5。根据你的业务处理列表上指定的用户使用步骤和screen的顺序来使用VuGen录制程序,产生一系列脚本代码。在“开始录制”对话框中
* 使用COM/DCOM 协议时,选择“Win32应用程序“
* 使用Web(HTTP/HTML)时,选择“Internet Application“
6。根据改进脚本方法和脚本语言规则来修改脚本。
改进脚本的方法:
1)为每一个GUI的screen添加事务语句来获得事务时间。
2)添加显示数据来帮助调试。
3)添加验证点来验证是否期望的文本或者图片在每个脚本执行后显示。
4)通过插入新参数和动态获得整个文件的方式对硬编码的URL,用户id,用户密码和其他的变量数据进行参数化。这样脚本中的参数就可以被动态的替换,以此来模拟运行时不同数据的使用。
5)添加重试逻辑(retry logic)来处理不可见的错误。
6)添加随机函数发生器变化脚本来模拟真实的负载。
7)添加if/else逻辑来检查结果,或者来进行合适的操作,或者来在合适的时候退出脚本。
8)在一个screen中添加语句来捕获需要在其他命令中使用的数据。当使用Microsoft .NET的web form技术的时候,需要避免习惯性的“脚本超时“错误。
9)添加语句来调用外部库函数,以便保存和检索在内存Virtual Table Server中的数据。
10)处理XML.
11)添加语句来模仿客户端的Javascrīpt问题。
12)添加语句来管理超时。
13)从事务计时器中计算和减去无效的时间。
14)输出日志。
15)添加集合点。
16)添加时间(Timing)。
脚本语言规则:
把cookie代码标注出来(因为脚本运行的时候他们被再次执行)。
7。通过在VuGen中运行来调试和调整脚本(单个用户),同时运行时设置的日志能够显示如下信息:
辨别和解决脚本编辑错误。
决定timing.
设置初始运行设置的场景。
8。在控制器中使用full test Runtime Settings来运行脚本。
脚本录制和产生:
建立一个新脚本的第一步是选择一个单协议或多协议。
* 一些协议可能在多协议模式下不能用。
* 只有在多协议的GUI下你才能重新排列action
在使用Java协议之前,确保你在环境变量的路径下有JDK,否则你可能会遇到这个错误:
Error: Failed to find javac.exe Java Compiler in Path and JDK installation folder in registry. [MsgId: MERR-22981]
Error: Failed to get JRE version. Check that your PATH environment variable contains\bin directory. [MsgId: MERR-22986] 当选择Java协议的时候:
* 只有选择了“RMI Java”才能录制。
* 如果选择“Java user”,“开始录制”图标或菜单是灰色的。
当你打开一个新的脚本时,默认的脚本名称为“noname1”。下一个新的脚本名称为“noname2”,以此类推。
注:有顺序的录制多个动作(而不是录制一个动作,然后停止开始另一个动作)。这样能使你识别出在你脚本中需要关联的序列码(在例如PeopleSoft的程序中)。
注:每次修改脚本后,脚本都需要重新编译。
Java:略
脚本文件的调用:
VuGen是默认在你双击.usr后缀文件的时候被调用。
在这个文件里,Javascrīpt被指定为“Type=General-Js”。
为了避免重新编译,我使用命令行的变量和值得组合这样的批处理文件来调用控制器。例如:
- REM LoadRun from LoadRunner 8.0 default installation location:
SET LR80=C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin
cd %LR80%
wlrun.exe -TestRun c:\Temp\Scenario1.lrs -port 8080脚本文件Action
主机上的代理发送的到服务器的请求是由虚拟用户生成器创建的(VuGen.exe)action的回放实现的。
Loadrunner创建的脚本有三部分:
* vuser_init 来初始化 Vuser。执行在这部分的虚拟用户的状态是"Init"
* Action 用来重复多次迭代 执行到这部分的虚拟用户的状态是"Running"
* vuser_end 推出虚拟用户。 执行到这部分的虚拟用户的状态是"Exiting"
如果你的脚本只需要执行一次,你仍然需要把这些脚本写到Action部分,因为在其他部分(vuser_init 和vuser_end)有些命令是不合法的或者会忽略掉。
VuGen允许脚本包含多个action。所以我为每一个screen创建一个新的action。
注:如果你想使用不同的用户登陆,就不要把登陆操作放到vuser_init中,而是放到action部分。
VuGen根据选择脚本选择协议的不同来添加不用的引用到“.h”头文件。
C的.h头文件
对于Web(HTTP/HTML)协议,
创建globals.h,包含内容:
#ifndef _GLOBALS_H #define _GLOBALS_H //-------------------------- // Include Files #include "lrun.h" #include "web_api.h" #include "lrw_custom_body.h" // recorded for web_custom_request functions. //-------------------------- // Global Variables #endif // _GLOBALS_H
对于COM/DCOM协议:略
C脚本语言的格式:
LoadRunner使用的没有进行微软扩展的ANSI C语法。任意最小的action代码块如下:
#include as_web.h // from LoadRunner's include folder. Action1() { /* comment block */ // comment line return 0; }
C脚本编译/类库
当VuGen编译脚本时,产生一个"pre_cci.ci"文件,这个文件包含了所有action的代码和包含文件。这就是为什么会有语法错误“not writing pre_cci.ci”的原因。
控制器编译这些.ci文件为机器目标码。
VuGen在每一个脚本文件中自动创建一个lib文件夹,这个文件夹中包含了combined_lib.c文件。该文件包含了所有引用文件。
#include "lrun.h" 来定义 UNIX或者Windows的函数。
#include "globals.h" LoadRunner'的模版文件夹的其中一个。#include "vuser_init.c"
#include "Action.c"
#include "vuser_end.c"警告:当你使用类库中的函数却没有正确包含该类库的时候,你会收到一条错误信息:
- Error -- Unresolved symbol
C类库
LoadRunner 使用 1994 GNU C Pre-Processor options 和 1995 LCC-win32 Retargetable C Compiler/Linker from the Free Software Foundation via Chris Fraser of AT&T and Dave Hanson of Princeton.
附加的函数定义在 ANSI C library中。
外部的没有返回整型数的C函数需要在脚本的开头进行显式声明。例如,string函数中的 string tokenizer:
extern char* strtok(char *token, const char *delimiter);
Java语法:略
OK,先到这里,休息一下,下期接着翻译LR脚本相关知识.
-
Key
2008-06-25 15:39:06
golba-100: AEAMAUIK-YAFEKEKJJKEEA-BCJGI
500VU: BGAUGLIX-AJGI-AEIEKEKJJKEAFJP-BDFHW
web-10000: AEABEXFR-YTIEKEKJJMFKEKEKWBRAUNQJU-KBYGB
-
关联函数web_reg_save_param的设置
2008-06-25 14:45:54
问题提出:如何对关联的数据进行字符串操作。下面使用了
LoadRunner
自带的订票例子为例,进行了这方面的试验。假设我要关联的数据是由几个字符串组成的。如何使这些字符串组成一个参数,供我后面的函数使用?
解决方法:
使用多个关联函数,对关联参数进行字符串操作,最后把生成的字符串保存成一个参数,供下面调用该参数的函数使用。
脚本如下:
Action()
{
int number1,number2;
char session11[1000];
char string[1000];
int length;
char *stringtemp;
//char session22[20];
web_reg_save_param("session1","LB=name=userSession value=","RB=.","Ord=ALL",LAST);
web_reg_save_param("session2","LB=.","RB=<table border=0><tr><td> </td>","Ord=ALL",LAST);
web_url("WebTours",
"URL=http://127.0.0.1:6080/WebTours/",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
LAST);
strcpy(string,"");
strcpy(string,lr_eval_string("{session1_1}"));
//strcpy(session1,"");
sprintf(session11,"{session2_1}");
strcat(string,".");
length= strlen(lr_eval_string(session11));
length=length-2;
number1=atoi(lr_eval_string("{session1_count}"));
number2=atoi(lr_eval_string("{session2_count}"));
lr_output_message("%d,%d",number1,number2);
//lr_output_message("%d",length);
stringtemp=lr_eval_string(session11);
strncat(string,stringtemp,length);
//srcat(string,session11);
lr_save_string(lr_eval_string(string),"session");
lr_output_message("%s",lr_eval_string("{session1_1}"));
lr_output_message("%s",lr_eval_string("{session2_1}"));
web_submit_data("login.pl",
"Action=http://127.0.0.1:6080/WebTours/login.pl",
"Method=POST",
"RecContentType=text/html", "Referer=http://127.0.0.1:6080/WebTours/nav.pl?in=home",
"Snapshot=t2.inf",
"Mode=HTML",
ITEMDATA,
"Name=userSession", "Value={session}", ENDITEM,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
"Name=JSFormSubmit", "Value=on", ENDITEM,
"Name=login.x", "Value=50", ENDITEM,
"Name=login.y", "Value=10", ENDITEM,
LAST);
lr_output_message("%s",lr_eval_string("{session}"));
return 0;
}
有两个关联的参数,
session1
和
session2
,最后生成
session
,被
web_submit_data
函数调用。蓝色部分是需要特别注意的地方。
脚本编写调试过程中遇到的问题和解释:
1.
web_reg_save_param
()中如果没有指定
Ord=ALL
的话,默认是取的第一个符合左右边界的值,这样我们使用关联的参数时可以直接使用变量名,如
session1
2.
web_reg_save_param
()中如果指定
Ord=ALL
的话,会生成一个数组,这样想取某个参数的话,需要使用的参数名需要加
_
和数组中的位置
,
如例子中取第一个
session1_1
,
如果这时候仍然用
session1,
是取不到参数的值的
.
3.
顺序问题
:
对关联参数相关的操作
,
需要放到包含该关联数据的请求函数之后
,
如上紫色部分代码用到关联的参数的语句
,
都需要放到
web_url()
之后
,
否则也不会取到关联的数据
4.注意lr_eval_string()函数和lr_save_string()函数的用法.
.
〖转自:zibeike〗