使用OCR加持的APP自动化测试

在APP自动化测试实践中,测试人员普遍会遇到一类典型问题:部分页面元素缺乏固定的id、xpath等可定位属性,例如自定义弹窗内的文本按钮、动态生成的验证码文本,或是部分原生控件的属性被开发屏蔽,导致常规元素定位方法失效。仅依赖Airtest的图像识别能力,在文字内容变化但样式一致的场景下,识别精准度往往难以满足测试需求。

光学字符识别(OCR)技术可有效解决此类问题。本文将探讨如何将PaddleOCR集成至Airtest框架,借助OCR能力增强APP自动化测试效果,攻克常规定位方法无法解决的技术难点。

一、先搞定环境:Airtest + PaddleOCR 安装

在开始写代码之前,先把基础环境搭好。这里要注意版本兼容性,不然容易踩坑。咱们先明确需要安装的核心依赖包,再一步步操作。

1.1 基础环境要求

  • Python 3.8.6(必须严格遵守,避免版本差异导致的问题)

  • Windows/macOS/Linux均可,建议Windows(对Airtest的GUI工具支持更友好)

  • 手机或模拟器(确保开启开发者模式,USB调试已打开)

1.2 依赖包安装

先创建一个虚拟环境(避免污染全局环境,这是好习惯),然后安装对应的依赖包。直接用pip安装即可,注意指定合适的版本:

复制代码
python 复制代码
# 创建并激活虚拟环境(Windows示例)
python -m venv ocr_auto_test_env
ocr_auto_test_env\Scripts\activate

# 安装Airtest,指定1.2.7版本(稳定且兼容Python3.8)
pip install airtest==1.2.7

# 安装PaddleOCR,指定2.6.1.3版本(避免最新版本的兼容性问题)
pip install paddleocr==2.6.1.3

# 安装Airtest配套的Android控制依赖(如果测Android APP)
pip install pocoui==1.0.82

注意事项:

  1. 安装PaddleOCR时,会自动安装PaddlePaddle依赖,无需额外手动安装;

  2. 如果是macOS系统,激活虚拟环境的命令是:source ocr_auto_test_env/bin/activate;

  3. 若安装过程中出现权限错误,Windows可右键命令行以管理员身份运行,macOS/Linux在命令末尾加--user。

1.3 环境验证

安装完成后,咱们简单验证一下环境是否可用:

复制代码
python 复制代码
# 验证Airtest
from airtest.core.api import *
print("Airtest导入成功")

# 验证PaddleOCR
from paddleocr import PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang='ch')
print("PaddleOCR初始化成功")

运行上述代码,如果没有报错,说明基础环境已经没问题了。这里补充一个环境验证的示意图,帮助大家直观查看运行结果:

二、核心逻辑:OCR如何加持APP自动化测试?

在Airtest的常规自动化测试中,我们主要依赖图像识别(找图)和元素定位(基于Android的uiautomator2、iOS的xctest)。但遇到前面说的"无属性可定位"场景时,这两种方式就会受限。

OCR加持的核心逻辑很简单:先通过Airtest获取APP当前页面的截图,然后用PaddleOCR识别截图中的文字内容和对应坐标,最后根据识别到的文字,用Airtest的点击、输入等API操作对应位置的元素。整个流程可以总结为:截图 → 文字识别 → 坐标提取 → 自动化操作。

举个具体的场景:一个APP的弹窗提示"确认提交",这个按钮没有id,也没有固定的xpath,但是文字是固定的。我们就可以通过上述流程,识别"确认提交"这几个字的坐标,然后点击这个坐标位置,完成自动化操作。

三、实操实现:Airtest + PaddleOCR 代码编写

接下来进入实操环节,咱们以"识别APP页面文字并点击指定文字位置"为例,完整实现一套代码。先说明一下本次实操的场景:打开某款APP(以Android端的"设置"APP为例,无需额外安装,系统自带,方便大家测试),通过OCR识别"WLAN"文字并点击进入。

3.1 整体代码目录结构

本次实操是单文件代码,但为了符合多文件代码示例的规范(提前演示目录结构写法),我们先给出一个可扩展的目录结构,后续如果需要扩展功能,直接按这个结构新增文件即可:

复制代码
python 复制代码
ocr_app_auto_test/
├── common/                # 公共工具类目录
│   ├── __init__.py
│   └── ocr_utils.py       # OCR相关工具函数
├── test_cases/            # 测试用例目录
│   ├── __init__.py
│   └── test_ocr_click.py  # 测试OCR点击功能
└── run.py                 # 程序入口文件

3.2 核心代码实现

下面按目录结构依次编写代码,所有代码基于Python 3.8.6,不使用type hint。

3.2.1 common/ocr_utils.py(OCR工具函数)

这个文件封装PaddleOCR的初始化和文字识别功能,方便后续复用:

复制代码
python 复制代码
from paddleocr import PaddleOCR
from airtest.core.api import snapshot

# 初始化PaddleOCR,全局只初始化一次,避免重复加载模型耗时
ocr = PaddleOCR(use_angle_cls=True, lang='ch', use_gpu=False)

def ocr_recognize_screen(save_screenshot_path=None):
    """
    对当前APP页面截图,并用OCR识别文字和坐标
    :param save_screenshot_path: 截图保存路径,None则不保存
    :return: OCR识别结果,格式为列表,每个元素是(文字, 坐标, 置信度)
    """
    # 1. 用Airtest获取当前页面截图
    if save_screenshot_path:
        snapshot(filename=save_screenshot_path)
        img_path = save_screenshot_path
    else:
        # 临时截图,保存到默认路径
        img_path = snapshot()
    
    # 2. 用PaddleOCR识别截图中的文字
    result = ocr.ocr(img_path, cls=True)
    
    # 3. 解析识别结果,提取文字和对应坐标(取文字区域的中心坐标)
    recognize_result = []
    for line in result:
        for word_info in line:
            text = word_info[1][0]
            # 坐标格式:[[x1,y1],[x2,y2],[x3,y3],[x4,y4]],取中心坐标
            x1, y1 = word_info[0][0]
            x3, y3 = word_info[0][2]
            center_x = (x1 + x3) / 2
            center_y = (y1 + y3) / 2
            confidence = word_info[1][1]
            recognize_result.append((text, (center_x, center_y), confidence))
    
    return recognize_result

def find_text_coordinate(recognize_result, target_text, min_confidence=0.8):
    """
    从OCR识别结果中找到目标文字的中心坐标
    :param recognize_result: ocr_recognize_screen的返回结果
    :param target_text: 目标文字
    :param min_confidence: 最小置信度,低于此值的结果忽略
    :return: 目标文字的中心坐标(x,y),未找到返回None
    """
    for text, coordinate, confidence in recognize_result:
        if target_text in text and confidence >= min_confidence:
            return coordinate
    return None
3.2.2 test_cases/test_ocr_click.py(测试用例)

编写具体的测试用例,实现"打开设置APP → 识别WLAN文字 → 点击进入"的流程:

复制代码
python 复制代码
from airtest.core.api import *
from airtest.core.android import Android
from common.ocr_utils import ocr_recognize_screen, find_text_coordinate

def test_ocr_click_wlan():
    # 1. 连接Android设备(确保设备已通过USB连接,开启USB调试)
    # 这里不指定设备号,默认连接第一个已连接的设备
    dev = Android()
    connect_device("Android:///")
    print("设备连接成功")
    
    # 2. 打开设置APP(包名:com.android.settings,启动Activity:.Settings)
    start_app("com.android.settings")
    print("设置APP启动成功")
    # 等待页面加载完成
    sleep(2)
    
    # 3. 对当前页面进行OCR识别,保存截图到当前目录
    recognize_result = ocr_recognize_screen(save_screenshot_path="settings_home.png")
    print("OCR识别完成,识别结果:", recognize_result)
    
    # 4. 查找目标文字"WLAN"的坐标
    target_coordinate = find_text_coordinate(recognize_result, "WLAN")
    if target_coordinate:
        print(f"找到目标文字'WLAN',坐标:{target_coordinate}")
        # 5. 点击目标坐标
        touch(target_coordinate)
        print("点击WLAN成功")
        # 等待页面跳转
        sleep(2)
        # 再次截图,验证是否跳转成功
        snapshot(filename="wlan_page.png")
        print("跳转后截图已保存")
    else:
        print(f"未找到目标文字'WLAN'或置信度不足")
    
    # 6. 关闭APP
    stop_app("com.android.settings")
    print("设置APP关闭成功")
    
    # 7. 断开设备连接
    dev.disconnect()
    print("设备连接断开")

