Jmeter识别图片验证码插件(后置处理器)

使用tess4j识别图片验证码
1.下载tess4j,下载地址https://sourceforge.net/projects/tess4j/
2.编写ocr识别类OCRUtil 
参考代码:

package com.gzy.OCR;
 
import java.io.File;
 
import org.testng.annotations.Test;
 
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
 
/**
 * OCR识别工具类,调用tess4j实现OCR识别
 * 注意:
 * 1.tess4j核心包和lib下所有jar包均需要引入
 * 2.拷贝tessdata文件夹于当前用户目录
 */
public class OCRUtil {
    public OCRUtil() {
    }
 
    @Test
    public void test() {
        File imageFile = new File("C:/Users/gzy/Desktop/tess4j/image.jpeg");
        System.out.println(getOCRResult(imageFile));
    }
 
    public static String getOCRResult(File file) {
 
        ITesseract instance = new Tesseract();  
        String result = null;
 
        try {
            result = instance.doOCR(file);
        } catch (TesseractException e) {
            System.out.println(e.getMessage());
        } finally {
            file.delete();
        }
 
        return result;
 
    }
}
3.编写验证码准确性校验类VcodeUtils
VcodeUtils参考代码

package com.gzy.OCR;
 
import org.testng.annotations.Test;
 
/**
 * 验证码正确性校验,分别校验纯数字、纯字母、以及数字+字母的准确性
 */
public class VcodeUtils {
    private final static String PATTERNINT = "0123456789";
    private final static String PATTERNAbc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private final static String PATTERNAbcAndINT = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
    public VcodeUtils() {
 
    }
 
    @Test
    public void test() {
        String str = vcode("   1   a    3V  ", 3, 4);
        System.out.println("--->>" + str + "<<---");
    }
 
    public static String vcode(String vcode, int type, int len) {
        vcode = vcode.trim();
        vcode = vcode.replace(" ", "");
        char[] vcodeChar = vcode.toCharArray();
        if (vcodeChar.length != len) {
            vcode = "error";
            return vcode;
        }
 
        if (type == 1) {
 
            // 纯数字
 
            for (int i = 0; i < len; i++) {
                if (PATTERNINT.indexOf(vcode.toCharArray()[i]) < 0) {
                    vcode = "error";
                    return vcode;
                }
            }
 
        } else if (type == 2) {
            // 纯字母
            for (int i = 0; i < len; i++) {
                if (PATTERNAbc.indexOf(vcode.toCharArray()[i]) < 0) {
                    vcode = "error";
                    return vcode;
                }
            }
 
        } else {
            // 数字字母混合
            for (int i = 0; i < len; i++) {
                if (PATTERNAbcAndINT.indexOf(vcode.toCharArray()[i]) < 0) {
                    vcode = "error";
                    return vcode;
                }
            }
 
        }
 
        return vcode;
 
    }
}


4.通过TestBean框架创建VcodeExtractor组件
编写VcodeExtractor类,实现验证码识别逻辑
package com.gzy.OCR;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
import org.apache.jmeter.processor.PostProcessor;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.testelement.AbstractScopedTestElement;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
 
/**
 * 1.VcodeExtractor实现逻辑,继承AbstractScopedTestElement类,实现PostProcessor, TestBean 
 * 2.AbstractScopedTestElement类是AbstractTestElement子类
 * 3.定义属性myFile,vcodeLen,vcodeType,imageType,所有属性都必须有共有的get、set方法
 * myFile:对应界面上选择文件操作
 * vcodeLen:验证码长度
 * vcodeType:验证码类型
 * imageType:验证码图片类型
 */
public class VcodeExtractor extends AbstractScopedTestElement implements PostProcessor, TestBean {
    private File myFile;
    private int vcodeLen;
    private String vcodeType;
    private String imageType;
    private int Type = 0;
    //定义 UID
    private static final long serialVersionUID = 241L;
    //获取日志类
    private static final Logger log = LoggingManager.getLoggerForClass();
    //定义属性vcode默认值
    private String vcode = "error";
 
    public File getMyFile() {
        return myFile;
    }
 
    public void setMyFile(File myFile) {
        this.myFile = myFile;
    }
 
    public int getVcodeLen() {
        return vcodeLen;
    }
 
    public void setVcodeLen(int vcodeLen) {
        this.vcodeLen = vcodeLen;
    }
 
    public String getVcodeType() {
        return vcodeType;
    }
 
    public void setVcodeType(String vcodeType) {
        this.vcodeType = vcodeType;
    }
 
    public String getImageType() {
        return imageType;
    }
 
    public void setImageType(String imageType) {
        this.imageType = imageType;
    }
 
