python + uiautomator2测试框架搭建

一、介绍

        uiautomator2 是一个可以使用Python对Android设备进行UI自动化的库,仅支持Android平台的原生应用测试。。其底层基于Google uiautomator,Google提供的uiautomator库可以获取屏幕上任意一个APP的任意一个控件属性,并对其进行任意操作。它提供便利的python接口。允许测试人员直接在PC上编写Python的测试代码,操作手机应用,完成自动化测试,大大提高自动化代码编写的效率。 

        原理解释:
        python端:运行脚本,往移动端发送HTTP请求
        移动端:安装atx-agent,然后atx-agent启动uiautomator2服务进行监听,并识别python脚本,转换为uiautomator2的代码。
        移动设备通过WIFI(同一网段)或USB接收到PC上发来的HTTP请求,执行制定的操作
​​​​​​​
二、安装

        安装 uiautomator2,
                命令行窗口:pip install -U uiautomator2
        设备安装atx-agent:                         

# init就是所有USB连接电脑的手机上都安装uiautomator2
python -m uiautomator2 init


三、安装weditor

        在APP自动化测试是,需要使用到元素定位,UI元素定位的工具--WEditor,方便我们快速的识别手机上的元素,方便写代码。WEditor能够提供辅助编写脚本,定位元素,调试代码等功能,是基于python的一个查看APP元素的工具。
        安装命令:pip install weditor==0.6.4  
        由于直接命令pip install weditor会报错,解决方法 太麻烦,所以直接降版本安装。
        查看安装是否成功:weditor --help
        使用:命令行窗口输入:python -m weditor   ,默认启动后,会直接在本地打开一个网页,接下来的操作都可以只在这个网页完成。


四、操作及应用

        1、链接手机

        device = uiautomator2.connect()  ,用的最多的是默认只有一台连接,或指定序列号链接。

import uiautomator2 as u2

#链接设备,这里是通过adb链接手机的;所以要提前装好adb;并能够adb devices发现该设备;
#用的最多的是默认的和指定序列号的,最方便
#不提供参数,默认连接方式,适用于只有一台设备
#device = u2.connect()

#有多台设备,指定设备ip,通过USB链接, 我的设备序列号是127.0.0.1
#device = u2.connect('127.0.0.1')

#通过wifi链接,设备IP要和PC在同一网络;在夜神模拟器,查到的序列号和ip同样
#device = u2.connect_wifi('127.0.0.1')

#打开被测试的app
device(text='浏览器').click()

注:用adb devices 查看当前pc链接的所有设备。

        2、APP操作:安装、卸载、启动

        这些操作都需要 用到app 的包名:device.app_current()

import uiautomator2 as u2

#链接设备,这里是通过adb链接手机的;所以要提前装好adb;并能够adb devices发现该设备;
#用的最多的是默认的和指定序列号的,最方便
#不提供参数,默认连接方式,适用于只有一台设备
#device = u2.connect()

#有多台设备,指定设备ip,通过USB链接, 我的设备序列号是127.0.0.1
device = u2.connect('127.0.0.1')

#通过wifi链接,设备IP要和PC在同一网络
#device = u2.connect_wifi('127.0.0.1')

#安装apk
#device.app_install("http://www.baidu.com/abc.apk")

#获取正在运行的apk的包名
pkgname = device.app_current
print(pkgname)

#卸载app,参数是包名
#device.app_uninstall(pkgname)

#启动app,传入要打开apk 的包名
device.app_start(pkgname)
#点击启动,打开被测试的app
device(text='浏览器').click()

#关闭app
device.app_stop(pkgname)

#清楚APP的数据,通常测试时不希望上次测试的动作影响下一次的测试;所以可以清除一下
device.app_clear(pkgname)

        3、获取pkg_name

                通过代码获取正在运行的APP包名:

