首页 > 其他分享 >【速看】如何通过合理的封装,让你的自动化脚本更上一层楼!

【速看】如何通过合理的封装,让你的自动化脚本更上一层楼!

时间:2023-10-27 11:15:28浏览次数:37  
标签:__ 封装 screen tpl 速看 更上一层楼 time 矩形 rect

此文章来源于项目官方公众号:“AirtestProject”
版权声明:允许转载,但转载必须保留原链接;请勿用作商业或者非法用途

1. 前言

上一篇推文利用一个在图片范围内实现随机坐标点击的例子,去教会大家如何将自己想要的效果实现出来,受到大家的热情反响,在我们官方讨论群中,还有大佬对我们的示例代码进行优化改进,做了很多合理的函数封装,以及减少了示例脚本内的二次查找等问题;我们也征得大佬同意,将他的代码与大家分享一下~(大佬来自Airtest官方讨论3群-Moty)

2. 代码分享

Moty同学是通过在本地python环境安装Airtest库去进行Airtest自动化脚本编写的,同时该脚本在AirtestIDE上是可以完美适配运行的。所以大家在编写自动化脚本的时候,可以有多重选择;但是AirtestIDE在代码编写上也有很多方便大家的小设计小巧思,大家也可以多多使用我们的AirtestIDE啊~

废话不多说,我们先来看看Moty同学代码的运行情况,可以看到通过生成随机坐标的形式,点击图片上的任意点,这里用计算器去具象化,可以看到每次随机坐标可以点击不同数字或者数字的不同位置,每次运行都可以获得随机的数字序列。

看起来很厉害的样子,我们应该这么去实现呢,让我们来看看Moty同学的代码吧~

# -*- encoding=utf8 -*-
__author__ = "Moty"

from airtest.core.api import *
from airtest.cli.parser import cli_setup
from airtest.core.error import *
from airtest.core.settings import Settings as ST
import random

"""
获取模板匹配的目标区域的矩形 这一部分实现参考 cv.py 中 loop_find 部分
: param : tpl 模板
: param : intervalfunc 没有合适匹配时的回调函数
: return 最佳匹配的矩形区域(x1,y1,x2,y2)
"""

def rectangle(tpl,intervalfunc=None):  
    G.LOGGING.info("Try finding: %s", tpl)
    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:
            match_result = tpl._cv_match(screen)
            if match_result:
                try_log_screen(screen)
                # 这里 rect 得到的是 4个坐标点 取出左上右下角 得到(x1,y1,x2,y2) 元组
                rect = match_result.get("rectangle")
                if rect is not None:
                    return (round(rect[0][0]) , round(rect[0][1]) , round(rect[2][0]) , round(rect[2][1]))

        if intervalfunc is not None:
            intervalfunc()

        # 超时则raise,未超时则进行下次循环:
        if (time.time() - start_time) > ST.FIND_TIMEOUT:
            try_log_screen(screen)
            # 如果超时,则抛出异常
            raise TargetNotFoundError('Picture %s not found in screen' % tpl)
        else:
            time.sleep(0.5)

"""
param : rect : 矩形区域 或模板
return : 区域内的随机坐标 
"""

# 获取矩形区域内的随机坐标
def random_point(rect):
    # 如果传入的是图片,则获取图片匹配的矩形区域
    if isinstance(rect, Template):
        x1, y1, x2, y2 = rectangle(rect)
    else:
        x1, y1, x2, y2 = rect
    # 在矩形区域内随机生成一个坐标点
    x = random.randint(x1, x2)
    y = random.randint(y1, y2)
    return x, y

"""
在 矩形范围内 随机点击 
param : v : 目标区域 or 模板 or 坐标点(兼容touch)
param : times : 点击次数
return :最终点击的点的坐标
"""
@logwrap
def random_touch_in_area(v, times=1, **kwargs):
    if isinstance(v, Template) or (isinstance(v, tuple) and len(v) == 4):
        pos = random_point(v)
    else:
        try_log_screen()
        pos = v
# 在目标区域内随机点击
    for _ in range(times): 
        G.DEVICE.touch(pos, **kwargs) 
        time.sleep(0.05)  
    delay_after_operation()  
    return pos


if __name__ == '__main__':

    # 如果没有通过命令行连接设备,则使用该连接命令,若使用IDE运行则可忽略这段代码,不用写上
    if not cli_setup():
        auto_setup(__file__, logdir=None, 
                devices=["android:///",])

    # 录制图片
    tpl = Template(r"tpl1697636105500.png", record_pos=(0.243, -0.165), resolution=(1080, 2280))

    # 获取模板匹配的目标区域的矩形
    result = rectangle(tpl)
    print(f"图片所在矩形区域 {result}")

    # 在目标区域内随机点击
    for i in range(10):
        p =  random_touch_in_area(tpl)
        print(f"第 {i+1:02d} 次点击坐标 {p}")
        sleep(1)