    @SuppressWarnings("finally")
    @Override
    public void process() {
//        重写process方法,实现操作逻辑
        JMeterContext context = getThreadContext();
        SampleResult previousResult = context.getPreviousResult();
        if (previousResult == null) {
            return;
        }
 
        switch (vcodeType) {
        case "纯数字":
            Type = 1;
            break;
        case "纯字母":
            Type = 2;
            break;
        default:
            Type = 0;
            break;
        }
 
        String status = previousResult.getResponseCode();
        int id = context.getThreadNum();
        String imageName = id + "." + imageType;
        if (status.equals("200")) {
//            如果响应码未200,则读取响应流生成对应验证码图片
            byte[] buffer = previousResult.getResponseData();
            FileOutputStream out = null;
            File file = null;
            try {
                file = new File(imageName);
                out = new FileOutputStream(file);
                out.write(buffer);
                out.flush();
 
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        log.info("打印用户路径--->>开始");
                        log.info(System.getProperty("user.dir"));
                        log.info("打印用户路径--->>结束");
                        log.info("识别验证码--->>开始");
                        //调用OCRUtil.getOCRResult()识别图片验证码
                        vcode = OCRUtil.getOCRResult(file);
                        log.info("原始验证码--->>开始");
                        log.info(vcode);
                        log.info("原始验证码--->>结束");
                        //调用VcodeUtils.vcode()对识别出来的验证码做正确性校验和处理
                        vcode = VcodeUtils.vcode(vcode, Type, vcodeLen);
                        log.info("最终验证码--->>开始");
                        log.info(vcode);
                        log.info("最终验证码--->>结束");
                        //将获取的验证码存入vcode属性供?Jmeter调用者使用,如果识别不成功,保存的值为error
                        JMeterVariables var = context.getVariables();
                        var.put("vcode", vcode);
                        var.put("vuser", String.valueOf(id));
                        log.info("识别验证码--->>结束");
                        return;
                    }
 
                }
 
            }
        } else {
            //提供直接测试方法,选取本地图片查看识别结果是否准确
            if (myFile != null && myFile.exists() && myFile.canRead()) {
                log.info("打印用户路径--->>开始");
                log.info(System.getProperty("user.dir"));
                log.info("打印用户路径--->>结束");
                log.info("识别验证码--->>开始");
                vcode = OCRUtil.getOCRResult(myFile);
                log.info("原始验证码--->>开始");
                log.info(vcode);
                log.info("原始验证码--->>结束");
                vcode = VcodeUtils.vcode(vcode, Type, vcodeLen);
                log.info("最终验证码--->>开始");
                log.info(vcode);
                log.info("最终验证码--->>结束");
                JMeterVariables var = context.getVariables();
                var.put("vcode", vcode);
                var.put("vuser", String.valueOf(id));
                log.info("识别验证码--->>结束");
                return;
            }
 
            JMeterVariables var = context.getVariables();
            var.put("vcode", vcode);
            var.put("vuser", String.valueOf(id));
            log.error("图片不存在或者获取图片响应流失败!");
        }
 
    }
 
}
编写VcodeExtractorBeanInfo类,定义UI属性
package com.gzy.OCR;
 
import java.beans.PropertyDescriptor;
 
import org.apache.jmeter.testbeans.BeanInfoSupport;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.testbeans.gui.TableEditor;
 
/**
 * 1.继承BeanInfoSupport类
 * 2.通过getprop()方法设置各属性默认值
 */
public class VcodeExtractorBeanInfo extends BeanInfoSupport {
 
    private PropertyDescriptor getprop(String name) {
        final PropertyDescriptor property = property(name);
        property.setValue(NOT_UNDEFINED, Boolean.FALSE);  
        return property;
    }
 
    private PropertyDescriptor getprop(String name, Object deflt) {
        PropertyDescriptor p = property(name);
        p.setValue(DEFAULT, deflt);
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
        return p;
    }
 
    public VcodeExtractorBeanInfo() {
        //无参构造函数关联VcodeExtractor
        super(VcodeExtractor.class);
        getprop("myFile");
//        设置验证码长度默认为4位
        getprop("vcodeLen", Integer.valueOf(4));
        PropertyDescriptor p = property("vcodeLen");
        p.setShortDescription("输入验证码长度,可輸入項: 任意正整数");
//        设置验证码类型默认为数字+字母
        getprop("vcodeType", "数字+字母");
        p = property("vcodeType");
        p.setShortDescription("输入验证码格式,可输入项:纯数字、纯字母、数字+字母");
//        设置验证码图片类型默认为jpg
        getprop("imageType", "jpg");
        p = property("imageType");
        p.setShortDescription("输入验证码图片类型,可输入项:jpg、jpeg、png");
    }
 
}


编写VcodeExtractorResources.properties定义各默认属性展示名称
displayName=gzy@VcodeExtractor
myFile.displayName=选择图片路径
vcodeLen.displayName=验证码长度
vcodeType.displayName=验证码类型
imageType.displayName=图片类型

注意:
1.使用tess4j除了需要引入tess4j-3.3.1.jar包外还需要引入其源码lib目录下的所有文件

2.需将该插件所依赖的所有jar包放入Jmeter下lib目录(或者全部存入统一文件夹,然后在jmeter.properties文件下修改user.classpath属性,如user.classpath=../classes;../lib;../lib/Tess4J/lib)

3.需要将tess4j的tessdata文件夹拷贝至Jmeter运行时用户目录,即bin目录


--------------------- 
作者:天天爱代码 
来源:CSDN 
原文:https://blog.csdn.net/u012421039/article/details/68944428 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/weixin_41508948/article/details/92800448