#获取所有正在运行的APP包名
print(device.app_list_running())
#获取当前正在运行的APP包名
print(device.app_current())

                adb指令获取:在命令行窗口输入命令

adb shell dumpsys activity | find "mFocusedActivity"
adb shell dumpsys activity top | findstr ACTIVITY 

        4、设备操作

                获取设备信息


#以字典的形式打印设备信息
print(device.info)
# 获取窗口大小
print(device.window_size())
# 获取当前应用程序信息。对于某些android设备,输出可以为空
print(device.current_app())
# 获取设备序列号
print(device.serial)
# 获取WIFI IP
print(device.wlan_ip)
# 获取详细的设备信息
print(device.device_info)

        5、截图        

#截屏,两种方式,
#先截后存
image = device.screenshot()
image.save("image_path.jpg")
# 截屏并保存
device.screenshot("image_path.")

        6、文件推拉

# 推送到文件夹
device.push("text.txt", "/sdcard/")
# 推送后重命名
device.push("text.txt", "/sdcard/new_name.txt")
# 推送 fileobj
with open("text.txt", 'rb') as f:
    device.push(f, "/sdcard/")
# 推动和更改文件访问模式,755是Linux里的7:可读可写可执行;
device.push("text.sh", "/data/local/tmp/", mode=0o755)

#拉取文件
device.pull("/sdcard/text.txt", "text.txt")
# 如果在设备上找不到文件,FileNotFoundError将引发
device.pull("/sdcard/file_not_exists.txt", "text.txt")

        7、按键操作

device.screen_on()#打开屏幕 
device.screen_off() #关闭屏幕

device.press("home") # 点击home键
device.press("back") # 点击back键
device.press("left") # 点击左键
device.press("right") # 点击右键
device.press("up") # 点击上键
device.press("down") # 点击下键
device.press("center") # 点击选中
device.press("menu") # 点击menu按键
device.press("search") # 点击搜索按键
device.press("enter") # 点击enter键
device.press("delete") # 点击删除按键
device.press("recent") # 点击近期活动按键,最近浏览的APP
device.press("volume_up") # 音量+
device.press("volume_down") # 音量-
device.press("volume_mute") # 静音
device.press("camera") # 相机
device.press("power") #电源键

#更多具体查看Android keyCode

五、元素定位

        UiAutomator定位用于Android APP的元素定位,使用UI Automator API(UISelector类)来搜索特定元素。Android APP页面布局用的是xml 可扩展标记语言,类似于HTML,可以粗俗的把元素定位理解为HTML的元素定位;下面是 UiSelector 类的一些常用接口使用方法。

        元素定位辅助工具:weditor,UI元素定位的工具--WEditor,方便我们快速的识别手机上的元素,方便写代码。WEditor能够提供辅助编写脚本,定位元素,调试代码等功能,是基于python的一个查看APP元素的工具。weditor运行时,会在浏览器打开一个页面,这个页面辅助我们定位APP上的元素。

        命令行窗框输入:weditor ,会在浏览器打开页面,手机上的内容就全部展示在浏览器上;相当于web页面打开 F12控制台一样效果。左侧,相当于手机页面,可以直接操作;中间显示元素属性,相当于F12控制台;右边显示录制脚本的代码。右下Hierarchy,点击名称,显示元素控件位置。

        最上面部分,是管理手机的,例如Android、ios;例如链接那台手机;dunp Hierarchy 刷新;
        weditor优势在于:一、可以同时管理多台设备;二、直接在调试界面操作手机,不需要另一只手去动手机;三、右边coding区自动生成脚本对应 python 代码。

        元素构成:控件由空间名称、控件属性、子控件构成;每个控件的控件名称、属性,都可以weditor页面中间模块找到;根据名称、属性,找到对应控件,指定执行操作,名称和属性可以组合使用。

        定位方式:根据weditor中间模块的 prop结构词定位;ui2支持 android 中 UiSelector 类中的所有定位方式。具体参考官方文档

