ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Jmeter验证码登录接口测试全攻略:固定码与OCR方案详解

Jmeter验证码登录接口测试全攻略:固定码与OCR方案详解 做接口测试最怕遇到验证码尤其登录接口一旦套上验证码脚本就没法全自动跑起来。很多测试同学卡在这一步明明Jmeter配置都对就是过不了登录最后只能手动填码性能测试也没法做。这篇文章我就把这几年处理验证码登录接口的Jmeter方案完整梳理一遍从最省事的绕过方案到OCR识别、从单机调试到并发场景连同踩过的坑一起说清楚。1. 验证码登录接口测试的整体设计思路1.1 验证码在登录链路中的真实位置先说业务逻辑。一个典型的验证码登录接口请求链路大概是这样的用户打开登录页前端向后端请求一张验证码图片后端生成图片同时把验证码文本存到Session或者Redis用户输入账号、密码、验证码点击登录前端把这三个字段连同Cookie里的SessionID一起提交后端拿用户提交的验证码和存储的验证码比对一致才继续走账号密码校验。在Jmeter里模拟这个流程卡点就两个第一个是拿到验证码图片并识别出文本第二个是保证提交验证码时关联的Session和获取图片时是同一个。如果你只写一个HTTP请求直接POST登录验证码必然是错的因为压根没走获取验证码这一步。理解了这条链路后面所有方案都是围绕“如何让Jmeter感知验证码”展开的。1.2 测试方案选型绕过、固定码、还是OCR根据项目实际情况验证码登录接口的Jmeter脚本有三种主流方案我按优先级排序第一是先查后端有没有验证码开关比如开发环境是否支持配置为固定验证码或者接口是否可以传入万能验证码。很多公司的测试环境和预发环境是有后门的直接关掉验证码或者固定成0000这是最稳定、识别率100%、并发压测完全不受影响的方案。第二是OCR识别方案。后端验证码图片接口正常可用Jmeter先请求图片再用OCR工具识别文本然后填入登录请求。这种方式适合验证码复杂度不高、图片背景干扰不大的场景识别率能做到70%到90%。第三是人工介入方案。脚本跑到登录步骤时暂停测试人员肉眼看图片手动填码填完再继续。这个方案我只在调试单个请求时用压测基本不考虑。额外提一句有些系统用的是短信验证码那需要和后端约定测试环境直接用固定短信码或者接短信平台做回读原理和图片验证码类似只是获取验证码的通道不同。1.3 为什么推荐优先走后门方案很多测试同学有个误区觉得用OCR识别验证码才显得专业。我的观点恰恰相反压测的核心目标是验证登录接口在并发下的表现而不是证明你能破解验证码。验证码只是登录流程里的一道锁如果你能把锁卸掉同样能验证登录逻辑为什么非要拿钥匙慢慢开性能测试场景下每分钟可能要发起几百上千次登录OCR识别一次平均要几百毫秒到一两秒识别率又不稳定一旦识别失败脚本就报错测试结果里混入了大量假失败最后分析报告时根本说不清楚到底是接口慢还是识别慢。所以我的建议是能用固定码就用固定码能关就关实在不行再上OCR而且OCR方案只适合功能测试或者小并发调试。另外在写Jmeter脚本时不管用哪种方案都要把验证码的获取和提交设计成同一个线程组里的前后步骤并且配合Cookie管理器保持会话上下文。如果你用两个线程组分别跑“获取验证码”和“登录”Session不共享等于白做。2. 环境准备与Jmeter配置的核心细节2.1 Jmeter版本和插件选型做验证码登录接口测试建议使用Jmeter 5.4以上版本我用过5.1到5.65.4以后对JSON提取和断言支持更顺手内置的JSON Extractor也足够用。安装路径不要有中文和空格不然某些Java特性会踩坑。JDK我这边统一用的JDK 8很多公司测试机还是老项目JDK 11在个别环境会有兼容性问题。需要准备的插件不多主要是三个Java Request Sampler或者直接用HTTP Request Sampler这个是Jmeter自带的。BeanShell Sampler或者JSR223 Sampler用于调用OCR接口和处理字符串。JSR223推荐用Groovy性能比BeanShell好但如果你不熟悉GroovyBeanShell也够用。JSON Extractor和Regex Extractor用来从响应里提取SessionID、图片Base64数据、登录返回的Token等。如果你的项目用的是HTTPS还需要处理证书。Jmeter自带的HTTP Client默认会校验SSL证书如果被测系统是自签名证书会报PKIX path building failed。我的做法是把被测系统的证书导出为CER文件然后用keytool -importcert导入到Jmeter运行JDK的cacerts信任库密码默认changeit。注意Jmeter的JRE和命令行用的JDK要是同一个否则导入没生效。2.2 线程组结构设计从单用户调试到并发压测验证码登录的Jmeter脚本线程组的结构直接决定脚本能不能跑通。我的习惯是先做单线程调试再改并发。线程组内部结构分为四块HTTP Cookie Manager放在线程组最上面全局生效用于维护Session。获取验证码的HTTP Sampler对应后端验证码图片接口。OCR识别层用JSR223或者BeanShell调用外部OCR接口把识别结果存到变量。登录的HTTP Sampler引用账号、密码和验证码变量提交后通过断言判断是否登录成功。如果你要用CSV文件参数化账号密码就在线程组上加CSV Data Set Config注意把“分享模式”改成“所有线程”否则多线程下每个线程只会读到第一行数据。单线程调试时循环次数设为1监听器加一个View Results Tree就够了。压测时循环次数按需求调整同时把监听器精简掉避免监听器本身成为瓶颈影响测试结果。2.3 证书和HTTPS脚本录制的前置处理有些项目连验证码图片接口也是HTTPS而压测环境又是HTTPS证书做的双向认证这种就麻烦一点。Jmeter录制HTTPS脚本时还要生成一个代理证书但日常测试不需要录制直接用HTTP Request手写接口参数就行注意在HTTP Request的Implementation里选HttpClient4并勾选Use KeepAlive。遇到过几次的报错是Connect to ... timed out排查后发现是JDK的TLS版本和被测服务器不匹配。可以在jmeter.properties里调整https.default.protocolTLSv1.2同时设置httpclient4.retrycount0避免网络抖动时Jmeter反复重试造成请求堆积。如果你用的是自签名证书且不想导入信任库也可以在HTTP Request的Advanced里勾选Use HTTP Client 4然后在jmeter.properties里把server.rmi.ssl.disable这类参数改掉。但我要提醒跳过SSL验证只适合你自己本机调试压测时建议按正规方式导入证书不然数据都不安全。3. 固定验证码方案最省事的登录接口联调方式3.1 后端配置固定验证码的两种常见做法固定验证码的后端实现方式通常有两种。第一种是后端代码写死了通用验证码比如if (captcha.equals(0000)) { // 直接通过 }这种万能码逻辑一般只在测试环境保留上线前会删掉。第二种是验证码生成后不存Redis而是存在一个全局配置类里测试人员可以调接口给验证码赋一个固定值。不管是哪种前端都需要对应处理。如果前端拿不到图片登录页显示不出来那就换个思路后端只对验证码接口做固定前端正常请求图片但无论图片显示什么后端的固定码都不变测试时直接输入固定码即可。如果前端还会自己校验一次验证码格式比如固定码位数不足4位直接不允许提交那就把固定码设计成符合格式要求的值例如8888。3.2 Jmeter脚本怎么写固定验证码场景下Jmeter脚本是最简单的。完整步骤如下第一步开启JmeterTest Plan下添加一个线程组命名“固定验证码登录调试”。线程组设置里线程数填1Ramp-Up填1循环次数填1。第二步在线程组下添加Config Element里的HTTP Cookie Manager。这里需要注意Cookie Manager默认会自动管理请求返回的Set-Cookie建议勾选Clear cookies each iteration否则多次循环时Session可能串掉。第三步添加一个HTTP Request请求登录接口。协议HTTP或HTTPS服务器名称填被测地址端口看环境方法POST路径填登录URL。在Parameters或Body Data里添加三个字段username、password、captcha。captcha直接填固定码例如8888。第四步添加一个Response Assertion断言登录成功接口返回的标志字段。比如返回JSON里包含success:true或者code:0。第五步点击运行查看结果树。如果登录成功说明固定码生效。然后你再改成10个线程循环100次跑压测脚本不需要变逻辑通畅。这里给一个JSON断言示例比如响应为{ code: 0, message: success, data: { token: abc123 } }可以在Response Assertion里选择JSON Path Assertion如果用JSR223断言可以用以下Groovy代码def response new groovy.json.JsonSlurper().parse(prev.getResponseData()) if (response.code ! 0) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage(登录失败: response.message) }注意如果登录接口的响应不是JSON而是文本就用Contains断言检查关键字。很多老系统登录成功后会返回一个跳转URL或者一段HTML里面包含用户名这种直接Contains匹配更稳定。3.3 固定码方案的局限和适用边界固定码方案虽然省事但不是所有项目都能用。如果你的被测系统是外部第三方提供的服务比如对接了SSO登录、短信平台或者后端逻辑写死不允许跳过验证码那固定码就走不通。另外在安全性要求高的金融级项目里验证码逻辑是硬编码在前端JS和后端服务两侧的测试环境也不开后门那只能走OCR识别路线。另一个坑有些系统虽然验证码是固定码但后端还是会校验验证码和Session的绑定关系比如验证码存入Redis时key是SessionID提交登录时如果没有携带相同的SessionID即使验证码对也不通过。这种情况下即使固定码生效你也必须在Jmeter脚本里先请求一次验证码图片接口获得SessionID再携带这个SessionID去登录。所以固定码方案里仍然建议先跑一个获取验证码的请求主要是为了拿到Session上下文。4. 动态验证码的OCR识别实战4.1 动态验证码的获取与传递方式当没有后门可用时只能走真实接口流程。动态验证码图片接口的响应形式一般有三种第一种是返回一张图片流Content-Type是image/jpeg或image/png响应体是二进制图片。Jmeter直接显示乱码需要把它保存为文件再识别。第二种是返回JSON里面包含Base64编码的图片字符串类似{img:data:image/png;base64,iVBORw0KGgo...}同时返回一个captchaId或者uuid。这种情况需要先用JSON Extractor提取Base64字段再解码成图片文件。第三种是验证码不在图片里而是通过短信或者邮箱发送这种接口通常是一个发送验证码的请求然后测试人员需要去数据库或测试账号里查最新验证码。把这部分也纳入自动化的话需要额外查询能力不在本文重点范围。不管哪种形式核心流程都一样获取图片 - 本地保存图片 - OCR识别 - 提交登录。Jmeter本身没有图片识别能力所以我的做法是让Jmeter调用一个本地的OCR服务或者用BeanShell调用Java OCR库。4.2 本地OCR服务搭建Python PaddleOCR最短路径我用的最多的OCR方案是PaddleOCR识别效果比Tesseract好尤其是带扭曲和干扰线的验证码。部署方式很简单在本地或一台压测辅助机上装Python 3.8以上环境然后安装pip install paddlepaddle paddleocr使用PaddleOCR 2.6以上版本可以写一个简单的HTTP服务接收验证码图片路径或Base64字符串返回识别结果。参考代码如下from paddleocr import PaddleOCR from flask import Flask, request, jsonify import base64 import tempfile import os app Flask(__name__) ocr PaddleOCR(use_angle_clsTrue, langen, show_logFalse) app.route(/ocr, methods[POST]) def ocr_api(): data request.get_json() img_b64 data.get(image) if not img_b64: return jsonify({code: 400, msg: no image}) tmp tempfile.NamedTemporaryFile(suffix.png, deleteFalse) tmp.write(base64.b64decode(img_b64)) tmp.close() result ocr.ocr(tmp.name, clsTrue) os.unlink(tmp.name) text if result and result[0]: for line in result[0]: text line[1][0] # 清理非字母数字字符验证码一般只包含字母数字 text .join(ch for ch in text if ch.isalnum()) return jsonify({code: 0, text: text}) if __name__ __main__: app.run(host0.0.0.0, port9898)这样Jmeter只需要发送一个HTTP请求到http://localhost:9898/ocr把Base64图片传过去OCR服务返回识别文本Jmeter再把这个文本作为登录参数即可。把OCR服务和被测服务分开部署避免OCR计算影响压测机的请求发送能力。Tesseract我也用过优点是安装简单Windows下有现成的exe但识别效果对验证码噪声敏感需要做灰度化、二值化预处理否则识别率感人。如果验证码风格简单纯数字四位用Tesseract也够。PaddleOCR的好处是不需要自己处理图像增强模型自带抗干扰能力识别率明显高一截。4.3 Jmeter调用OCR服务的完整脚本结构以下是我在Jmeter里跑通的完整脚本结构直接照着搭就能用。线程组结构HTTP Cookie Manager请求验证码图片接口HTTP Sampler提取Base64图片数据JSON Extractor或正则提取器调用OCR识别服务HTTP Sampler提取OCR返回的识别文本JSON Extractor登录接口HTTP Sampler登录结果断言JSR223或JSON断言第一步验证码图片接口通常返回JSON形如{captchaId:a1b2c3,imgBase64:data:image/png;base64,XXXX}在HTTP Sampler上添加JSON ExtractorVariable names:captchaId,imgBase64JSON Path expressions:$.captchaId,$.imgBase64Match Numbers: 1,1Default Values: NOT_FOUND第二步添加一个BeanShell Sampler或JSR223 Sampler把Base64字符串处理成纯Base64数据。因为接口返回的imgBase64可能带着data:image/png;base64,前缀需要用正则去掉。在JSR223 Sampler里写Groovyimport java.util.regex.Pattern String raw vars.get(imgBase64) String clean raw.replaceAll(^data:image/\\w;base64,, ) vars.put(imgPure, clean)这段代码会把data:image/png;base64,...转成纯Base64存到imgPure变量OCR接口那边只认纯Base64。第三步添加调用OCR服务的HTTP Sampler协议: http服务器: localhost端口: 9898路径: /ocr方法: POSTBody Data:{image:${imgPure}}别忘了添加HTTP Header Manager设置Content-Type: application/json。第四步在OCR请求下添加JSON Extractor提取返回文本Variable names:ocrTextJSON Path expressions:$.textDefault Values: OCR_FAIL第五步登录接口引用这个变量参数名: captcha值:${ocrText}第六步运行后观察。如果OCR识别失败登录接口自然会返回验证码错误这时需要检查OCR服务的日志输出看看识别文本是否为空或明显错误。4.4 识别结果的清洗和后置处理OCR识别结果经常带着空格、换行、特殊字符比如识别出aB 3d或者0被识别成O1被识别成l。后端验证码通常不区分大小写一般会统一转小写。Jmeter端在提交前最好做一层清洗转小写vars.put(ocrText, vars.get(ocrText).toLowerCase())去空格vars.get(ocrText).replaceAll(\\s, )只保留字母数字.replaceAll([^a-z0-9], )在Groovy里可以一次搞定String text vars.get(ocrText).toLowerCase().replaceAll([^a-z0-9], ) vars.put(ocrText, text)清洗好后可以做一次有效性判断如果清洗后的长度和验证码期望长度不符比如验证码是4位清洗后只有3位直接断言失败并跳过登录请求免得提交无意义的登录请求污染测试数据。这里有个小技巧如果你知道验证码位数可以在JSR223 Sampler里提前判断String text vars.get(ocrText) if (text.length() 4) { prev.setStopThread(false) AssertionResult.setFailure(true) AssertionResult.setFailureMessage(OCR识别结果过短: text) }注意prev对象是SampleResult用prev.setStopThread(false)不会停止线程但可以标记失败。如果你希望识别失败时直接跳过后续登录请求可以用vars.put(ocrValid, false)然后在登录接口的Action to be taken里配置条件判断不过这种逻辑在Jmeter里稍微绕我一般宁可让它登录失败然后依赖断言统计识别失败率。4.5 OCR识别方案的并发注意事项OCR识别方案做并发时最容易翻车。之前我在一个压测项目里用4台施压机每台机器并发50个线程OCR服务部署在单独一台机器上结果还是把OCR服务打崩了。原因很简单50个并发用户同时请求验证码图片然后一齐请求OCR识别OCR模型推理是计算密集型的单线程处理能力有限请求全部堆积超时率飙升。解决思路有两种第一种是OCR服务加队列和并发控制限制同一时刻推理的请求数多余请求排队等待。如果你会改Flask服务的话可以用Celery或者简单的线程池。我的做法是在Flask前加一层信号量import threading semaphore threading.Semaphore(4) # 同时最多4个OCR推理 app.route(/ocr, methods[POST]) def ocr_api(): with semaphore: # 推理逻辑 pass第二种是在Jmeter侧控制并发识别请求的速率比如用Constant Throughput Timer限制每分钟的OCR请求数或者用JSR223 Sampler加个Thread.sleep随机等待。这也能降低识别请求的瞬时冲击。另外OCR识别耗时通常在300ms到1500ms之间如果登录接口压测的目标吞吐是100 QPS那就意味着OCR服务至少要扛住每秒100次识别。这种情况不要用单机FlaskPaddleOCR建议用GPU机器或者独立OCR集群。不过说实话真到了这种量级你还是强烈建议后端提供固定码开关否则压测就变成了OCR服务压测失去了登录接口压测的意义。5. 登录结果断言与核心参数传递5.1 登录接口的返回数据怎么校验验证码对了之后登录接口会返回一堆东西常见的有token、用户信息、权限菜单、登录时间等。测试脚本里不需要校验全部字段重点就两个登录是否成功、拿到的凭证是否有效。对一个返回JSON的登录接口我会用JSON Extractor提取两个值登录状态字段和token字段。比如{ code: 0, msg: ok, data: { token: eyJhbGciOi..., userName: 张三 } }在登录HTTP Sampler下添加JSON ExtractorVariable names:loginCode,authTokenJSON Path expressions:$.code,$.data.token然后在响应断言或JSR223断言里判断loginCode是否为0token长度是否大于20。这样比单纯判断响应代码更可靠因为有些接口即使登录失败HTTP状态码仍然是200。5.2 BeanShell断言的实际写法评论区问得最多的是beanshell断言怎么判断登录结果。这里给一个通用模板注意BeanShell和JSR223的用法有些差异。我推荐用JSR223 Groovy因为BeanShell性能实在差不过在5.4版本里BeanShell还是兼容的。JSR223断言示例import groovy.json.JsonSlurper def responseText prev.getResponseDataAsString() def json new JsonSlurper().parseText(responseText) if (json.code ! 0) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage(登录接口返回错误: json.msg) } else { if (json.data.token null || json.data.token.length() 20) { AssertionResult.setFailure(true) AssertionResult.setFailureMessage(Token异常: json.data.token) } }如果你必须在BeanShell里写那就用org.apache.jmeter.assertions.AssertionResult写法类似只是解析JSON需要用org.json.JSONObject或者自己写正则。BeanShell多线程下容易阻塞压测时尽量别用。5.3 登录Token如何传递给后续接口登录接口测通了往往还有后续业务接口需要带Token比如查询订单、提交表单。在Jmeter里传递Token有三种方式第一种是正则提取器登录响应里如果Token是明文用正则抓取。比如token:([^])第二种是JSON Extractor上面已经写过。FastJSON解析比正则靠谱推荐优先用。第三种是JSR223脚本存入属性跨线程组使用。如果登录在一个线程组后续业务在另一个线程组那需要把Token存成全局属性。代码示例props.put(authToken, vars.get(authToken))另一个线程组在HTTP Header Manager里引用Authorization: ${__P(authToken,)}这里注意__P函数读取属性${authToken}读的是变量跨线程组必须用属性还不能把这个逻辑用一个线程组里的循环来跑否则属性被覆盖。5.4 断言太多会影响压测结果吗压力测试时断言尽量精简。有人喜欢在每个Sampler后面挂一堆断言检查各种字段这在高并发下会放大Jmeter的CPU开销导致施压机自身成为瓶颈。我的习惯是压测脚本只保留关键断言登录接口一个核心业务接口一个。调试阶段可以多断言压测时把非必要的断言全部注释掉或者放到setUp Thread Group里做前置校验。另外压测时不要加View Results Tree这种全量结果监听器它会存储每个Sample的响应体内存增长飞快。建议用Simple Data Writer输出到文件或者只启用Summary Report顺带定时清理结果文件。6. 常见问题与排查技巧实录6.1 提示验证码错误但OCR识别看起来是对的这个问题遇到太多次了。原因一般有三个Session不一致、大小写问题、验证码过期时间太短。Session不一致最常见。Jmeter里获取验证码的HTTP请求和登录的HTTP请求虽然都在同一个线程组但如果线程组配置了Reset cookies each iteration或者Cookie Manager没有放在线程组最上层就会导致两次请求的SessionID不同。后端存验证码时按SessionID关联Session不一致怎么提交都失败。解决方法是把HTTP Cookie Manager放在线程组首个子节点并确认两次请求都携带了同一个SessionID。你可以在查看结果树里看登录请求的Cookie请求头和获取验证码请求的Cookie头比对一下。大小写问题。后端通常把验证码转成小写再比对但OCR识别出来可能混着大小写如果你在提交前没有统一转小写能识别对但验证失败。清洗逻辑里强制toLowerCase()能解决。验证码过期时间太短。有些系统验证码有效期只有30秒如果从获取图片到识别再登录用了很久尤其OCR服务响应慢后端已经删掉这验证码了。日志里看到获取验证码时间戳和登录时间戳差了几十秒就要排查到底哪一步慢了。6.2 登录接口报HTTPS握手失败压测环境是HTTPS时Jmeter经常报SSL handshake或者PKIX path错误。主要原因是Jmeter所用JDK的信任库没有导入被测系统证书或者被测系统TLS版本和JDK默认协议不一致。排查步骤用浏览器打开登录接口点击地址栏锁图标导出证书为cer文件。找到Jmeter的JDK路径执行keytool -importcert -file your.cer -keystore cacerts -alias youralias如果提示密码默认是changeit。如果导入后还是握手失败检查jmeter.properties里的https.default.protocol改成TLSv1.2。被测系统如果只支持TLS1.3那就需要升级JDK版本JDK8默认支持到TLS1.3需要打个补丁比较麻烦。这种情况建议换更高版本JDK来跑Jmeter。6.3 并发时获取验证码失败率突然上升并发环境下获取验证码接口本身也可能挂。如果响应超时先看是不是验证码接口有频率限制比如同一IP每秒只允许请求一次那并发必挂。这种限制通常可以通过后端配置关闭或者在压测机前加一层代理统一出口IP。如果验证码接口本身不稳定比如返回500或空值那即使Jmeter脚本正确登录也过不去。要判断是脚本问题还是接口问题单独用一个线程组只循环请求验证码接口看单接口的表现。如果是接口性能问题需要先解决接口本身再谈登录压测。6.4 常见问题速查表现象可能原因解决方案登录永远提示验证码错误Cookie/Session不一致检查Cookie Manager位置和Cookie内容登录永远提示验证码错误验证码大小写问题OCR结果转小写后提交OCR识别总是空图片Base64前缀没去掉用正则去掉data:image前缀OCR识别总是空OCR服务未启动单独用Postman调一下OCR接口OCR识别结果长度不对模型识别出多余字符用正则只保留字母数字HTTPS握手失败JDK信任库没导入证书keytool导入证书HTTPS握手失败TLS版本不一致调整jmeter.properties并发时大量超时OCR服务处理不过来OCR服务加并发限制或换GPU并发时大量超时验证码接口限流关闭限流或改压测策略线程组获取验证码和登录Session不一致线程组循环清Cookie勾选Cookie Manager选项登录成功但断言失败断言字段路径错误在结果树里看实际返回JSON结构6.5 调试时最实用的三个工具除了Jmeter我调试这类接口还会用Postman和在线Base64工具。Postman里可以快速手动走一遍获取验证码、登录的流程确认接口逻辑没问题再写Jmeter脚本。Base64工具用于检查图片数据是否完整如果Jmeter提取的Base64字段在工具里能正常显示图片说明提取没问题问题出在识别环节。还有一个技巧在Jmeter脚本里临时加一个Debug Sampler把需要的变量打印到结果树里。排查时常用调试完记得删掉否则压测报告里打印的变量数据量很大影响结果文件大小。7. 从功能调试到压测落地的几个实操心得7.1 脚本调试时的“三色原则”我调试Jmeter脚本时习惯只关注结果树里红绿灯绿色是成功红色是失败灰色是跳过。固定验证码方案下整个脚本应该是全绿OCR方案下只要登录断言不失败就说明整个链路通了。如果登录请求变红第一时间不是去看OCR服务而是先看获取验证码请求是否绿色再看OCR请求是否绿色最后看登录请求的请求体里验证码字段是否有值。按照这个顺序排查能省很多时间。7.2 压测前的试运行清单正式压测前建议按这个顺序做一遍单线程循环1次确认全链路绿色。单线程循环5次确认每次的验证码都能识别成功没有偶发失败。10个线程循环10次观察OCR服务CPU和响应时间确认扛得住。关掉调试监听器打开Summary Report开始正式压测。这一步特别重要很多人在第2步就开始并发压测结果全是验证码识别失败白白浪费压测时间。识别率不够高的情况下先在低并发把OCR服务调优或者改用固定码。7.3 关于验证码识别率的一句话经验PaddleOCR默认模型对印刷体字符识别很好但验证码常常故意扭曲、加干扰线、字符粘连。如果识别率低于70%别死磕模型先去看验证码生成逻辑如果验证码固定4位数字且无复杂干扰PaddleOCR轻松90%以上如果带彩色噪点和弧线识别率可能掉到60%这时候跟产品经理反映一下测试环境降低验证码复杂度是双方都省事的办法。7.4 最后一点压测报告的解读别被“识别失败”污染用OCR方案做完压测分析报告时要把识别失败导致的接口错误独立统计。我的做法是在登录接口的断言里区分两类失败一类是断言验证码错误一类是断言超时。这样报告里能直接看验证码识别失败率而不是笼统的登录失败率。否则领导看到一片红第一反应就是登录接口有问题实际上很多是OCR识别不准造成的。我个人在实际项目里的取舍是只要能拿到测试后端配置权限验证码一律用固定码或者关闭验证码只有拿不到权限、必须验证整个登录链路时才启动OCR辅助识别。而且要记得验证码识别本身是个概率问题不管怎么优化都不可能做到100%准确压测场景下要保证的是系统稳定性不是保证每张验证码都认识。先把这两件事分清楚Jmeter验证码登录的脚本你就基本琢磨透了。
返回列表