1. 背景说明
在自动化测试(接口自动化或UI自动化)工作中,在应用登录时如何自动识别验证码可能是一开始就需要解决的问题。不同于手工测试,对于自动化测试来说,如何自动并准确识别验证码一直是个比较难处理的问题。在自动化测试过程中如果测试人员没有好的处理方法,就只能要求开发人员进行特殊处理,例如在后台设置万能验证码,或永久 TOEKN 跳过验证码环节,甚至直接测试环境取消验证码,这种处理方式只能在测试环境中,在生产环境部署时又需要恢复,整个流程操作繁琐,且容易造成安全隐患。
本文以登录为场景,详细介绍 MeterSphere 如何利用OCR技术,在接口自动化以及UI自动化测试中自动识别图片验证码,实现整体测试流程自动化。
2. ddddocr项目
2.1 项目简介
ddddocr是一个基于深度学习的OCR(Optical Character Recognition,光学字符识别)库,用于识别图片中的文字。它可以识别各种类型的文字,包括印刷体、手写体、表格、条形码等。dddocr库使用了深度卷积神经网络(CNN)和循环神经网络(RNN)等先进的模型,具有较高的准确性和稳定性。Github地址为:https://github.com/sml2h3/ddddocr
目前 ddddocr 支持滑块验证码、点选类验证码、字母数字验证码等多种验证码的识别。
# http://{host}:{port}/{opt}/{img_type}/{ret_type}
# opt:操作类型 ocr=OCR det=目标检测 slide=滑块(match和compare两种算法,默认为compare)
# img_type: 数据类型 file=文件上传方式 b64=base64(imgbyte)方式 默认为file方式
# ret_type: 返回类型 json=返回json(识别出错会在msg里返回错误信息) text=返回文本格式(识别出错时回直接返回空文本)
# 例子:
# OCR请求
# resp = requests.post("http://{host}:{port}/ocr/file", files={'image': image_bytes})
# resp = requests.post("http://{host}:{port}/ocr/b64/text", data=base64.b64encode(file).decode())
# 目标检测请求
# resp = requests.post("http://{host}:{port}/det/file", files={'image': image_bytes})
# resp = requests.post("http://{host}:{port}/ocr/b64/json", data=base64.b64encode(file).decode())
# 滑块识别请求
# resp = requests.post("http://{host}:{port}/slide/match/file", files={'target_img': target_bytes, 'bg_img': bg_bytes})
# jsonstr = json.dumps({'target_img': target_b64str, 'bg_img': bg_b64str})
# resp = requests.post("http://{host}:{port}/slide/compare/b64", files=base64.b64encode(jsonstr.encode()).decode())
2.2 部署安装
在安装 MeterSphere 服务器中执行以下安装命令,或者准备一台带 docker 环境的服务器。
git clone https://github.com/sml2h3/ocr_api_server.git
cd ocr_api_server
# 修改entrypoint.sh中的参数,具体参数往上翻,默认9898端口,同时开启ocr模块以及目标检测模块
# 编译镜像
docker build -t ocr_server:v1 .
# 运行镜像
docker run -p 9898:9898 -d ocr_server:v1
# 验证是否安装成功
可以通过直接GET访问http://{host}:{port}/ping来测试,如果返回pong则启动成功
3. 具体操作说明
整体流程:下载验证码图——>上传ddddocr识别——>取回识别文字——>带入接口登陆/页面
3.1 登录接口验证码识别
3.1.1 确认下载验证码接口
确认刷新验证码的接口,可以通过浏览器F12进行抓包,比如下面刷新验证码或者下载验证码的接口为:
https://xxx/api/service/sdk/external/login/captcha
在接口中请求此接口,并且用后置参数提取方式保存验证码对应的key值。
3.1.2 下载验证码并且进行base64编码
通过访问具体的下载接口的URL后,利用 MeterSphere 的后置脚本将需要将返回的验证码进行下载并且进行base64编码。
下载验证码后置脚本(beanshell脚本):
import java.io.*;
byte[] result=prev.getResponseData(); //这个是获取到请求返回的数据,prev是获取上个请求的返回
String file_name="img.png";//代表存放文件的位置和文件名
File file=new File(file_name);
FileOutputStream out=new FileOutputStream(file);
out.write(result);
out.close();
验证码图片转base64脚本(python脚本):
import base64
def img_to_base64(img_path):
with open(img_path, 'rb')as read:
b64 = base64.b64encode(read.read())
return b64
img_b64 = img_to_base64('img.png')
vars.put("img_b64", img_b64)#将转成base64的验证码存为img_b64变量
log.info(img_b64)
3.1.3 调用OCR接口,进行验证码识别
调用采用OCR请求接口:http://{host}:{port}/ocr/b64/json,并且通过后置参数提取方式提取相应识别到的验证码文本
3.1.4 验证码应用
最终将提取的验证码文本,通过变量带入接口登陆中
3.1.5 整体运行效果
3.2 登录页面验证码识别
3.2.1 打开网页
使用MeterSphere UI测试模块的场景步骤,打开被测系统的网页,并通过浏览器开发者工具获确认后续步骤需要用到图形验证码的地址,这里图形验证码的地址为https://zp.hunau.edu.cn/base/frame/recruitVerfication.jsp。
3.2.2 输入账号/密码
第二个步骤是分别输入登录用户账号以及密码,根据表达式定位即可。
并在步骤的后置脚本中,需要使用以下脚本将验证码图片加载为base64编码。
var imgSrc = "https://zp.hunau.edu.cn/base/frame/recruitVerfication.jsp";
console.log("imgSrc = " + imgSrc);
var image = new Image();
image.src = imgSrc;
image.addEventListener('load', function() {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
var imgBase64 = canvas.toDataURL("image/jpeg");
window.imgBase64Final = imgBase64.split(',')[1]; // 设置为全局变量
console.log("imgBase64inner = " + window.imgBase64Final);
});
//上面的函数是异步的,加载图片需要时间,所以在后续的步骤的前置操作中需要添加等待时间
3.2.3 base64编码
因为前一步的脚本需要时间识别验证码内容,所以添加一个前置等待时间用来等待上一步图片加载完成后。
在后置操作中,可以使用以下脚本将base64编码设置为MeterSphere变量。
var middleData = window.imgBase64Final;
return middleData;
3.2.4 OCR请求
脚本中请求ddddocr服务,从base64编码中识别出图片验证码。如果在被测系统页面的脚本中直接请求ocr服务,会受到浏览器cors策略的限制请求失败,所以这一步需要添加一个访问ocr页面的追加页面来避免cors。
在后置脚本中需要添加以下脚本用于识别图形验证码内容,该脚本识别过程也是异步的,所以在后续步骤里需要添加一部分等待时间。
var url = "http://10.1.11.37:9898/ocr/b64/json";
var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', url, true);
httpRequest.setRequestHeader("Content-type", "application/json");
var imgBase64Final = ${middleData} ;
console.log("这是因上一个脚本的变量"+imgBase64Final);
httpRequest.send(JSON.stringify(imgBase64Final));
// 响应后的回调函数
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText);
window.code = response.result;
console.log("这个就是提取出来的验证码"+window.code);
} else {
console.error("请求失败: " + httpRequest.status);
}
}
};
因为脚本需要时间识别验证码内容,所以添加一个前置等待时间。
在后置脚本中通过以下脚本将识别出来的图形验证码设置为MeterSphere变量。
var verifyCode = window.code;
return verifyCode;
3.2.5 返回登录页面
经过前面的步骤,图形验证码已经识别出来并设置为 MeterSphere 变量了,接下来需要返回被测系统页面填写图形验证码。
3.2.6 输入验证码
这个步骤目的是在验证码输入框内输入前面返回的验证码变量。
3.2.7 点击登录
在输入了账号密码和验证码后,点击登录按钮即可成功登录。
3.2.8 运行效果
输入图形验证码:
登录成功:
总结:通过 MeterSphere 平台并结合于ddddocr的图片验证码识别能力,在接口自动化以及UI自动化中准确识别图片验证码,满足实际自动化测试要求。