性能测试LoadRunner解决动态验证码问题

对于这个问题,通常我们可以采取以下三个途径来解决该问题: 

1、第一种方法,也是最容易想到的,在被测系统中暂时屏蔽验证功能,也就是说,临时修改应用,无论用户输入的是什么验证码,都认为是正确的。这种方法最容易实现,对测试结果也不会有太大的影响(当然,这种方式去掉了“验证验证码”这个环节,不过这个环节本来就很难成为系统性能瓶颈)。但这种方法有一个致命的问题:如果被测系统是一个实际已上线的系统,屏蔽验证功能会对已经在运行的业务造成非常大的安全性的风险,因此,对于已上线的系统来说,用这种方式就不合适了;     

2、第二种方法,在第一种方法的基础上稍微进行一些改进。第一种方法带来了很大的安全性问题,那么我们可以考虑,不取消验证,但在其中留一个后门,我们设定一个所谓的“万能验证码”,只要用户输入这个“万能验证码”,我们就验证通过,否则,还是按照原先的验证方式进行验证。这种方式仍然存在安全性的问题,但由于我们可以通过管理手段将“万能验证码”控制在一个小的范围内,而且只在性能测试期间保留这个小小的后门,相对第一种方法来说,在安全性方面已经有较大的改进了;

3、如果安全性对应用来说真的是至关重要的,不容许有一丝一毫的闪失,那我们还可以用更进一步的方法来处理这个问题。a)一般的性能测试工具(MI的LR、Seague的Silk performer等)都能够调用外部的DLL或是组件接口,因此,可以考虑获得“验证码验证”部分的实现,写一个验证码获取的DLL,在测试脚本中进行调用即可。  b)或者用一个请求去刷新认证码页面,然后通过关联将返回的图片保存为硬盘的一个文件,然后用ocr(光学字符识别)去识别这个文件内容,保存结果到txt,最后用LR读这个文本。

方法a)示例:

在脚本里添加函数解决验证码的问题,当然这种方法绕过服务器,但还是可行的

步骤一:编写一个GUID.h的头文件,里面包含一个由26个字母和9个数字随机产生的一串随机数的GUID方法,代码如下:

//GUID.hchar* lr_guid_gen(char* paramName){                         //生成GUID方法
typedef struct _GUID    {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
GUID m_guid;
char buf[50];
char pNameStr[50];
CoCreateGuid(&m_guid);
// 定义输出格式
sprintf (buf, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", // 大写
// sprintf (buf, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",// 小写
//sprintf (buf, "%08lX%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",// 小写
m_guid.Data1, m_guid.Data2, m_guid.Data3,
m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],
m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);
lr_save_string(buf, paramName);
sprintf(pNameStr,"{%s}",paramName);
return lr_eval_string(pNameStr);
}

步骤二:然后再编写一个头文件verify.h,里面包含一个获取上面生成随机字符串的验证码,比如下面代码(获取上述字符串的第5位开始截取六个长度的验证码)

//verify.h  验证码头文件#define VALIDATESTART5//default 5
#define VALIDATENUM6//default 6//!!!!!warn: must free the return point in your own program, or it will leak memory
char* GetValidate(char *str)
{
// init some var
char *pSrc = str;  
char *pDst = NULL;
char *pHeader = NULL;
int cnt = 0; //the current num of character in the pHeaderif (pSrc == NULL) //chech the string is validate or not 
{
return NULL;
}
pDst = (char *)malloc(sizeof(char)*(VALIDATENUM + 1)); //malloc dynamic memory
pHeader= pDst;//record the head addr
pSrc = pSrc + (VALIDATESTART - 1);//find the start pos
while (*pSrc != '\0' && cnt != VALIDATENUM) 
{
if ( *pSrc != '-')
{
*pDst++ = *pSrc;
cnt++;
}
pSrc++;
}
*pDst = '\0';//add the last end character '\0'
return pHeader;
}

