Airtest图像识别测试工具原理解读&最佳实践

这篇具有很好参考价值的文章主要介绍了Airtest图像识别测试工具原理解读&最佳实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 Airtest简介

Airtest是一个跨平台的、基于图像识别的UI自动化测试框架,适用于游戏和App,支持平台有Windows、Android和iOS。Airtest框架基于一种图形脚本语言Sikuli,引用该框架后,不再需要一行行的写代码,通过截取按钮或输入框的图片,用图片组成测试场景,这种方式学习成本低,简单易上手。

2 Airtest实践

APP接入流水线过程中,赛博平台只支持air脚本,因此需要对京管家APP的UI自动化脚本进行的改造。如截图可见,AirtestIDE的主界面由菜单栏、快捷工具栏和多个窗口组成,初始布局中的“设备窗口”是工具的设备连接交互区域。
air脚本生成步骤:

  1. 通过adb连接手机或模拟器
  2. 安装应用APK
  3. 运行应用并截图
  4. 模拟用户输入(点击、滑动、按键)
  5. 卸载应用

Airtest图像识别测试工具原理解读&最佳实践

通过以上步骤自动生成了 .air脚本,调试过程中我们可以在IDE中运行代码,支持多行运行以及单行运行,调试通过后可在本地或服务器以命令行的方式运行脚本:
.air脚本运行方式:airtest run “path to your .air dir” —device Android
.air脚本生成报告的方式:airtest report “path to your .air dir”

3 Airtest定位方式解析

IDE的log查看窗口会时时打印脚本执行的日志,从中可以看出通过图片解析执行位置的过程。下面就以touch方法为例,解析Airtest如何通过图片获取到元素位置从而触发点击操作。

@logwrap
def touch(v, times=1, **kwargs):
    """
    Perform the touch action on the device screen
    :param v: target to touch, either a ``Template`` instance or absolute coordinates (x, y)
    :param times: how many touches to be performed
    :param kwargs: platform specific `kwargs`, please refer to corresponding docs
    :return: finial position to be clicked, e.g. (100, 100)
    :platforms: Android, Windows, iOS
    """
    if isinstance(v, Template):
        pos = loop_find(v, timeout=ST.FIND_TIMEOUT)
    else:
        try_log_screen()
        pos = v
    for _ in range(times):
        G.DEVICE.touch(pos, **kwargs)
        time.sleep(0.05)
    delay_after_operation()
    return pos

click = touch  # click is alias of t

该方法通过loop_find获取坐标,然后执行点击操作 G.DEVICE.touch(pos, kwargs),接下来看loop_find如何根据模板转换为坐标。

@logwrap
def loop_find(query, timeout=ST.FIND_TIMEOUT, threshold=None, interval=0.5, intervalfunc=None):
    """
    Search for image template in the screen until timeout
    Args:
        query: image template to be found in screenshot
        timeout: time interval how long to look for the image template
        threshold: default is None
        interval: sleep interval before next attempt to find the image template
        intervalfunc: function that is executed after unsuccessful attempt to find the image template
    Raises:
        TargetNotFoundError: when image template is not found in screenshot
    Returns:
        TargetNotFoundError if image template not found, otherwise returns the position where the image template has
        been found in screenshot
    """
    G.LOGGING.info("Try finding: %s", query)
    start_time = time.time()
    while True:
        screen = G.DEVICE.snapshot(filename=None, quality=ST.SNAPSHOT_QUALITY)
        if screen is None:
            G.LOGGING.warning("Screen is None, may be locked")
        else:
            if threshold:
                query.threshold = threshold
            match_pos = query.match_in(screen)
            if match_pos:
                try_log_screen(screen)
                return match_pos
        if intervalfunc is not None:
            intervalfunc()
        # 超时则raise,未超时则进行下次循环:
        if (time.time() - start_time) > timeout:
            try_log_screen(screen)
            raise TargetNotFoundError('Picture %s not found in screen' % query)
        else:
            t

首先截取手机屏幕match_pos = query.match_in(screen),然后对比传参图片与截屏来获取图片所在位置match_pos = query.match_in(screen)。接下来看match_in方法的逻辑:

def match_in(self, screen):
    match_result = self._cv_match(screen)
    G.LOGGING.debug("match result: %s", match_result)
    if not match_result:
        return None
    focus_pos = TargetPos().getXY(match_result, self.target_pos)
    return focus_pos

里面有个关键方法:match_result = self._cv_match(screen)

