飞道的博客

App-UI自动化测试(Airtest+Pycharm)

483人阅读  评论(0)

对Airtest+poco框架的理解:

1.Airtest是一个跨平台的,基于图像识别的UI自动化测试框架,适用于游戏测试和App测试,可以脱离Airtest IDE,使用Pycharm进行脚本编写和运行,支持平台有Windows,Android和IOS。
2.Airtest Project包含了两个框架,一个是Airtest,一个是Poco,两个框架其实都是Python的第三方库。在脚本编写过程中,可以引用其他的库来加强自己的脚本。
3.通俗来说,Airtest用来做自动化测试,其实就是基于图像识别来模拟手动的一些点击操作,本人在工作中运用到的这个框架和poco操作,是对用例的自动化实现,基于用例来编写自动化脚本。

关于封装poco方法

使得在Pycharm中能够正常使用poco操作:

import unittest
from utx import *
from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

这是测试框架中引用的头文件及一些声明,想要使用poco的操作,就要先实例化poco对象

poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

这一行就是实例化poco对象的一个说明,通过这一行实例化poco对象了之后就可以使用poco中已经封装好了的操作;

Airtest使用的图像识别算法:

默认情况下,Airtest会尝试用 SURFMatching 、TemplateMatching 和 BRISKMatching 这三种算法来进行图像识别
TemplateMatching 属于模板匹配算法
SURFMatching 和 BRISKMatching 则属于特征点匹配方法。
简单点说,模板匹配算法依赖特征向量来进行图像匹配,而特征点匹配算法则是依赖于图像的特征点 。这些算法对于设备画面上唯一的图标,图像的识别效果会比较好,因为它们拥有较多的特征向量/特征点,而对于纯文字截图、含有大量空白背景的截图,识别效果会差一些。我们都知道,纯文字截图中仅仅包含了一些简单的笔画,特征向量/特征点会比较少,像对于图像来说,更容易识别到错误的结果。而空白背景的截图,各个像素点的灰度值基本没有什么变化,所以特征点几乎没有,就更容易找不到匹配结果或者匹配到天差地远的结果出来。

程序如何根据算法结果判定是否找到匹配的截图

那当我们编写好截图脚本,并开始运行的时候,程序是如何用这些图像识别算法来帮助我们判定是否识别到结果的呢?
这里先说明两个关键性名词:阙值和可信度,它们的取值范围都是【0,1】,在每一条图像识别的脚本中,都会有1个用于结果筛选的阙值。当前我们脚本中设置默认的是threshold=0.8(可在【0,1】范围内自行调整)

touch(Template(r"D:/CompTest/png/sousuo.png", threshold=0.8, rgb=True, resolution=(width,height)))
self.assertIsNotNone(Template("D:/CompTest/png/Browser/40.7.2/搜索框/hahajieguo.png", threshold=0.8, rgb=True, resolution=(width,height)))

当三种算法在执行过程中识别到初始结果时,就会计算出来这个初始结果的可信度,即根据当前截图与设备页面的识别度去计算出当前截图的可信度。当截图的可信度>设置的阙值,程序会认为找到了最佳的匹配结果,即成功识别到,反之则认为在当前设备页面没有找到匹配的图片与截图适配。则无法继续执行脚本。
我们可以在执行截图脚本的时候,查看log窗口,观察算法识别结果的可信度。如下图’confidence显示的‘所示:(识别到的可信度为0.99) ,大于设置的0.8,即说明在当前设备页面上找到了最佳匹配的图片。

[02:51:22][DEBUG]<airtest.core.api> try match with TemplateMatching
[02:51:22][DEBUG]<airtest.aircv.template_matching> [Template] threshold=0.8, result={‘result’: (600, 750), ‘rectangle’: ((548, 714), (548, 787), (653, 787), (653, 714)), ‘confidence’: 0.9948793053627014}
[02:51:22][DEBUG]<airtest.aircv.template_matching> find_best_result() run time is 0.04 s.

截图和poco操作的共用用法
1.模拟点击

#基于图片识别
touch(Template(r"D:/CompTest/png/caidan.png", threshold=0.8, rgb=True, resolution=(1080, 2400)))
#基于坐标点击,x,y均为浮点数
touch((x,y))
#基于resourse id点击
poco("resourse id").click()
poco("resourse id").long_click(duration=2)  #对某一resourse id的元素长按,长按2s
#基于文本内容点击
poco(text='文本内容').click()
poco(text='').long_click(duration=2) #对某一文本内容的元素长按,时间2s
#双击
double_click(v)  #v代表文字或者需要触摸点击屏幕的坐标

