软件测试


网站首页 | 软件测试论坛 | 软件测试培训 | 软件测试博客 | 软件测试杂志 | 软件测试沙龙 | 软件测试下载 | 软件测试顾问
业界新闻 | 软件测试人才 | 软件测试技术 | 软件测试工具 | 行业软件测试 | 软件测试管理 | 软件质量专栏 | 软件开发专栏
当前位置:首页>>软件测试工具>>Mercury>>正文
LoadRunner下DLL的调用
文章出处:51testing 作者:陈卫俊 发布时间:2007-01-26
场景介绍       
        最近在做类似于QQ的通信工具的性能测试
时发现了一些问题,现总结出来与大家分享一下。希望大家在使用LoadRunner时不仅仅停在只是录制/播放角本,而全面提升角本的编程技术,解决复杂场景。
        本次测试中碰到的问题是这样的,在消息的传送过程中遇到了DEC加密的过程,LoadRunner录制到的全是加密的消息,比如我录制了某一个用户的登陆,发送消息,退出,但由于是加密的,只能单个用户使用,但如果我想并发多少个用户就存在很多问题,最直接的一个问题就是用户名是加密的,密码是加密的,当然你可以说让程序那里注掉加密的代码进行明码的测试,当然也是一种办法。但程序组提出了要使用更真实的方法来模拟,这时就必需使用下面介绍的方法。
        一开始是直接把API移植到LoadRunner中来,不过由于加密算法异常复杂,有几层循环,而角本是解释执行的,进行一次加密运算可能需要好几分钟,当然在角本里可以把角本本身运行的时间去掉,但这样做显然没有直接调用DLL来的效率高。由于程序组比较忙,所以无法提供DLL给测试,所以测试完成了DLL的编写,并在LoadRunner中调用成功,高效的完成了用户信息加密,参数
关联,成功的完成了测试。
动态链接库的编写
  在Visual C++6.0开发环境下,打开FileNewProject选项,可以选择Win32 Dynamic-Link Library建立一个空的DLL工程。
  1. Win32 Dynamic-Link Library方式创建Non-MFC DLL动态链接库

  每一个DLL必须有一个入口点,这就象我们用C编写的应用程序一样,必须有一个WINMAIN函数一样。在Non-MFC DLL中DllMain是一个缺省的入口函数,你不需要编写自己的DLL入口函数,用这个缺省的入口函数就能使动态链接库被调用时得到正确的初始化。如果应用程序的DLL需要分配额外的内存或资源时,或者说需要对每个进程或线程初始化和清除操作时,需要在相应的DLL工程的.CPP文件中对DllMain()函数按照下面的格式书写。
 
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
    break;
case DLL_THREAD_ATTACH:
    break;
case DLL_THREAD_DETACH:
    break;
case DLL_PROCESS_DETACH:
    break;
default:
    break;
}
return TRUE;
}
  
        参数中,hMoudle是动态库被调用时所传递来的一个指向自己的句柄(实际上,它是指向_DGROUP段的一个选择符);ul_reason_for_call是一个说明动态库被调原因的标志,当进程或线程装入或卸载动态链接库的时候,操作系统调用入口函数,并说明动态链接库被调用的原因,它所有的可能值为:DLL_PROCESS_ATTACH: 进程被调用、DLL_THREAD_ATTACH: 线程被调用、DLL_PROCESS_DETACH: 进程被停止、DLL_THREAD_DETACH: 线程被停止;lpReserved为保留参数。到此为止,DLL的入口函数已经写了,剩下部分的实现也不难,你可以在DLL工程中加入你所想要输出的函数或变量了。

  我们已经知道DLL是包含若干个函数的库文件,应用程序使用DLL中的函数之前,应该先导出这些函数,以便供给应用程序使用。要导出这些函数有两种方法,一是在定义函数时使用导出关键字_declspec(dllexport),另外一种方法是在创建DLL文件时使用模块定义文件.Def。需要读者注意的是在使用第一种方法的时候,不能使用DEF文件。下面通过两个例子来说明如何使用这两种方法创建DLL文件。

  1)使用导出函数关键字_declspec(dllexport)创建MyDll.dll,该动态链接库中有两个函数,分别用来实现得到两个数的最大和最小数。在MyDll.h和MyDLL.cpp文件中分别输入如下原代码:
 