@logwrap
def _cv_match(self, screen):
    # in case image file not exist in current directory:
    ori_image = self._imread()
    image = self._resize_image(ori_image, screen, ST.RESIZE_METHOD)
    ret = None
    for method in ST.CVSTRATEGY:
        # get function definition and execute:
        func = MATCHING_METHODS.get(method, None)
        if func is None:
            raise InvalidMatchingMethodError("Undefined method in CVSTRATEGY: '%s', try 'kaze'/'brisk'/'akaze'/'orb'/'surf'/'sift'/'brief' instead." % method)
        else:
            if method in ["mstpl", "gmstpl"]:
                ret = self._try_match(func, ori_image, screen, threshold=self.threshold, rgb=self.rgb, record_pos=self.record_pos,
                                        resolution=self.resolution, scale_max=self.scale_max, scale_step=self.scale_step)
            else:
                ret = self._try_match(func, image, screen, threshold=self.threshold, rgb=self.rgb)
        if ret:
            break
    return ret

首先读取图片调整图片尺寸,从而提升匹配成功率:
image = self._resize_image(ori_image, screen, ST.RESIZE_METHOD)
接下来是循环遍历匹配方法for method in ST.CVSTRATEGY。而ST.CVSTRATEGY的枚举值:

CVSTRATEGY = ["mstpl", "tpl", "surf", "brisk"]
if LooseVersion(cv2.__version__) > LooseVersion('3.4.2'):
    CVSTRATEGY = ["mstpl", "tpl", "sift", "brisk"]

func = MATCHING_METHODS.get(method, None),func可能的取值有mstpl、tpl、surf、shift、brisk,无论哪种模式都调到了共同的方法_try_math

if method in ["mstpl", "gmstpl"]:
    ret = self._try_match(func, ori_image, screen, threshold=self.threshold, rgb=self.rgb, record_pos=self.record_pos,
                            resolution=self.resolution, scale_max=self.scale_max, scale_step=self.scale_step)
else:
    ret = self._try_match(func, image, screen, threshold=self.threshold, rgb=self.rgb)

而_try_math方法中都是调用的func的方法find_best_result()

@staticmethod
def _try_match(func, *args, **kwargs):
    G.LOGGING.debug("try match with %s" % func.__name__)
    try:
        ret = func(*args, **kwargs).find_best_result()
    except aircv.NoModuleError as err:
        G.LOGGING.warning("'surf'/'sift'/'brief' is in opencv-contrib module. You can use 'tpl'/'kaze'/'brisk'/'akaze'/'orb' in CVSTRATEGY, or reinstall opencv with the contrib module.")
        return None
    except aircv.BaseError as err:
        G.LOGGING.debug(repr(err))
        return None
    else:
        return ret

以TemplateMatching类的find_best_result()为例,看一下内部逻辑如何实现。

@print_run_time
def find_best_result(self):
    """基于kaze进行图像识别,只筛选出最优区域."""
    """函数功能:找到最优结果."""
    # 第一步:校验图像输入
    check_source_larger_than_search(self.im_source, self.im_search)
    # 第二步:计算模板匹配的结果矩阵res
    res = self._get_template_result_matrix()
    # 第三步:依次获取匹配结果
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    h, w = self.im_search.shape[:2]
    # 求取可信度:
    confidence = self._get_confidence_from_matrix(max_loc, max_val, w, h)
    # 求取识别位置: 目标中心 + 目标区域:
    middle_point, rectangle = self._get_target_rectangle(max_loc, w, h)
    best_match = generate_result(middle_point, rectangle, confidence)
    LOGGING.debug("[%s] threshold=%s, result=%s" % (self.METHOD_NAME, self.threshold, best_match))
    return best_match if confidence >= self.threshold else Non

重点看第二步:计算模板匹配的结果矩阵res,res = self._get_template_result_matrix()

def _get_template_result_matrix(self):
    """求取模板匹配的结果矩阵."""
    # 灰度识别: cv2.matchTemplate( )只能处理灰度图片参数
    s_gray, i_gray = img_mat_rgb_2_gray(self.im_search), img_mat_rgb_2_gray(self.im_source)
    return cv2.matchTemplate(i_gray, s_gray, cv2.TM_CCOEFF_NORMED)

可以看到最终用的是openCV的方法,cv2.matchTemplate,那个优先匹配上就返回结果。

4 总结

使用过程中可以发现Airtest框架有两个缺点:一是对于背景透明的按钮或者控件,识别难度大;二是无法获取文本内容,但这一缺点可通过引入文字识别库解决,如:pytesseract。
对不能用UI控件定位的部件,使用图像识别定位还是非常方便的。UI自动化脚本编写过程中可以将几个框架结合使用,uiautomator定位速度较快,但对于flutter语言写的页面经常有一些部件无法定位,此时可以引入airtest框架用图片进行定位。每个框架都有优劣势,组合使用才能更好的实现目的。

作者:京东物流 范文君

来源:京东云开发者社区文章来源地址https://www.toymoban.com/news/detail-489903.html