2.设置断言

#基于跳转页图标作为断言
assert_exists(Template("D:/CompTest/png/shezhi.png", threshold=0.8, rgb=True, resolution=(1080, 2400))) #判断目标图片是否存在
assert_not_exists()  # 判断目标图标是否不存在
#基于文字识别断言
print(poco(text='').exists()) #判断text=''内容是否存在
#基于resourse id识别断言
print(poco("resourse id").exists()) #判断对应resourse id是否存在

注意:用图片assert_exists, self.assert_exists等的这种方式作为断言的话,如果找不到对应断言的图片,脚本是会报错的;但是用文字或者resourse id来作为断言去判断的话,只会在脚本日志中显示True,False,毕竟是print的结果,所以针对不同场景不同使用,对于使用脚本的同学来看图片的方式更为准确,因为不需要看日志,但是对图片的要求会比较高,有时候截图下来的图片确实存在但可能就是识别不到,所以写脚本的时候需要多次尝试,但是对于写脚本的同学来说当然是文本或者resourse id更为方便,图片或者图标可能会随着版本大改或者小改而变化,但是文本或者resourse id很少会发生变化,用来断言更为方便。

3.模拟输入

text("",enter=True) #直接输入文本内容,输入完默认回车,可修改True为False即取消回车
poco("resourse id").set_text("文本内容")
poco("输入框").set_text("文本内容")

4.屏幕滑动

width,height = poco.get_screen_size() #获取设备屏幕尺寸
swipe((0.5 * width, 0.5 * height), vector=(0, 0.5), duration=0.1) #vector内参数表示方向,duration控制滑动时间
#根据坐标进行滑动
poco.swipe( [0.5,0.8] , [0.5,0.2] ) #使用相对坐标,第一个为起始坐标,第二个为终点坐标

5.常用keyevent按键(用keyevent事件代替手机设备的物理按键)

 KEYCODE_ENTER                #回车键
 KEYCODE_HOME                 #HOME键
 KEYCODE_POWER                #电源键
 KEYCODE_BACK                  #返回键
 KEYCODE_VOLUME_UP(DOWN)     #音量加减

6.if判断当前页面元素是否存在

#基于图片判断
if exists(Template("D:/CompTest/png/shezhi.png", threshold=0.8, rgb=True, resolution=(1080, 2400))):
#基于文本
if poco(text=' ').exists()#基于resourse id
if poco("resourse id ").exists()

判断和断言的区别就在于,断言是相当于加一层“保险”,因为你已经知道页面跳转后是会存在某一个元素的,加此断言去识别就是为了确保脚本执行的过程中运行到了这一步。
判断则是不确定页面跳转的元素是否存在,或者说是页面跳转可能会出现不同情况,则在此加入if判断,当跳转结果为1时该如何继续执行,当结果为2时又该如何。

7.用于进行某些页面跳转需要等待的场景

poco(text='xxx ').wait(10).click()  #10s内刷不到文本xxx就失败
poco(" resource id").wait(10),click() #10s内刷不到resource id一致的就失败 

8.长按拖动

poco(text='印地语').start_gesture().hold(2).to(poco(text='简体中文')).hold(2).up()
#将印地语长按拖动到简体中文的位置

9.屏幕上执行缩放操作

pinch(in_or_out=in, center=None, percent=0.5):

在屏幕上执行缩放操作,参数in_or_out表示要进行的是缩放还是放大,默认是in,表示缩放,out表示放大,只能枚举这两个值。center参数表示缩放的中心,默认是None,表示屏幕中心,如果是其他地方的话,则使用(x,y)来表示缩放的中心坐标。

将用例实现自动化脚本,最重要的是思路,上述的方法可以混用,但是在不同测试机上的行为还不一定能说百分百保证准确,还需要不断尝试,尤其是需要用到resourse id的部分,若是App升级迭代版本较多,由于各个版本不同,可能会导致其中页面元素的resourse id 不同,就会导致脚本在别的测试机上不适配。


转载:https://blog.csdn.net/gt5335/article/details/115081763
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场