通过adb与python结合创建的设备驱动脚本deviceDriver.py
来源:互联网 发布:mac aecc2017切换中文 编辑:程序博客网 时间:2024/05/23 11:06
#coding=utf8'''adb shell input关键命令如下:输入文本信息:adb shell input text <string> 例如:input text hello按键操作:adb shell input keyevent [--longpress] <key code or name>例如:input keyevent 1 或者 input keyevent KEYCODE_MENU点击操作:adb shell input tap <x> <y>例如:input tap 100 200滑动操作:adb shell input swipe <x1> <y1> <x2> <y2>例如:input swipe 0 0 100 100 截屏:adb shell screencap <filename>例如:adb shell screencap /sdcard/screen.png'''#用于获取设备临时文件存放目录import tempfile #调用系统命令popenimport os import re import time import xml.etree.cElementTree as ET class DeviceDriver(object): """ 通过元素定位,需要Android 4.0以上 """ def __init__(self): """ 初始化,创建一个设备对象,以及获取当前PC下临时文件的路径; 调用re库,创建一个以数字的模式对象。 """ #获取当前设备临时文件存放的目录 self.tempFile = tempfile.gettempdir() #创建一个以数字匹配的规则对象 self.pattern = re.compile(r"\d+") try: #创建设备连接的对象实例 self.devices=os.popen("adb wait-for-device ") except Exception: print u"连接设备....." finally: self.devices.close() #获取活动页面的UI信息文件 def __uidump(self): """ 获取设备当前活动页面的hierarchy的UI信息, 通过uiautomator dump命令把UI信息存放在uidump.xml文件中; 通过adb pull命令把uidump.xml文件下载到本地临时文件目录下 """ try: if self.devices: #获取设备当前活动页面的hierarchy的UI信息, #通过uiautomator dump命令把UI信息存放在uidump.xml文件中; dumpui=os.popen("adb shell uiautomator dump --compressed /data/local/tmp/uidump.xml") #通过adb pull命令把uidump.xml文件下载到本地临时文件目录下 pulldumpfile=os.popen("adb pull /data/local/tmp/uidump.xml " + self.tempFile) else: print u"查看设备是否连接....." except Exception: print "Get uidump.xml Fail...." finally: #关闭连接 pulldumpfile.close() dumpui.close() #获取元素的位置信息 def __element(self, attrib, name): """ 同属性单个元素,返回单个坐标元组 """ #调用函数,把uidump.xml文件存放在本地临时目录下 self.__uidump() try: #把uidump.xml文件转换成元素tree tree = ET.ElementTree(file=self.tempFile + "\\uidump.xml") #使用iter方法对tree中标记为node进行深度遍历 #把node元素存放在treeIter中 treeIter = tree.iter(tag="node") #对treeIter总元素进行处理 for elem in treeIter: #进行元素属性批判的 #如果属性值相同执行下面命令 if elem.attrib[attrib] == name: #获取满足要求元素的bounds值 bounds = elem.attrib["bounds"] #获取页面元素是否可以点击属性 clickable=elem.attrib["clickable"] #通过数字匹配规则,把bouns合并成一个list coord = self.pattern.findall(bounds) #获取元素的X坐标 #通过把元素的左右边界的X坐标对减获取元素宽度 #把左边坐标值加上元素宽度的一半 #就获取了精确的X值 Xpoint = (int(coord[2]) - int(coord[0])) / 2.0 + int(coord[0]) #获取元素的Y坐标 #通过把元素的上下边界的Y坐标对减获取元素高度 #把上坐标值加上元素高度度的一半 #就获取了精确的Y值 Ypoint = (int(coord[3]) - int(coord[1])) / 2.0 + int(coord[1]) #返回元素的坐标 return (elem,Xpoint, Ypoint,clickable) except Exception: print "Get the position of element Error!" #获取属性值形同的元素列表 def __elements(self, attrib, name): """ 同属性多个元素,返回坐标元组列表 """ #用来放元素坐标 elementList = [] #调用函数,把uidump.xml文件存放在本地临时目录下 self.__uidump() try: tree = ET.ElementTree(file=self.tempFile + "\\uidump.xml") treeIter = tree.iter(tag="node") for elem in treeIter: if elem.attrib[attrib] == name: bounds = elem.attrib["bounds"] #获取页面元素是否可以点击属性 clickable=elem.attrib["clickable"] #通过数字匹配规则,把bouns合并成一个list coord = self.pattern.findall(bounds) Xpoint = (int(coord[2]) - int(coord[0])) / 2.0 + int(coord[0]) Ypoint = (int(coord[3]) - int(coord[1])) / 2.0 + int(coord[1]) #把元素坐标以元组添加到元素位置列表 elementList.append((elem,Xpoint, Ypoint,clickable)) return elementList except Exception: print "Get the list of the position of elements Error!" def findElementByName(self, name): """ 通过元素名称定位 usage: findElementByName(u"设置") """ return self.__element("text", name) def findElementsByName(self, name): return self.__elements("text", name) def findElementByClass(self, className): """ 通过元素类名定位 usage: findElementByClass("android.widget.TextView") """ return self.__element("class", className) def findElementsByClass(self, className): return self.__elements("class", className) def findElementById(self, Id): """ 通过元素的resource-id定位 usage: findElementsById("com.android.deskclock:id/imageview") """ return self.__element("resource-id",Id) def findElementsById(self, Id): return self.__elements("resource-id",Id) #点击元素 def ClickElement(self,dx,dy): try: if self.devices: tap=os.popen("adb shell input tap " + str(dx) + " " + str(dy)) else: print u"没有连接设备..." except Exception: pass finally: tap.close() #滑动设备屏幕 def swipeScreen(self,x1,y1,x2,y2): try: if self.devices: #滑动设备 swipescreen=os.popen("adb shell input swipe " + str(x1) + " " + str(y1) + " " + str(x2) + " " + str(y2)) else: print u"没有连接设备..." except Exception: pass finally: swipescreen.close() #换新屏幕 def wakeUp(self): try: if self.devices: #唤醒设备 wakeupDevice=os.popen("adb shell input KEYCODE_MENU") else: print u"没有连接设备..." except Exception: pass finally: wakeupDevice.close() def test(): driver = DeviceDriver() ele=driver.findElementByName(u"喜马拉雅FM") driver.ClickElement(ele[1], ele[2]) driver.deviceScreencap() time.sleep(1) if __name__=="__main__": test()
核心是通过adb shell uiautomator dump命令获取活动页面的UI信息,然后通过xml包,把文件转换成tree!
通过node节点中的属性获取元素元素坐标!
该脚本封装了
findElementByName,findElementsByName,findElementByClass,findElementsByClass,findElementById,findElementsById,ClickElement,swipeScreen,wakeUp等函数用来定位app的元素位置!
通过adb shell input 命令来操作元素的点击!
总结:
app自动化测试中的UI测试是测试的难点与头痛的地方,因为通过appium进行元素定位,不精确而且元素会经常变换,维护成本大!同时,appium环境部署相当复杂!该脚本能完成,元素定位于点击,屏幕滑动等功能!经过测试,操作响应比appium快的多!
后期我会根据把该脚本与monkeyrunner+unittest+robot framework整合在一起!如果写的不到位的希望补充~~~~~~~~~
下面是初步结合如下:
阅读全文
0 0
- 通过adb与python结合创建的设备驱动脚本deviceDriver.py
- deviceDriver.py与robot framework结合使用的简单实例
- 解决ADB server didn't ACK的py脚本
- py脚本得到Python的版本
- matlab调用Python的.py脚本文件
- 动态安装android设备的adb驱动
- 通过adb命令连接特定的设备
- (三)NT驱动基础——创建驱动设备 并 实现驱动与应用程序的通信
- adb通过wifi连接pc端与android设备
- 如何通过adb命令获取手机型号与设备信息
- 如何通过adb命令获取手机型号与设备信息
- 如何通过adb命令获取手机型号与设备信息
- Python中创建了与已有模块同名的.py文件
- python 脚本 .py文件执行
- python:脚本:1:AdapterRemoval_statistics_sample.py
- linux驱动之设备号与创建设备节点
- 通过脚本创建数据库与表
- RDP与嵌入式设备的结合
- android studio3.0 kotlin配置Anko
- 从尾到头打印链表
- 分形三角形
- SaltStack实战之远程执行-Returners
- Leetcode-Merge Two Sorted Lists
- 通过adb与python结合创建的设备驱动脚本deviceDriver.py
- [转]有return的情况下try catch finally的执行顺序(最有说服力的总结)
- 重建二叉树
- 使用多张图片做帧动画的性能优化
- Mac构建Protobuf
- Leetcode 152 Maximum Product Subarray
- 贪心+并查集
- Fork and Join: Java也可以轻松地编写并发程序
- 170609 逆向-VB的自然编译和伪编译