如何用覆盖函数的方式,实现你自己的touch?

此文章来源于项目官方公众号:"AirtestProject"

版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途

1、前言

在使用Airtest进行日常测试工作中,我们有时候想针对某个接口进行功能增强,或者增加一些错误处理和重试机制,但是又不想直接修改Airtest源码,因为担心更新Airtest库就会覆盖掉源码的修改。

这个时候,我们更推荐大家使用python覆盖函数的方式处理,通过覆盖函数的方式改变函数的行为是一种常见的编程技巧,既能让我们的代码保持灵活性,又避免了直接修改源码库。

下文我们将一起来看下覆盖函数在Airtest框架下的应用小案例.。

2、示例

我们以覆盖Airtest里的touch接口为例,来一起体验下覆盖函数的魅力:

2.1 新建一个new_touch脚本文件并导入需要覆盖的函数

新建一个new_touch脚本文件,并将我们需要增强的函数或某个语句先导入并取一个与原函数不冲突的别名。

python 复制代码
from airtest.core.api import touch as old_touch

这一行代码表示从 airtest.core.api 模块中导入了touch函数,并将其重命名为old_touch 。这样做的目的是保留原有的touch函数,以便在新函数中调用。

2.2 开始定义覆盖函数

在新建的**new_touch**文件下,可以正常调用旧函数并结合实际场景去增加所需要增强的功能,去实现想要达到的效果。

python 复制代码
from airtest.core.api import *
from airtest.core.api import touch as old_touch

def touch(pic):

    try:
	#若打开App后是进入的学习积分界面,即可直接点击

        old_touch(pic)
        print("进入的是学习积分界面")

    except TargetNotFoundError:
	#若打开App后是进入的App首页界面,需要先点击积分

        print("进入的是首页界面")
        old_touch(Template(r"tpl1712044513750.png", record_pos=(0.267, -1.05), resolution=(1080, 2520)))
        
        print("现在进入了学习积分界面")
        
	#跳转到对应的学习积分界面后再进行点击
        old_touch(pic)

2.3 在脚本中导入新函数以覆盖旧函数

创建一个新的跑测脚本,并将new_touch文件放到与跑测脚本同一文件夹下,使用import导入new_touch文件的touch用法,就可以直接使用我们修改后的touch用法。

python 复制代码
# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *

from new_touch import touch

#打开进入学习强国App
start_app("cn.xuexi.android")


#尝试点击选读文章任务跳转
touch(Template(r"tpl1712044077691.png", target_pos=6, record_pos=(-0.006, 0.261), resolution=(1080, 2520)))

在需要使用新的touch函数的脚本中,首先从airtest.core.api导入所有内容,然后从定义了新touch函数的模块(这里该模块名为new_touch)导入新的touch函数。由于Python的名称解析是从左到右的,后导入的同名函数会覆盖先前导入的函数,因此这样做可以确保新的touch函数覆盖了原始的 touch 函数。

2.4 最终效果

2.5 覆盖函数的功能增强

在了解完一个简单的覆盖函数示例之后,我们可以再来看一个稍微复杂点的小案例,就是利用覆盖函数,给旧函数增加一些错误处理操作或者错误log记录等。依然以Airtest的 touch 接口为例:

参考代码如下:

在新的touch函数里,我们增加了一些错误记录,并截图错误场景,将报错抛出,在日常点击的时候可以更精准的去判断报错出现的场景以及原因。

python 复制代码
from airtest.core.api import *
from airtest.core.api import touch as old_touch
import logging

# 初始化日志记录器
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
"""
param target: 点击目标,可以是图片(Template)或坐标。
param timeout: 超时时间,单位为秒。
param retry_interval: 重试间隔时间,单位为秒。
"""

def touch(target, timeout, retry_interval):

    start_time = time.time()  # 记录开始时间
    while True:
        try:
            # 尝试点击目标
            old_touch(target)
            logger.info(f"成功点击图片")
            break  # 点击成功则退出循环
            
        except TargetNotFoundError:
			#计算超时时间
            current_time = time.time()
            elapsed_time = current_time - start_time

            if elapsed_time > timeout:

                # 如果超时,则捕获异常并记录错误信息
                logger.error(f"在指定的超时时间 {timeout} 秒内未找到目标图片")

                # 捕获屏幕截图以供后续分析
                snapshot(filename=f"error_{current_time}.png")
                raise  # 重新抛出异常,或者可以选择其他的错误处理方式

            else:
                 # 没有超时,则等待一段时间后重试
                logger.info(f"未找到目标图片,{retry_interval} 秒后重试...")
                time.sleep(retry_interval)
                continue

        except Exception as e:
            # 捕获其他可能的异常,并记录
            current_time = time.time()
            logger.error(f"点击图片时发生未知错误: {e}")

            # 捕获屏幕截图以供后续分析
            snapshot(filename=f"error_{current_time}.png")
            raise  # 重新抛出异常,或者可以选择其他的错误处理方式

调用方式跟刚才简单的案例一样,从 enhanced_touch 文件中 import 新的touch进来,需要注意 importtouch 的语句一定放在 from airtest.core.api import * 之后,确保覆盖。

python 复制代码
# -*- encoding=utf8 -*-
__author__ = "Airtest"

from airtest.core.api import *
from enhanced_touch import touch

auto_setup(__file__)

start_app("cn.xuexi.android")

#调用修改后的touch,并传入需要识别的图片、超时时间、重试间隔时间
touch(Template(r"tpl1712113066466.png", record_pos=(0.298, 0.285), resolution=(1080, 2520)), timeout=10, retry_interval=5)

3、小结

函数覆盖是一种强大的技术,可以在不改变原始代码的情况下调整、增强或替换现有功能。不过,这种技术也需要谨慎使用,因为它可能会导致代码的可读性和可维护性降低,尤其是在覆盖的函数逻辑变得复杂时。正确的文档记录和清晰的代码结构对于维护这种类型的代码至关重要。

我们的样例仅供参考,不一定适用于所有场合,同时也欢迎大家给我们投稿自己写的覆盖函数或封装函数,我们也会多多分享更多的相关的使用技巧。让我们一起努力,共同进步~


AirtestIDE下载airtest.netease.com/
Airtest 教程官网airtest.doc.io.netease.com/
搭建企业私有云服务airlab.163.com/b2b

官方答疑 Q 群:526033840

相关推荐
XH华3 小时前
初识C语言之二维数组(下)
c语言·算法
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
拭心4 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
不想当程序猿_4 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
落魄君子4 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
菜鸡中的奋斗鸡→挣扎鸡4 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin4 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码5 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7245 小时前
LILAC采样算法
人工智能·算法·机器学习
菌菌的快乐生活5 小时前
理解支持向量机
算法·机器学习·支持向量机