步骤三:将两个头文件加入globals.h里,我们就可以调用这两个函数了,不如在action调用,可以再脚本前面加上如下代码:

   char *test;char *test1;lr_load_dll("ole32.dll");      //引用windows生成GUID的APItest=lr_guid_gen("GUID");      //调用上面lr_guid_gen()方法lr_save_string(test,"GUID");lr_output_message(test);lr_output_message("xxxxxxxxxxxxx:%s",lr_eval_string("{GUID}"));    //生成随机字符串test1=GetValidate(test);         //获取验证码lr_save_string(test1,"ID");lr_output_message("%s",lr_eval_string("{ID}"));

这样就算完成了,记得加入一句获取验证码图片的脚本哦!

方法b)示例:

代码如下:

Action(){  int flen;    //定义一个整型变量保存获得文件的大小long filedes;    //保存文件句柄char file[256]="D:\\test1.png";    //保存文件路径及文件名char result[5];   //存放验证码的,必须大于验证码的位数web_set_max_html_param_len("20000");     //设置参数的最大长度,注意该值必须大于文件的大小web_url("login", 
"URL=http://X.X.X.X/Kindergarten/login/login", 
"Resource=0", 
"RecContentType=text/html", 
"Referer=", 
"Snapshot=t1.inf", 
"Mode=HTTP", 
LAST);  //使用关联函数获取下载文件的内容,在这里不定义左右边界,获得服务器响应的所有内容
web_reg_save_param("pic","LB=","RB=","SEARCH=BODY",LAST);//发送下载验证码的请求
web_url("voliCode", 
"URL=http://X.X.X.X/Kindergarten/login/voliCode?d=1446432884699", 
"Resource=0", 
"RecContentType=text/html", 
"Referer=", 
"Snapshot=t1.inf", 
"Mode=HTTP", 
LAST); flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE);   //获取响应中的文件长度if(flen > 0) {//以写方式打开文件if((filedes = fopen(file, "wb")) == NULL){lr_output_message("打开文件失败!");return -1;}fwrite(lr_eval_string("{pic}"), flen, 1, filedes);   //写入文件内容fclose(filedes);    //关闭文件}system("D:\\test.bat");if((filedes=fopen("D:\\test.txt","rt"))== NULL){lr_output_message("打开test.txt文件失败!");return -1;}  fread(result,4,1,filedes);fclose(filedes);  lr_output_message("the velue3 is: %s",result); 
lr_save_string(result,"check");
lr_output_message("the check is %s",lr_eval_string("{check}"));lr_start_transaction("登录");web_submit_data("userLogin", 
"Action=http://X.X.X.X/Kindergarten/login/userLogin", 
"Method=POST", 
"RecContentType=text/html", 
"Referer=http://X.X.X.X/Kindergarten/login/login", 
"Snapshot=t13.inf", 
"Mode=HTTP", 
ITEMDATA, 
"Name=username", "Value=17715290001", ENDITEM, 
"Name=password", "Value=123456", ENDITEM, 
"Name=code", "Value={check}", ENDITEM, 
LAST); 
lr_end_transaction("登录",LR_AUTO);//验证登录是否成功:登录进去后再提交一次数据交互的请求
lr_start_transaction("修改密码");web_submit_data("changePwd", 
"Action=http://X.X.X.X/Kindergarten/sys/changePwd", 
"Method=POST", 
"RecContentType=application/json", 
"Referer=http://X.X.X.X/Kindergarten/sys/changePwdView", 
"Snapshot=t53.inf", 
"Mode=HTTP", 
ITEMDATA, 
"Name=oPwd", "Value=123456", ENDITEM, 
"Name=nPwd", "Value=qwaszx", ENDITEM, 
"Name=nPwd2", "Value=qwaszx", ENDITEM, 
LAST);lr_end_transaction("修改密码",LR_AUTO);return 0;}

备注:

1、char result[5];这个是定义存放验证码的,必须大于验证码的位数,否则最后文件读出来的验证码后面会自动加入几个乱码字符;

2、 system("D:\\test.bat");  执行test.bat,注意D盘和test.bat之间是\\,盘符要转义;  test.bat内容如下:

    D:\InstallSoftware\Tesseract-OCR\tesseract.exe d:\test1.png d:\test -1   (tesseract.exe必须安装目录也写进去)

3、我测试的系统登录的url是 http://X.X.X.X/Kindergarten/login/login, 如果直接获取该网址的文件来获取验证码,文件太大,会失败;可以用火狐浏览器打开该网址,然后选中验证码,右键直接查看获取验证码的url,即:http://X.X.X.X/Kindergarten/login/voliCode?d=1446432884699; 然后再使用关联函数 web_reg_save_param获取 该url的下载内容;

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/611133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【hcie-cloud】【21】容器详解【容器网络说明、容器存储说明、容器镜像说明、dockerfile详述、缩略词】【下】

文章目录 容器介绍,容器工作机制、容器常用命令说明容器网络容器网络简介容器常用网络类型 - Bridge容器常用网络类型 - Host容器常用网络类型 - None其他容器网络类型【Macvlan、Overlay、IPvlan】容器网络相关配置 容器存储容器中应用数据的存储容器持久化存储配置…

2024.1.8每日一题

