jmeter http接口测试怎么测试有验证码的接口

注册登录_登陆接口文档
请求地址:&POST & xxxxxx
请求参数:
LoginName:"mtest",
// 登录名,可以为用户名或邮箱
Password:"123456"
响应数据:成功
"State": 0,
"Msg": "登陆成功",
"Session": "xDfWVWc1oHQvIEHFtuknjSMl1eWLA0SEy3afxxI3+guZM3ErKonSOWGxWdliPkR4BLo1WmUwOMaEuOc8pnsemhcfosXKNFHeig8jTl+BIQvjWWOQcNWG3rAT5Nyg5ke90+85jM8HfPfQcChJlxZoqqu0jrzoN2FjyMZLSwnAu+TIyobXDj20/ap7JOEfWVj9QWHrBI+H37Cbl2OHgdcJ38kIBjWZtzSUjezYIk78wSNDE8Z6JiNYWsWxqMVY",
// 加密后的字符串,登陆成功后每次都要传回此值
"UserInfo": {
// 用户信息
"Id": 246565,
"Code": "687f722b-9c29-4df9-b52a-34de",
// 客户代码
"LoginName": "mtest",
"FullName": " ",
"NickName": "",
"Email": "",
"AuthEmail": true,
// 是否验证邮箱
"Mobile": "",
// 手机号码
"AuthMobile": true,
// 是否验证手机
"IsActive": 1,
// 是否可用
"CreateTime": " 14:23:00",
// 创建时间
"LoginCount": 134,
// 登录次数
"LastLoginTime": " 11:11:18",
// 最后登录时间
"PreviousTime": " 10:25:41",
// 上次登录时间
"RegisteredSource": 0,
// 注册来源:0主站,1新浪,2QQ
"RegisteredSourceKey": "",
// 来源Key
"SafeLevel": 1,
// 会员安全等级
"IsLock": false,
// 是否被锁定
"IP": null,
// 客户端IP
"WeiXinRegisteredSourceKey": "",
// 微信注册来源KEY,即open id;为了区分原来存在的RegisteredSource(此字段不能同时存在多个第三方并存)
"BigRegisteredSource": 0,
// 大类注册来源(0:PC端,2:H5直接注册,21:H5微信注册, 30 :android直接注册, 40 :IOS直接注册)
"HasPassword":true
// 账户是否已设定密码
"State":9999,
"Msg":"登录失败",
// 错误提示信息
"Data":null
// 没有额外数据返回
1.用jemter做接口
1.我们先建立一个线程组
2.我们要设置一个http,发送http默认请求值,放入你需求测试的地址
3.在建立一个http请求
4.添加监控器,主要是监控结果,查看结果树
5.查看请求,发现请求是成功了的,但是响应数据是错误,登录失败了,因为请求失败以后的数据是以下的数据
"State":9999,
"Msg":"登录失败",
// 错误提示信息
"Data":null
// 没有额外数据返回
至于为什么,是因为登录需要加密的key,有一个加密的算法,那如果这样,就只能用java来手写这个接口了,就在下次共享出来吧
阅读(...) 评论()下次自动登录
现在的位置:
& 综合 & 正文
用Jmeter做接口测试
最近做,服务层的代码先是用junit写,因为项目时间紧,加上流程经常变化,代码写的很粗糙,需要不停的准备不同的测试数据,不能进行自动化的执行,一个方面是流程确实需要不同的测试数据,另外一个方面是,测试代码中没有对测试数据进行处理,所以会造成这样的情况,不过为了测试流程的正常性,这些进行测试也是可以的。
在开发代码都稳定后,是用这样的测试方法肯定是不行的,也考虑过重构单元测试代码,但是因为项目调用到好几个服务,但是只有三个入口,而测试的主要目的是进行接口测试,单元测试只是辅助开发进行测试,所以如何进行更优化的接口测试是主要的。
因为对熟悉,再加上之前是用Jmeter做过HTTP协议的接口测试,所以考虑用jmeter来做接口测试,主要是使用Jmeter的请求,编写相应的测试代码,在jmeter的代码中,调用入口方法,而方法需要的参数通过java请求的参数传递,这样可以使用参数化对传递的参数进行参数化,为了快速查找问题,在代码中,使用Jmeter提供的方法设置了请求的数据以及相应的数据,而为了验证测试结果是否通过,在代码中取得发放返回值,然后和期望值进行比较,如果一致,则测试结果为真,否则为测试失败。
当然仅仅是在代码中对方法返回结果进行比较还不够,还需要到去验证相应的数据是否存在,是否修改,这就用到了jmeter的beenshell断言,另外,因为测试结果也会在页面中体现,所以也增加了http请求,设置断言,断言web页面的值和期望一致。
通过以上方法,可以实现使用Jmeter进行接口测试,然后通过和ANT集成,每次在修改底层代码后,跑一遍测试脚本,基本上可以确认是否存在问题。
另外使用jmeter准备的测试脚本,可以用来做,或者用来准备数据也是非常的方便!
以上只是对流程进行描述,没有相应的代码,看的也学会云里雾里,后面会把代码贴上来!
&&&&推荐文章:
【上篇】【下篇】在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
这也看不出QPS啊
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
QPS = req/sec = 请求数/秒 是不是Thoughput那列
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:> 博客详情
摘要: 最近做的项目需要测试很多接口,上网查一查,发现完整讲述接口测试的资料太少,所以最近自己做完这个项目,把测试的东西整理一下和大家分享一下,希望对看到的人有所帮助
&&&&一、测试需求描述
& &1、 本次测试的接口为http服务端接口
& &2、 接口的主要分成两类,一类提供给查询功能接口,一类提供保存数据功能接口,这里我们举例2个保存数据的接口,因为这两个接口有关联性,比较有代表性;
& & 3、接口描述:
&&&&&&&&保存信用卡账户信息接口:
&&&&&&&&& & 传入参数:& &
&&&&&&&&& & & & args={
&&&&&&&&& & & & & & "clientNo":"",
&&&&&&&&& & & & & & "alias": "**信用卡2",
&&&&&&&&& & & & & & "cardName": "长城*****卡2",
&&&&&&&&& & & & & & &"cardNo": "51",
&&&&&&&&& & & & & & }
&&&&&&&&& & 传出参数:
&&&&&&&&& & & & & & 保存成功:{"returnCode":"0","returnMsg":"保存成功"}
&&&&&&&&& & & & & & 保存失败:{"returnCode":"1","returnMsg":"保存失败"}
&&&&&&&&& & 保存逻辑:数据传入进来,验证通过,保存到信用卡账户表中
&&&&&&&&保存信用卡账单接口:
&&&&&&&&& & 传入参数:
&&&&&&&&& & & & args={
&&&&&&&&& & & & & & "clientNo":"",
&&&&&&&&& & & & & & "accountName": "测试",
&&&&&&&&& & & & & & "billDate": "08",
&&&&&&&&& & & & & & "billMonth": "201509",
&&&&&&&&& & & & & & &"cardNo": "51",
&&&&&&&&& & & & & & "currentPayment": "欠款459.80",
&&&&&&&&& & & & & & "paymentDate": " 09:00:00",&
&&&&&&&&& & & & & & }
&&&&&&&&& & 传出参数:&
&&&&&&&&& & & & & & 保存成功:{"returnCode":"0","returnMsg":"保存成功"}
&&&&&&&&& & & & & & 保存失败:{"returnCode":"1","returnMsg":"保存失败"}
& & & & &&&&&&&&&&&&&保存逻辑:保存时先去信用卡信息表查看clientNo对应的表是否存在,如存在则数据校验通过,
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&将数据保存进入信用卡账单表
注:这个保存逻辑在接口开发设计文档中可能没有写或写的不详细,这时要与开发接口人员或产品人员多多沟通去熟悉接口逻辑
二、测试分析
&&&&1、逻辑分析
& & & & 1)、从保存逻辑上来看,这两个接口明显是有依赖关系的,所以我们先测试信用卡账户信息接口,再测试保存信用卡账单接口
&&&&&&&&2)、接口传入的数据,最终是保存到数据库中,所以当接口返回保存成功的时候,我们也要去对应的数据库表中核对相应的数据(这里可以用jmeter链接数据库进行操作代理手工)
& & & & 3)、当出现保存失败的情况时,我们需要查看系统的日志,所以我们也要准备好查看日志的权限和地址
&&&&2、测试工具的准备
& & & & 1)、单个接口测试,我们使用火狐的插件poster
& & & & 2)、多个接口测试,我们使用Jmeter进行测试
三、使用工具测试
&&&&1、Poster工具的使用方法见
& & & & & &&
&&&&2、使用Jmeter对接口测试
& & & & & & 首先我们说一下为什么用Poster测试后我们还要用Jmeter做接口测试,在用poster测试时候会发现的是一个接口一个接口的测试,我们每次测试成功后的数据,在工具中是无法保存的,再次测试的时候我们还要重新输入测试的数据,当我们测试一个接口的时候可能感觉不明显,但是当你测试几十个接口的时候,你就会发现使用Jmeter的好处,如果按测试阶段来说冒烟测试我们用poster,集成测试我们用Jmeter
四、使用Jmeter接口测试
&&&&&&&&1、首先邮件添加一个线程组,这里我们重命名InterfaceTest
&&&&&&&&2、在线程组上添加一个Http默认请求,并配置服务器的IP地址和传输编码
&&&&&&&&3、在线程组中添加一个HTTP请求,这里我们重命名“增加信用卡账户信息接口”
&&&&&&&&&&&&
&&&&&&&&4、配置接口请求信息,这配置示例如下:
&&&&&&&&5,在保存信用卡账单接口请求,示例如下:
&&&&&&&&& &&
&&&&&&&&注:由于Jmeter请求线程组内的请求时从第一个开始执行,所以我们将需要最先执行的请求放在前面
&&&&&&&&6、在线程组上添加监听器,察看结果树和聚合报告
&&&&&&&&7、点击启动,运行结束后查看,结果树和聚合报告
&&&&&&&&8、去数据库中核对数据
&&&&&&&&9、大批量数据制造
&&&&&&&&& & 思路:
&&&&&&&&1)、可参数化的参数,保存信用卡账户信息接口(clientNo,cardNo),保存信用卡账单接口(clientNo,cardNo,billMonth,paymentDate)
&&&&&&&&2)、两个接口的依赖关系,保存信用卡账单接口(clientNo,cardNo)要和信用卡账户信息接口(clientNo,cardNo)的两个相同,也就是说这两个要用一个参数,且还不能重复
&&&&&&&&根据上面两个特点,(clientNo,cardNo)我们选取使用计数器,每循环一次计数器加1,那么我们将线程组设置循环执行1万次;billMonth,paymentDate,这两个日期我们是使用随机函数${__Random(1,9,)},将月份参数化;
&&&&&&&&3)、在线程组上创建计数器,配置如下:
&&&&&&&&4)、引用计数器和随机函数
&&&&&&&&信用卡账户接口传入参数
&&&&&&&&& & & & args={
&&&&&&&&& & & & & & "clientNo":"${add}",
&&&&&&&&& & & & & & "alias": "**信用卡2",
&&&&&&&&& & & & & & "cardName": "长城*****卡2",
&&&&&&&&& & & & & & &"cardNo": "${add}51",
&&&&&&&&& & & & & & }
&&&&&&&&账单接口传入参数
&&&&&&&&args={
&&&&&&&&& & & & & & "clientNo":"${add}",
&&&&&&&&& & & & & & "accountName": "测试",
&&&&&&&&& & & & & & "billDate": "08",
&&&&&&&&& & & & & & "billMonth": "20150${__Random(1,9,)}",
&&&&&&&&& & & & & & &"cardNo": "${add}51",
&&&&&&&&& & & & & & "currentPayment": "欠款459.80",
&&&&&&&&& & & & & & "paymentDate": "2015-0${__Random(1,9,)}-25 09:00:00",&
&&&&&&&&& & & & & & }
&&&&&&&&<span style="color:#)、设置线程组循环测试,点击运行,查看运行结果,再去数据库看看,大批量数据就这样产生了
欢迎大家关注微信公众号与QQ群进行交流
有socket压力测试方案吗?可以分享一下吗
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥如何为Apache JMeter开发插件(三)——冲破图片验证码的束缚
我们在性能测试中总会时不时地遭遇到来自于应用系统的各种阻碍,图片验证码就是一类最常见的束缚,登录或交易时需要按照图片中的内容输入正确的验证信息后,数据才可以提交成功,这使得许多性能测试工具只能望而却步。网上也出现了一些LoadRunner的解决方案,但结合LoadRunner对于C脚本内存控制和识别成功率低下等诸多问题,这些方案没有什么实际用途。然而,为JMeter开发插件却给我们提供了一条可行的道路来冲破图片验证码的束缚!
选择一个理想的第三方图形图像识别工具
在此我们首先需要一个比较理想的图形图像识别工具来完成将验证码中的图形图像文字识别转换为文本文字主体识别工作,在此我们选择Tesseract, Tesseract是一个开源的OCR(Optical Character Recognition,光学字符识别)引擎,可以识别多种格式的图像文件并将其转换成文本,发布在Googel Project上,地址为(但Googel Project停止维护后不知道现在在哪里维护)。
一组用于验证码识别的JMeter插件
我们常见的验证码图片样本如下:
当你遇到这样的验证码时,首先你要做的就是降噪,将背景的一些干扰我们识别文本内容的线条过滤掉,人眼需要降噪,识别软件在进行识别前也需要帮助其进行降噪来加大识别成功率,通常降噪的方案是对图片像素点进行逐个扫描,通过创建降噪规则对背景噪音进行过滤,如上面的样本,我们可以建立如下降噪规则和方法:
public static int isFilter(int colorInt) {
Color color = new Color(colorInt);
if ((color.getRed() & 85 && color.getRed() & 255)
&& (color.getGreen() & 85 && color.getGreen() & 255)
&& (color.getBlue() & 85 && color.getBlue() & 255)) {
public static BufferedImage removeBackgroud(BufferedImage img)
throws Exception {
int width = img.getWidth();
int height = img.getHeight();
for (int x = 0; x & ++x) {
for (int y = 0; y & ++y) {
if (isFilter(img.getRGB(x, y)) == 1) {
img.setRGB(x, y, Color.WHITE.getRGB());
将图片文件转换为BufferedImage对象进行去背景降噪,通过调用removeBackgroud方法,我们降噪后的图片如下:
可以看到效果非常明显,但降噪也有它的局限性,比如会把一些需要正常显示的图形文字过滤掉一部分,诸如此类问题我们会在后面的介绍中通过其他方式解决,但对于图形图像识别软件的输入来说,必须对其加以降噪才能保证读取正确率。
2. 识别插件(第一个Extractor插件)
我们在最初的章节介绍了Extractor的基本实现方法,在此我们还是简单回顾一下后置处理器的一些功能,下图显示了JMeter为我们默认提供的后置处理器:
所谓后置处理器是相对Sampler的后置,主要用于处理Sampler所抽样得到的SamplerResult对象,对SamplerResult做修饰或通过SamplerResult抽取信息,最常使用的是“正则表达式提取器”、“CSS/JQuery Extractor”、“XPath Extractor”,使用它们可以实现性能测试脚本中最重要的“关联”操作。
好了,我们的需求是对验证码进行读取,即通过验证码URL获取到图片资源(这部分由“HTTP请求Sampler”完成),然后提取资源中的图形图像信息作为Tesseract的输入,最后在将Tesseract的输出作为一个JMeter参数数据进行保存。惯例使用分离法,分为逻辑控制部分VcodeExtractor和GUI部分VcodeExtractorGUI,另外,还包括对图片进行处理的ImageIOHelper类以及实现调用Tesseract对验证码信息识别并读取的OCR类。
ImageIOHelper主要包含两大部分,一部分就是前面所介绍的降噪逻辑,另一部分是将图片格式转换为tiff格式以更好地进行识别,这部分的代码参考如下:
public static File createImage(File imageFile, String imageFormat) {
File tempFile = null;
ImageInputStream iis = null;
ImageOutputStream ios = null;
ImageReader reader = null;
ImageWriter writer = null;
Iterator&ImageReader& readers = ImageIO.getImageReadersByFormatName(imageFormat);
reader = readers.next();
iis = ImageIO.createImageInputStream(imageFile);
reader.setInput(iis);
IIOMetadata streamMetadata = reader.getStreamMetadata();
TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);
tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
Iterator&ImageWriter& writers = ImageIO.getImageWritersByFormatName("tiff");
writer = writers.next();
BufferedImage bi = removeBackgroud(reader.read(0));
IIOImage image = new IIOImage(bi,null,reader.getImageMetadata(0));
tempFile = tempImageFile(imageFile);
ios = ImageIO.createImageOutputStream(tempFile);
writer.setOutput(ios);
writer.write(streamMetadata, image, tiffWriteParam);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(iis != null){
iis.close();
} catch (IOException e) {
e.printStackTrace();
if(ios != null){
ios.close();
} catch (IOException e) {
e.printStackTrace();
if(writer != null){
writer.dispose();
if(reader != null){
reader.dispose();
return tempF
private static File tempImageFile(File imageFile) {
String path = imageFile.getPath();
StringBuffer strB = new StringBuffer(path);
return new File(strB.toString().replaceFirst("jpg", "tif"));
OCR类主要是通过Process调用已经安装的Tesseract程序,调用命令基本形式为tesseract xxx.tif 1 -l eng,参考如下代码:
import java.io.BufferedR
import java.io.F
import java.io.FileInputS
import java.io.IOE
import java.io.InputStreamR
import java.util.ArrayL
import java.util.L
public class OCR {
private final String LANG_OPTION = "-l";
private final String EOL = System.getProperty("line.separator");
private String tessPath = "D://Program Files (x86)//Tesseract-OCR";
public String recognizeText(File imageFile,String imageFormat) {
File tempImage = ImageIOHelper.createImage(imageFile,imageFormat);
File outputFile = new File(imageFile.getParentFile(),"output" + imageFile.getName());
StringBuffer sb = new StringBuffer();
List&String& cmd = new ArrayList&String&();
cmd.add(tessPath+"//tesseract");
cmd.add("");
cmd.add(outputFile.getName());
cmd.add(LANG_OPTION);
cmd.add("eng");
ProcessBuilder pb = new ProcessBuilder();
pb.directory(imageFile.getParentFile());
cmd.set(1, tempImage.getName());
pb.command(cmd);
pb.redirectErrorStream(true);
Process process = null;
BufferedReader in = null;
process = pb.start();
wait = process.waitFor();
if(wait == 0){
in = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath()+".txt"),"UTF-8"));
while((str = in.readLine())!=null){
sb.append(str).append(EOL);
in.close();
tempImage.delete();
new File(outputFile.getAbsolutePath()+".txt").delete();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(in != null){
in.close();
} catch (IOException e) {
e.printStackTrace();
tempImage.delete();
return sb.toString();
VcodeExtractor类继承AbstractScopedTestElement抽象类,实现PostProcessor接口的process方法,来处理利用OCR读取验证码信息的逻辑控制,参考代码如下:
import java.io.F
import java.io.FileOutputS
import java.io.IOE
import java.io.S
import org.apache.jmeter.processor.PostP
import org.apache.jmeter.samplers.SampleR
import org.apache.jmeter.testelement.AbstractScopedTestE
import org.apache.jmeter.threads.JMeterC
import org.apache.jmeter.threads.JMeterV
import org.apache.jorphan.logging.LoggingM
import org.apache.log.L
public class VcodeExtractor extends AbstractScopedTestElement implements PostProcessor, Serializable{
private static final Logger log = LoggingManager.getLoggerForClass();
public void process() {
JMeterContext context = getThreadContext();
SampleResult previousResult = context.getPreviousResult();
if (previousResult == null) {
log.debug("VcodeExtractor processing result");
String status = previousResult.getResponseCode();
int id = context.getThreadNum();
String imageName = id + ".jpg";
if(status.equals("200")){
byte[] buffer = previousResult.getResponseData();
FileOutputStream out = null;
File file = null;
file = new File(imageName);
out = new FileOutputStream(file);
out.write(buffer);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(out != null){
out.close();
} catch (IOException e) {
e.printStackTrace();
String vcode = new OCR().recognizeText(file, "jpg");
vcode = vcode.replace(" ", "").trim();
JMeterVariables var = context.getVariables();
var.put("vcode", vcode);
var.put("vuser", String.valueOf(id));
} catch (Exception e) {
e.printStackTrace();
代码逻辑非常简洁,即通过getThreadContext()方法获取当前线程(vuser)的上下文,从而从上下文中获取到前一个Sampler所抽样的结果,为保证结果不为空我们做了一个简单的处理,也可以添加一些更为精细的控制,如下代码:
if(context.getPreviousSampler() instanceof HTTPSampler){
判断前一个Sampler是否为HTTPSampler,以限定有效使用范围。
将previousResult.getResponseData()保存为文件后,通过前面我们创建的OCR完成识别任务后,将识别结果通过JMeterVariables对象保存下来,在此我们分别建立了两个参数”vcode”和”vuser”,后面我们可以用它们进行测试。
该版本的VcodeExtractorGUI类只是单纯实现一个可视化的界面用于在测试计划Tree中进行操作:
import org.apache.jmeter.processor.gui.AbstractPostProcessorG
import org.apache.jmeter.testelement.TestE
public class VcodeExtractorGUI extends AbstractPostProcessorGui{
public TestElement createTestElement() {
VcodeExtractor extractor = new VcodeExtractor();
modifyTestElement(extractor);
public String getLabelResource() {
return this.getClass().getName();
public String getStaticLabel() {
return "VcodeExtractor";
public void modifyTestElement(TestElement extractor) {
super.configureTestElement(extractor);
将插件打包插入JMeter框架,可以在后置处理器列表中查看到VcodeExtractor组件:
建立测试计划,看看我们的插件对图片验证码的识别情况如何:
测试中,我们设置了5个线程(vuser),可以看到已经成功识别验证码数字,并把他们保存到了对应的vcode参数,但这样就够了吗?显然还差得远,有时你会发现识别结果是这样的:
这意味着识别存在错误!
3. 提高识别成功率
识别成功率是成败的关键,提升成功率可以采取以下方案:
训练Tesseract
提供大量样本来训练Tesseract对特定图形的识别成功率。
修正错误的识别结果
有些识别错误是这样的,如:
将J识别为[,将M识别为|\/|,将N识别为||,这种识别错误是机器识别离散一些的像素点产生的,人眼是可以修正的,因此,我们可以建立映射表方式将错误字符进行修正。
避免混淆形状接近的图形字符
有些识别错误是这样的,如:
将5识别为S,将1识别为I,将0识别为O,这种识别错误是纯的图形混淆产生的,人眼也可能犯此类错误,我们管它叫“看不清”。
4. 看不清,换一张(第一个Controller插件)
“看不清,换一张”无论对人眼或机器识别都是一种弥补方案,我们对于“看不清”的字符需要模拟换一张重新识别的操作,这里我们引入一个新的插件Controller(逻辑控制器),照例我们先来回顾一下该插件的一些功能,下图显示了JMeter为我们默认提供的逻辑控制器:
前面的章节曾经介绍过所谓逻辑控制器主要就是用来控制线程行为的,当然也包括一些用于划分Sampler或功能边界的控制器如事务控制器和录制控制器,主要是依靠一些限定的条件或阈值的判断,按想要的方式控制总体线程或单独线程行为。
好了,我们的需求很明确“看不清,换一张”,在此可以完全照搬循环控制器的源代码,参考LoopController类和LoopControlPanel类,只需要对LoopController在每次循环结束后判断是否退出的函数中增加我们对于图片是否看清的逻辑,代码如下:
private final static String PATTERN = "34789ABCEFHKLPRTUVWXY"
private boolean isVerify(String vcode){
int length = vcode.length();
if(length != 4){
return false;
for(int i = 0; i & i++){
if(PATTERN.indexOf(vcode.toCharArray()[i]) & 0){
return false;
return true;
public Sampler next() {
JMeterContext context = getThreadContext();
JMeterVariables var = context.getVariables();
String vcode = var.get("vcode");
if(vcode != null){
if(isVerify(vcode)){
setDone(true);
return null;
if(endOfLoop()) {
if (!getContinueForever()) {
setDone(true);
return null;
return super.next();
如果通过isVerify函数校验(看得清楚)就直接退出循环,否则(看不清楚)就接着重新请求图片验证码进行校验(换一张),创建此逻辑控制器VcodeVerifyController。
将插件打包插入JMeter框架,可以在逻辑控制器列表中查看到VcodeVerifyController组件:
一个完整的登录测试计划
这是一个标准的登录测试计划,所有要素一应俱全,HTTP Cookie管理器负责保持会话状态,CSS/JQuery Extractor负责关联,将lt的值保存为LT参数,其设置参考下图:
我们的插件组VcodeVerifyController和VcodeExtractor负责将图形验证码正确识别和读取,其中VcodeVerifyController支持尝试读取循环次数的设置:
一个登录的HTTPSampler,将读取的${vcode}参数和关联的${LT}参数一并POST到Web服务器:
一个由响应断言完成的文本检查点,验证登录成功后的欢迎页面:
在此,我们设置5个线程(vuser)进行测试,测试结果如下:
全部通过了登录验证,但根据测试发现识别率成功基本在75%左右,因此,还需要进一步完善,第一是通过改进识别逻辑,第二是增加一个验证码如果识别错误重新进行识别提交登录事务的过程控制。
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?

我要回帖

更多关于 jmeter测试登陆验证码 的文章

 

随机推荐