名称描述
texttext是指定文本的元素
textContainstext中包含有指定文本的元素
textMatchestext符合指定正则的元素
textStartsWithtext以指定文本开头的元素
classNameclassName是指定类名的元素
classNameMatchesclassName类名符合指定正则的元素
descriptiondescription是指定文本的元素
descriptionContainsdescription中包含有指定文本的元素
descriptionMatchesdescription符合指定正则的元素
descriptionStartsWithdescription以指定文本开头的元素
checkable可检查的元素,参数为True,False
checked已选中的元素,通常用于复选框,参数为True,False
clickable可点击的元素,参数为True,False
longClickable可长按的元素,参数为True,False
scrollable可滚动的元素,参数为True,False
enabled已激活的元素,参数为True,False
focusable可聚焦的元素,参数为True,False
focused获得了焦点的元素,参数为True,False
selected当前选中的元素,参数为True,False
packageNamepackageName为指定包名的元素
packageNameMatchespackageName为符合正则的元素
resourceIdresourceId为指定内容的元素
resourceIdMatchesresourceId为符合指定正则的元素

示例代码:        

import uiautomator2 as u2
#导入元素定位辅助工具
import weditor

#adb连接手机
device = u2.connect('127.0.0.1')

#定位元素并操作;这些属性可以组合使用
device(text='浏览器').click()
#或者先定位,后操作
element = device(textStartsWith='浏览')
element.click()

         子元素和兄弟定位

                根据上下级关系进行定位;上级:页面的外层;下级:页面的内层;同级:sibling,同一级。        

#子元素定位:
#查找类名为android.widget.ListView下的Bluetooth元素
device(className="android.widget.ListView").child(text="Bluetooth")

#兄弟元素定位
element = device(textContains='个人中心', className='android.widget.TextView')
#若是只有一个兄弟元素,可以不用传参
element.sibling(text='购物车').click()

        相对位置定位

                相对定位可以定位某个元素的前后左右元素,定位速度慢,因为要做页面渲染;不建议用。括号里面可以添加相对定位的目标元素结构词方法,不添加,则默认选择对应位置的第一个元素。

element = device(textContains='个人中心', className='android.widget.TextView')
 
element.left(text='评价').click()  #不填参数,则默认左边第一个元素
element.right(text='购物车').click()
element.up(text='付款').click()
element.down(text='订单').click()

        元素常用api:如 element.exists() ,判断 element 元素是否存在。

方法描述返回值备注
exists()判断元素是否存在True,Flase@property装饰的类属性方法
info返回元素的所有信息字典@property装饰的类属性方法
get_text()返回元素文本字符串
set_text(text)设置元素文本None
clear_text()清空元素文本None
center()返回元素的中心点位置(x,y)基于整个屏幕的点


        

六、APP操作:点击、拖动、滑动、长按

        点击: click:        
        device(text='').click() ,通过元素定位;
        device.click(x,y) 通过全局坐标点击,元素定位不便时使用;

        滑动:device.swipe

        输入:先定位元素,再输入;
                输入:element.send_keys()
                清空:element.clear_text()

七、智能等待

        强制等待是 time.sleep(5);这个等待时间是固定的,智能等待,等待事件完成,然后开始进行下一步;主要有:
        device.app_start('package_name',wait=true)  ;等待APP启动完成;不需要time.sleep(),加上wait=true;
        device.wait_activity()
        device(text'='button').wait()  等待button元素出现
        device(text='password').wait_gone()  等待password元素消失
        device().exist()         等待元素是否存在
        device.implicitly_wait()      设置等待超时时间,也可单独给元素设置;如device().click(tiimeout=10)。
​​​​​​​        等待点击,设置隐式等待后: click() ,  clear_text()
        
八、toast

        展示及获取toast弹窗信息

#展示toast信息
device.toast.show("Hello world")

#获取toast信息
device.toast.get_message()

九、案例实战

        

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值