LeetCode 回旋镖的数量 447. 回旋镖的数量 - 力扣(LeetCode) 题目描述 给定平面上 n 对 互不相同 的点 points ,其中 points[i] [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的距离和 i 和 k 之间的欧式…

Python - 深夜数据结构与算法之 Two-Ended BFS

目录 一.引言 二.双向 BFS 简介 1.双向遍历示例 2.搜索模版回顾 三.经典算法实战 1.Word-Ladder [127] 2.Min-Gen-Mutation [433] 四.总结 一.引言 DFS、BFS 是常见的初级搜索方式,为了提高搜索效率,衍生了剪枝、双向 BFS 以及 A* 即启发式搜索…

【办公技巧】Word中如何对齐选择题中的ABCD选项?

使用word文件制作试卷,如何将ABCD选项全部设置对齐?除了一直按空格或者Tab键以外,还有其他方法吗?今天分享如何将ABCD选项对齐。 首先,我们打开【替换和查找】,在查找内容输入空格,然后点击全部…

2024年工信部AI人工智能证书“计算机视觉工程师”证书报考中!

为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署求,深入实施人才强国战略和创新驱动发展战略,加强全国数字化人才队伍建设,持续推进人工智能专业人员能…

视频做成二维码查看?多格式视频二维码生成器的使用方法

现在音视频是工作和生活中经常需要使用的一种内容表现形式,很多人都通过这种方式来查看视频内容,比如产品介绍、使用说明、安装教程等。通过一个二维码就可以来承载视频内容,与传统的方式相比拥有更快的内容传播速度,简化用户获取…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷⑧

2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷8 目录 需要竞赛软件包环境以及备赛资源可私信博主!!! 2023年全国职业院校技能大赛(高职组) “云计算应用”赛项赛卷8 模块一 …

创业只有破釜沉舟才能成功吗?2024个人创业做什么?2024普通人如何创业?

第一次创业必须零成本,千万别被那些砸锅卖铁、卖车卖房创业最后发了大财的鸡汤故事洗了脑,否则你一定会血本无归,妻离子散。 如果你要创业,请记住这组数据,全国能活过三年的创业公司只有10%,这10%不等于已经…

C# 自定义配置文件序列化生成+文件格式错误自动回档

文章目录 前言选择Xml简单的Xml使用测试用例简单的写简单的读简单的生成配置修改配置类测试用例运行结果对比 代码逻辑封装逻辑示意封装好的代码测试生成配置文件格式错误测试使用默认值覆盖来解决问题 配置文件人为修改错误如何解决解决方案代码测试用例运行结果 代码封装总结…

uni-app实现一键登录(企业版:因为获取手机号功能**目前针对非个人开发者**,所以个人开发者无法唤起获取手机号界面)

微信授权登录 用户在使用小程序时,其实已登录微信,其本质上就是:微信授权给小程序读取微信用户信息。 获取登录凭证(企业版) 前端:调用 wx.login() 接口获取登录凭证(code)。 后…

数据结构期末复习笔记

文章目录 数据结构期末复习第一章:数据结构绪论第二章:顺序表与单链表第三章:其它链表第四章:栈如何中缀转后缀后缀如何计算 第五章:队列第六章:串第七章:树的概念和遍历第八章:赫夫…

muduo网络库剖析——网络地址InetAddress类

muduo网络库剖析——网络地址InetAddress类 前情从muduo到my_muduo 概要socketaddr_in介绍成员用法 网络地址转换函数 框架与细节成员函数使用方法 源码结尾 前情 从muduo到my_muduo 作为一个宏大的、功能健全的muduo库,考虑的肯定是众多情况是否可以高效满足&…

在矩池云使用微调ChatGLM3-6B教程

今天给大家介绍下如何在矩池云使用ChatGLM3-6B模型。 1 简介 GitHub:https://github.com/THUDM/ChatGLM3 魔搭:https://modelscope.cn/models/ZhipuAI/chatglm3-6b/ ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的新一代对话预训练模型。ChatGLM3…

租房别再傻傻的扯网线了!随身WiFi靠谱品牌推荐,哪个随身WiFi最好用

如果你是租房党,并且预算有限的话,拉网线太麻烦了,价格很贵,需要搬家的时候还要重新扯线,事儿很多。想买一个网速快,便捷的随身WiFi看电影、刷刷抖音、打打游戏,那一定一定要认真看完我这篇文章…

metrics安装异常原因【doesn‘t contain any IP SANs】

1、问题背景 安装好k8s后,安装metrics-server后发现对应的pod一直无法启动。 apiVersion: v1 kind: ServiceAccount metadata:labels:k8s-app: metrics-servername: metrics-servernamespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Cl…

Jasper report InputStream动态生产Logo

第一步,新建一个Parameter 新建一个对象Parameter,类型为java.io.InputStream 第二步,拖拽Image对象 拖拽Image对象,并调整长宽,Image下选择Expression $P{Logo_Blue} 第三步,把图片转换成stream rptHea…

numpy100练习题,包含相应使用函数解释

取自github开源项目:numpy100题 文章目录 1. 导入numpy库并简写为 np (★☆☆)2. 打印numpy的版本和配置说明 (★☆☆)3. 创建一个长度为10的空向量 (★☆☆)4. 如何找到任何一个数组的内存大小? (★☆☆)5. 如何从命令行得到numpy中add函数的说明文档?…

D41|打家劫舍

198.打家劫舍 初始思路&&题解复盘: 确定dp数组(dp table)以及下标的含义 dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。 2.确定递推公式 决定dp[i]的因素就是第i房…

Unity 实用方法 合集

Unity 实用方法 合集 Unity 打字机效果2D 坐标旋转计算球面坐标求值平滑移动鼠标位置获取2D屏幕坐标转世界坐标物体朝向目标多物体中心点生成本地图片加载画面线框显示画面线框显示 搭载效果 贝塞尔曲线绘制贝塞尔曲线绘制 搭载效果 网格弯曲网格弯曲 搭载效果 Delaunay 模型生…

安泰ATA-4014高压功率放大器在传感器脉冲涡流检测中的应用

传感器在工程领域起着至关重要的作用,能够实时获取各种物理量的信息。而功率放大器作为传感器信号处理的重要组成部分,广泛应用于各种测量和控制系统中。本文将探讨功率放大器在这一领域的重要性和作用。 首先,了解传感器脉冲涡流检测的基本原…