if __name__ == "__main__":
    test_ocr_click_wlan()
3.2.3 run.py(程序入口)

编写入口文件,用于执行测试用例:

复制代码
python 复制代码
from test_cases.test_ocr_click import test_ocr_click_wlan

if __name__ == "__main__":
    print("开始执行OCR加持的APP自动化测试用例")
    test_ocr_click_wlan()
    print("测试用例执行完成")

3.3 代码运行说明

  1. 运行前准备:确保Android设备已通过USB连接电脑,开启开发者模式和USB调试;如果用模拟器,确保模拟器已启动,且与电脑正常连接。

  2. 运行命令:在项目根目录下,激活虚拟环境后,执行命令:python run.py

  3. 运行结果:程序会自动连接设备、启动设置APP、识别WLAN文字并点击,最后关闭APP。运行过程中会生成两个截图文件:settings_home.png(设置首页截图)和wlan_page.png(WLAN页面截图),同时控制台会输出相关日志信息。

四、使用注意事项

在实际使用Airtest + PaddleOCR进行APP自动化测试时,有几个点需要特别注意,避免出现问题:

4.1 模型加载与性能问题

PaddleOCR的模型首次加载时会比较耗时,建议全局只初始化一次(就像我们在ocr_utils.py里做的那样),不要在每次识别时都重新初始化,否则会严重影响测试效率。如果测试环境有GPU,可以开启use_gpu=True,能显著提升识别速度。

4.2 置信度阈值的设置

不同的APP页面、不同的文字清晰度,OCR识别的置信度会有差异。如果置信度阈值设置太低,容易识别错误;设置太高,可能会找不到目标文字。建议根据实际测试场景调整min_confidence参数,一般设置在0.7-0.9之间比较合适。

4.3 截图质量的影响

OCR识别的准确率很大程度上依赖于截图质量。如果APP页面有模糊、反光、遮挡等情况,识别效果会很差。建议在测试时确保设备屏幕干净、无遮挡,同时避免在页面加载过程中截图(可以通过sleep等待页面加载完成,或者用Airtest的wait函数)。

4.4 多文字重复的场景处理

如果页面中有多个相同的目标文字,find_text_coordinate函数会返回第一个识别到的坐标。如果需要点击特定位置的文字,需要扩展函数逻辑,比如根据坐标的范围来筛选(比如只点击屏幕上半部分的目标文字)。

4.5 平台兼容性问题

本次实操是基于Android平台,iOS平台的使用方式类似,但需要注意Airtest对iOS的支持要求:需要安装Xcode、配置WebDriverAgent等。另外,PaddleOCR在iOS平台的性能表现可能不如Android,建议在iOS测试时多做验证。

五、总结

OCR技术为解决APP自动化测试中的元素定位难题提供了一种有效的思路,尤其是在处理无固定属性的元素、动态文字等场景时,Airtest的图像识别能力结合PaddleOCR的文字识别能力,能极大地提升自动化测试的覆盖率和稳定性。

相关推荐
AI人工智能+2 小时前
智能表格识别技术突破传统OCR局限,实现复杂纸质表格的精准数字化转换
深度学习·ocr·表格识别
qyresearch_2 小时前
直线导轨:精密制造的“隐形冠军”,驱动工业自动化升级的核心力量
人工智能·自动化·制造
天若有情6732 小时前
用 Python 爬取电商商品数据:从入门到反爬破解
开发语言·python
深圳市快瞳科技有限公司2 小时前
专业OCR与大模型混合架构:破解文档智能处理难题的务实之道
计算机视觉·系统架构·ocr
七夜zippoe2 小时前
RabbitMQ与Celery深度集成:构建高性能Python异步任务系统
分布式·python·rabbitmq·celery·amqp
Hello阿尔法2 小时前
SCons 一款基于 Python 的自动化构建工具
python·跨平台·构建工具·scons
龚子亦2 小时前
【Jenkins】实现Unity远程自动化打包
unity·自动化·jenkins
Pyeako2 小时前
Opencv计算机视觉--图像边缘检测
人工智能·python·opencv·计算机视觉·sobel·canny·图像边缘检测