到了这里,关于Airtest图像识别测试工具原理解读&最佳实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 自动化测试工具airtest之上传文件或图片(web自动化上传图片)

    web自动化测试图片上传的方法: 第一种为当具有input标签时,如: input type=\\\"file\\\" name=\\\"file\\\" multiple=\\\"multiple\\\" 这类可以通过selenium中的send_keys()上传 直接实现: driver.find_element_by_css_selector(\\\"[type=\\\'file\\\']\\\").send_keys(r\\\"文件地址\\\")  第二种为当不是input标签时,将不能使用上述方法我们可以

    2024年02月06日
    浏览(46)
  • DDR压力测试工具memtester的源码解读和交叉编译

    最近公司的一款产品,核心板上的DDR由工业级的降为民用的,程序运行过程中容易出现内存泄漏的问题。所以再产品测试流程中增加DDR的压力测试。 使用最流行的开源工具 memtester 但是memtester默认测试循环次数太多,完成一次压力测试需要20多分钟不利于生产测试,于是需要

    2024年02月11日
    浏览(50)
  • AutoRunner自动化测试工具新版本智能识别算法之视觉识别

    泽众AutoRunner(简称AR)是国内专业的支持C/S、B/S各种技术框架的、基于组件识别的自动化测试工具,实现7*24小时的自动化回归测试和功能测试,让测试更智能。 视觉识别是一种通过计算机技术对图像或视频进行分析和理解的方法。这种算法能够将图像中的特征和模式与已知

    2024年02月11日
    浏览(32)
  • 802.11kvr无线漫游原理及漫游测试工具推荐

    常见支持漫游的无线组网场景主要有AC+AP组网、mesh组网两大类: (1)AC+AP 组网   网络中所有AP被AC集中管理,发射统一的无线SSID,终端连入该SSID网络中可在不同的AP点之间实现无缝漫游。 (2)mesh 组网   母子路由无线mesh组网,子节点配置全部受控于主路由以扩展无线信号

    2024年02月04日
    浏览(52)
  • 案例分享| T-Box功能自动化测试方案: 测试对象和原理分析 | 车内T-Box与手机端的交互流程 | 测试方案设计及实测结果 | T-Box功能自动化测试系统框架 | 软硬件工具组成及作用

    背景 T-Box是实现汽车车联网的一个关键环节,从起初单纯的实现车辆信息采集,已发展到具有车辆信息监测及信息交互(V2X)、车辆远程控制、安全监测和报警、远程诊断、边缘计算等多种离线和在线的应用功能的载体。为保障T-Box功能的正常运转,对其进行功能测试就尤为

    2024年04月13日
    浏览(109)
  • 精通api接口测试,接口分类,接口架构,http,webservice,dubbo接口协议,接口流程,接口工具,cookie,session,token接口鉴权原理以及实战

    接口口测试和接口自动化测试一直都是很多人混乱的概念。所以搞清楚2个的概念是很重要的一件事情。 接口:一段具备逻辑处理功能的程序代码组成的,可被其他方法、服务或应用所使用。 对于调用接口的那一方,可以把接口看做一只黑匣子,只需要负责按约定传入参数,

    2024年02月02日
    浏览(47)
  • 接口测试工具——Postman测试工具 & Swagger接口测试+SpringBoot整合 & JMeter高并发测试工具

    头部携带token 类型选择JSON https://apifox.com/ swagger2,较多 swagger3, Knife4j的前身是swagger-bootstrap=ui,前身swagger–bootstrap-ui是一个纯swagger–ui的ui皮肤项目 https://doc.xiaominfo.com/docs/quick-start 底层就是swagger 序号 注解 作用 1 @Api(tags = “图书的api接口类”) 左侧名字 2 @ApiOperation(“findPa

    2024年02月12日
    浏览(58)
  • 海康直连工具 海康测试工具,工程宝测试软件等

    海康直连工具 海康测试工具,工程宝测试软件等,监控工程调试软件,海康/大华,摄像头IP批量修改,摄像头密码重置,恢复出厂等各种工程测试软件,所有软件为app格式, 都是原厂最新版软件,别再问可不可以装在手机/平板/电脑上能不能用,这是工程宝专业测试软件用在

    2024年02月12日
    浏览(121)
  • 【测试工具】UnixBench 测试

    UnixBench 原本叫做 BYTE UNIX benchmark suite。软件为 Unix 类的系统提供了一些基本的性能指标。通过不同的测试来测试系统不同方面的性能(2D,3D,CPU,内存等等)。这些测试的结果将和一些标准的系统来做比较,从而得出一些性能指数,比原始 的测试数据容容易理解。 UnixBench一

    2024年01月16日
    浏览(42)
  • 自动化测试工具比传统测试工具的优势体现在哪里?

    随着软件行业的快速发展和扩张,自动化测试工具在提高测试效率和质量方面起到了不可或缺的作用,那你知道自动化测试工具比传统测试工具的优势体现在哪里吗?   首先,自动化测试工具能够大大缩短测试周期。相比于传统手动测试,自动化测试工具能够在短时间内执行

    2024年02月16日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包