//MyDLL.h
extern "C" _declspec(dllexport) int desinit(int mode);
extern "C" _declspec(dllexport) void desdone(void);
extern "C" _declspec(dllexport) void des_setkey(char *subkey, char *key);
extern "C" _declspec(dllexport) void endes(char *block, char *subkey);
extern "C" _declspec(dllexport) void dedes(char *block, char *subkey);
//MyDll.cpp
#include"MyDll.h"
//这里我用了比较大小的函数代替了我要实现的函数
int desinit(int a, int b)
{
if(a>=b)return a;
else
return b;
}
int desdone(int a, int b)
{
if(a>=b)return b;
else
return a;
}
该动态链接库编译成功后,打开MyDll工程中的debug目录,可以看到MyDll.dll、MyDll.lib两个文件。LIB文件中包含DLL文件名和DLL文件中的函数名等,该LIB文件只是对应该DLL文件的"映像文件",与DLL文件中,LIB文件的长度要小的多,在进行隐式链接DLL时要用到它。读者可能已经注意到在MyDll.h中有关键字"extern C",它可以使
其他编程语言访问你编写的DLL中的函数。
LoadRunner调用动态链接库
        上面完成动态链接库开发后,下面就介绍动态链接库如何被LoadRunner进行调用,其实也是很简单的。在LoadRunner中的DLL调用有局部调用与全局调用,下面介绍局部调用。
首先把你编译的DLL放在角本路径下面,这里是MyDll.dll,MyDll.lib.然后在Action中使用
lr_load_dll("MYDll.dll"),此函数可以把DLL加载进来,让你调用DLL里面的函数,而DLL中的运算是编译级的,所以效率极高,代码样例如下:
#include "lrs.h"
Action()
{
        //
        int nRet = 6;
        char srckey[129];
        memset(srckey, 'a', 128);
        lr_message(lr_eval_string(srckey));
        lr_load_dll("MyDLL.dll");
        nRet = desinit(5,8);
        lr_message("比较的结果为%d",nRet);
    return 0;
}
运行结果
        比较的结果为8

        全局的动态链接库的调用则需要修改mdrv.dat,路径在LoadRunner的安装目录下面(LoadRunner/dat directory);在里面修改如例:
        [WinSock]
ExtPriorityType=protocol
WINNT_EXT_LIBS=wsrun32.dll
WIN95_EXT_LIBS=wsrun32.dll
LINUX_EXT_LIBS=liblrs.so
SOLARIS_EXT_LIBS=liblrs.so
HPUX_EXT_LIBS=liblrs.sl
AIX_EXT_LIBS=liblrs.so
LibCfgFunc=winsock_exten_conf
UtilityExt=lrun_api
ExtMessageQueue=0
ExtCmdLineOverwrite=-WinInet No
ExtCmdLineConc=-UsingWinInet No
WINNT_DLLS=user_dll1.dll, user_dll2.dll, ...
//最后一行是加载你需要的DLL
        这样你就可以在LR中随意的调用程序员写的API函数,进行一些复杂的数据加密,准备的一些操作,进行复杂的测试。同时如果你觉的有大量高复杂的运算也可以放在DLL中进行封装,以提高效率。