可以看出来,在编写代码的时候,Moty同学将每一个步骤进行函数封装后,可以减少二次查找的次数以及代码冗余,Moty同学的编写思路很值得我们学习~

3.小结

最后,希望同学们在学习以及使用Airtest的时候,可以先学习方法,掌握代码编写技巧后,对自己的脚本可以进行优化再优化,从而实现代码收益最大化。同时,我们也鼓励大家在学习我们的官方教程脚本的时候,进行优化再创作,也可以到我们官方Q群进行投稿噢~

官方Q群:目前1、2、3群已满,大家可以加入4群(117973773)。

这里附上我们官方教程文档的网址,欢迎同学们查阅哦:https://airtest.doc.io.netease.com/


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

官方答疑 Q 群:117973773

标签:__,封装,screen,tpl,速看,更上一层楼,time,矩形,rect
From: https://www.cnblogs.com/AirtestProject/p/17791404.html

相关文章

  • C++封装数据结构
    1.概论C++STL之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector,string,list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以......
  • 微信小程序--3.request.ts文件封装
    3.request.ts文件封装api.tsimportrequestfrom'./request'//获取tokenexportfunctioninit(data:object){returnrequest({url:'/api/wechat_mini/auth/wx_init',data})}request.tsconstapp=getApp();//提示语方法functio......
  • PC3221单节锂电池充电器芯片ESOP8封装高耐压输入
    特性输入耐压28V输出耐压15V输入过压保护7V短路保护高达1A可编程充电电流精度1%的4.2V预设充电终止电压防电池反接无需MOSFET、检测电阻或隔离二极管在无过热危险的情况下实现充电速率最大化的热调节功能ESOP8/DFN2x2-8/DFN2x3-8/DFN3x3-8封装符合RoHS标准描述PC3221是......
  • Java中将Byte[] 转成封装类型
    今天做一个需求,需要将byte[]类型转换为Double和String,因此整理起来 Doublebyte[]转doublepublicDoublebyteArrayToDouble(byte[]bytes){if(bytes.length!=8){thrownewIllegalArgumentException("数据长度不符");}longlongBits=0;for(inti=0;i<8......
  • 统一封装结果集和异常类
    1封装统一返回结果类publicclassAjaxResult{//是否成功privateBooleansuccess;//状态码privateIntegercode;//提示信息privateStringmsg;//数据privateObjectdata;publicAjaxResult(){}//自定义返回结果......
  • 基于ZCU104的PS和PL数据交互例程(二):vivado中封装现有工程成IP
    基于ZCU104的PS和PL数据交互例程(二):vivado中封装现有工程成IP设计DUT功能正常创建一个vivado工程,添加一个dut.v的文件功能:读入100个输入数据,每个数据依次加0,1,2,...,然后输出。比如输入是0到99,则输出是0,2,4,到198,如下图所示。状态机:时序图:端口情况:创建vivado工程正常创建新......
  • 自己封装的一些算数工具方法
    工作中计算的比较多,自己封装了一些工具方法,感觉还是挺好用的。packagecom.yunmeng.iot.common.utils;importjava.math.BigDecimal;importjava.math.RoundingMode;importjava.util.List;importjava.util.Objects;importjava.util.function.Function;importjava.util......
  • app应用程序该如何封装,能提升产品价值和用户体验感
    哈喽各位同学们好,我是咕噜铁蛋,咱们又见面了。之前我和大家聊了好多苹果文件签名的小知识,今天咱们换个口味讲讲别的内容---封装。随着移动应用市场的蓬勃发展,用户对应用的期望也变得更高。一个成功的应用不仅仅要具备功能完善和界面美观的特点,还需要在用户体验和产品价值方面提供差......
  • 第二章 第一二节 Map替换实体类,封装响应结果和全局异常处理
    项目前期准备一.Map代替实体类与数据库交互1.Map的优点​ 灵活性强于JavaBean,易扩展,耦合度低​ 写起来简单,不用每次都修改​ 易于mybatis数据库操作​ 缺点:不能直接明显看出map中的参数2.javaBean的优缺点​ 优点:更符合java语言的规则,且名字可以直接看出​ 缺点:需要......
  • 封装分页
    实现分页代码的封装,方便以后其他代码的调用在project/app01/目录新建utils文件夹文件夹下新建pagination.py文件pagination.py"""自定义分页组件以后如果想要使用这个分页组件,需要做:在视图函数中:fromapp01.utils.paginationimportPaginationdefprettynum_......