jmeter使用Beanshell处理验证码
在接口测试、自动化测试工作中,你一定会遇到验证码处理的问题,很多初入测试、甚至测试老鸟的处理方式都比较粗暴,要么找开发设置为万能验证码或者直接测试环境取消验证码,说实话这种方式也非常实用,毕竟验证码不是我们项目核心,手工测试一下就可以了,何必自动化实现呢?
今天给大家介绍一种Jmeter接口测试时对验证码自动识别的方式,先说在前头,该方式对于背景干扰的图片识别率还是有点低,但是对于纯色底纹的识别率基本100%,请择情使用。
主要思路步骤如下:
1、通过接口获取验证码
2、验证码处理脚本
3、jmeter中配置验证码处理脚本
4、识别验证码
一、验证码接口案例介绍
在我们项目的登录模块中就带有验证码,我们就以这个接口为例讲解。
我们可以在jmeter中实现这个接口,步骤如下。
1、启动jemter
2、创建线程组->http采样器、debug采样器,http采样器设置如下
3、添加监听器->HTTP采样器->保存结果到文件,配置如下,几个选项都不勾选,默认文件名为1.png
4、添加监听器->查看结果树,保存、运行脚本。
二、验证码处理代码
现在验证码文件已经保存在本地了,需要将其读取为base64加密格式,然后才能进行后续的验证码识别。
下面我们将使用java,编写图片文件处理的文件,实现将base64加密的数据转文图片文件,也可以将图片文件处理为base64加密文件,并将其导出为jar包备用。
1、eclipse创建java工程
2、导入sun.misc.BASE64Decoder.jar包,需自行下载
创建文件夹lib
复制sun.misc.BASE64Decoder.jar包到lib文件夹下
选择sun.misc.BASE64Decoder.jar,右键build path->add build path
3、创建包、java文件,目录结构如下
4、java文件ToImage内容如下,如果文件名或者类名不同,需要调试代码,注意事项。
声明类一定为public,否则jmeter调用会出现找不到类的问题
main方法为调试代码,导出包之前可以注释掉
package com.qf;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;
public class ToImage {
public static void main(String[] args){
// String base64Str = "iVBORw0KGgoAAAANSUhEUgAAAKAAAAA8CAIAAABuCSZCAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAOq0lEQ·········
// boolean b=false;
// try {
// b = GenerateImage(base64Str, "D:/gg.jpg");
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println(b);
String aa = GetImageStr("E:/3-Learning/Deep-Learning-master/imageVerydow/1.png");
System.out.println(aa);
}
/**
* 图片转化成base64字符串
* @param imgPath
* @return
*/
public static String GetImageStr(String imgPath) {// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
String imgFile = imgPath;// 待处理的图片
InputStream in = null;
byte[] data = null;
String encode = null; // 返回Base64编码过的字节数组字符串
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
try {
// 读取图片字节数组
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
encode = encoder.encode(data);
//加密代码后的字符串会自动化换行,通过该句取消掉换行
encode = encode.replaceAll("\r\n", "");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return encode;
}
/**
* base64字符串转化成图片
*
* @param imgData
* 图片编码
* @param imgFilePath,存放到本地路径
* @return
* @throws IOException
*/
@SuppressWarnings("finally")
public static boolean GenerateImage(String imgData, String imgFilePath) throws IOException { // 对字节数组字符串进行Base64解码并生成图片
if (imgData == null) // 图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
OutputStream out = null;
try {
out = new FileOutputStream(imgFilePath);
// Base64解码
byte[] b = decoder.decodeBuffer(imgData);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
out.write(b);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
out.flush();
out.close();
return true;
}
}
}
5、导出jar包
代码调试通过后,导出该工程jar包备用(jmeter中Beanshell处理器可以导入jar包并使用其功能)。
选中工程名->export->jar file->配置导出的jar选项,如图设置,点击Finish完成导出。
至此,我们就拥有了一个ToImage.jar的文件,该文件提供两个方法:
GetImageStr:图片转化成base64字符串
GenerateImage:base64字符串转化成图片
三、Jmeter实现验证码识别
实现验证码识别,需要借助OCR(Optical Character Recognition,光学字符识别)插件,我们可以通过gitee下载一个,当然可以自己实现识别代码。
我们采用gitee上的开源的jmeter-captcha识别码插件,可以下载其jar包直接使用,也可以下载源码包二次开发。作者建议二次开发,因为不同验证码的底纹干扰不同,处理方式也不太一样,如果是打包的jar包,识别率就会收到影响。
本文采用jar包直接演示,如需要可以直接找作者索要,源码见gitee。
https://gitee.com/changpei12315/jmeter-captcha
1、下载jmeter-captcha,并配置到到{JMEMTER_HOME}/lib/ext/下
https://gitee.com/hyj-jmeter/jmeter-captcha/releases
2、下载tessdata语言包,为空默认在{JMEMTER_HOME}/lib/tessdata下
https://gitee.com/changpei12315/tessdata_fast
将下载的tessdata_fast中的文件复制到tessdata中即可。
3、jmeter中测试计划设置
添加ToImage.jar包
添加sun.misc.BASE64Decoder.jar包
定义一个变量code,用于中转存储验证码数据
4、jmeter采样器后置处理设置
线程组->后置处理器->Beanshell后置处理器,并设置如下:
import com.qf.ToImage;
//先将图像文件读入到此处,转为base64
String aaa = ToImage.GetImageStr("E:/1.png");
System.out.println(aaa);
//使用put方法将加密的图片数据输出到code变量(测试计划中定义)中
vars.put("code",aaa);
线程组->后置处理器->验证码识别插件(完成前两步才有),配置如下:
5、运行查看结果
其实本案例中的验证码的识别率很低,需要调整ocr对图片的灰度、干扰线等代码优化。
四、其他简单验证码的识别
如果验证码图片比较简单,没有复杂底纹和干扰的话,识别率还是挺高的。
1、白底纯数字的验证码识别
验证码识别插件设置语言为:eng
Beanshell后置处理器设置读入文件为:E:/sz.png
3、白底纯字母的验证码识别
验证码识别插件设置语言为:eng
Beanshell后置处理器设置读入文件为:E:/zm.png
4、白底纯汉字的验证码识别
验证码识别插件设置语言为:chi_sim
Beanshell后置处理器设置读入文件为:E:/hz.png
五、总结
后续持续更新一篇对干扰优化的文章,可以替换掉现有的jmeter-captcha.jar包。
以及一篇深度学习的文章,通过学习算法训练学习,可以有效提升识别准确率。欢迎大家的持续关注和点赞。
更多关于软件测试培训的问题,欢迎咨询千锋教育在线名师,如果想要了解我们的师资、课程、项目实操的话可以点击咨询课程顾问,获取试听资格来试听我们的课程,在线零距离接触千锋教育大咖名师,让你轻松从入门到精通。