站内搜索
相关文章
◎关于"RPC server is unavailable"的解决方案
◎QTP中虚拟对象设置
◎TD中Case的复用
◎中英文操作系统切换导致的找不到对象的解决方法
◎利用Analysis 分析结果
◎文件/表参数的数据分配和更新方法
◎QTP描述性编程原理介绍
◎对象库的管理与合并
◎QTP的学习历程
◎LoadRunner学习——LoadRunner的安装
◎解决回放时浏览器乱码问题
◎TD与QTP连接
◎QTP中的描述性编程
◎测试结果报告知多少
◎QTP中设置共享对象库
◎设定时间让脚本自动运行
◎如何在QTP中使用IE以外浏览器录制和运行测试?
◎QTP中调用共享文件
◎如何使用qtp检查网页中显示的文字颜色为指定的颜色
◎LoadRunner使用虚拟IP测试流程
◎QTP中的步骤生成器
◎Robot GUI脚本操作SQL SERVER数据库
◎QTP脚本还可以这样写
◎对动态的weblist取得其name值
◎QTP中测试环境的初始化
◎QTP Recovery Scenario 简介
◎解决LR无法动态从数据库取值的方法
◎详解loadrunner的think time
◎QTP的登陆脚本设计
◎再论TD的数据迁移
◎关于IP欺骗的问题
◎LoadRunner与Winsock协议[翻译]
◎QTP的录制回放过程
◎LoadRunner函数介绍续
◎LoadRunner函数介绍
◎如何通过LoadRunner监控Linux和Unix操作系统的资源状况
◎专注于业务需求的自动化测试——Mercury Business Process Testing
◎如何查看LoadRunner虚拟用户(vuser)类型
◎使用LoadRunner测试TUXEDO
◎对LR回放中highest severity level was"ERROR"的解决方法
◎使用Winrunner进行性能测试
◎如何区分Server Time 和 Network Time
◎利用LR测试程序基类的性能
◎如何用LR监视服务器LINUX的方法
◎如何在QC中调用QTP进行测试
◎WinRunner使用经验介绍
◎使用LoadRunner来测试BEA TUXEDO(LoadRunner7.6)
◎MI测试工具介绍
◎VB 调用 QuickTestpro 脚本
◎QTP的登陆脚本设计
热门文章
◎主流测试工具介绍(1)
◎Winrunner经验总结
◎主流测试工具介绍(2)
◎主流测试工具介绍(3)
◎Winrunner TSL命令简介(一)
◎WinRunner的问题整理
◎LoadRunner监视的性能计数器
◎四款主流测试工具的测试流程
◎Loadrunner中参数的设置
◎LoadRunner的一个解决方案
◎让LoadRunner走下神坛
◎WinRunner 脚本标准格式
◎LoadRunner简化国泰航空测试流程
◎WinRunner如何实现自动化测试
◎利用loadrunner测试ORACLE存储过程的性能
◎jboss tomcat weblogic websphere 性能对比测试
◎Winrunner TSL命令简介(四)
◎Winrunner TSL命令简介(二)
◎使用LoadRunner测试TUXEDO
◎TestDirector项目数据迁移完整过程
◎LoadRunner函数介绍
◎关于"RPC server is unavailable"的解决方案
◎Winrunner TSL命令简介(三)
◎使用Winrunner进行性能测试
◎TD7.6 字段中英文对照表
◎Winrunner Context Sensitive命令列表
◎LoadRunner本机录制http协议程序遇到的问题以及解决方法
◎WinRunner使用经验介绍
◎TD中Case的复用
◎对脚本的建议
◎MI测试工具介绍
◎QTP的登陆脚本设计
◎如何用QTP解析PDF
◎winsock协议错误编码解析
◎TD 7.x 升级到 TD 8.0 的一些经验(SQLSERVER 下)
◎QuickTestPro SP考试心得
◎loadruner报错:Step download timeout(120 seconds)的解决方法
◎使用LoadRunner来测试BEATUXEDO (LoadRunner 7.6)
◎QuickTestPro中的快捷键
◎ERP功能测试最佳实践:10个步骤确保ERP系统的可靠性
◎高级测试管理的工具和技术
◎winsock的buffer简单解析
◎何谓 Keyword-Driven Testing?
◎LoadRunner学习——LoadRunner的安装
◎QTP的学习历程
◎使用LoadRunner来测试BEA TUXEDO(LoadRunner7.6)
◎LoadRunner函数介绍续
◎QTP的登陆脚本设计
◎关于"The RPC server is unavailable"的探讨及解决方案
◎改进质量和测试管理

Google提供的广告