通过python调用adb命令实现用元素名称、id、class定位元素

xiaoxiao2021-02-28  108

在Android自动化测试过程中,使用monkeyrunner可以通过坐标点击某个元素,但缺点是受屏幕分辨率影响,需要随时更改坐标位置。最近有使用了下Appium这个工具,优点是可以通过元素名称、id、class等属性定位,但是需要搭建稍微有点复杂的环境,然后我就想能不能不依赖任何环境,使用纯Python实现通过这几个属性定位,只需要直接执行python脚本就ok?接下来开始着手实现

首先需要Android版本高于4.0,使用这个命令“adb shell uiautomator dump”命令,执行“adb shell uiautomator dump /data/local/tmp/uidump.xml”,然后将该xml文件pull到本地,从里面可以看到手机上当前页面的布局,在note节点下可以找到这些属性:text,resource-id,class,bounds,知道这些内容后就可以使用python对该xml文件解析获取到对应的属性,取出bounds的值,计算出对应元素区域的中心坐标,接着使用adb shell input tap 命令就可以点击该坐标,如果有相同的属性值,那就需要得到一个坐标点的列表,以应用“1号店“为例,在桌面上通过应用名称“1号店”,点击进入应用,然后点击“手机充值”,截图如下:

用python简单实现:

[python]  view plain  copy #coding=utf-8      import tempfile   import os   import re   import time   import xml.etree.cElementTree as ET      class Element(object):       """      通过元素定位,需要Android 4.0以上      """       def __init__(self):           """          初始化,获取系统临时文件存储目录,定义匹配数字模式          """           self.tempFile = tempfile.gettempdir()           self.pattern = re.compile(r"\d+")          def __uidump(self):           """          获取当前Activity控件树          """           os.popen("adb shell uiautomator dump /data/local/tmp/uidump.xml")           os.popen("adb pull /data/local/tmp/uidump.xml " + self.tempFile)          def __element(self, attrib, name):           """          同属性单个元素,返回单个坐标元组          """           self.__uidump()           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"]                   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])                      return Xpoint, Ypoint             def __elements(self, attrib, name):           """          同属性多个元素,返回坐标元组列表          """           list = []           self.__uidump()           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"]                   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])                   list.append((Xpoint, Ypoint))           return list          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)      class Event(object):       def __init__(self):           os.popen("adb wait-for-device ")          def touch(self, dx, dy):           """          触摸事件          usage: touch(500, 500)          """           os.popen("adb shell input tap " + str(dx) + " " + str(dy))           time.sleep(0.5)      def test():       element = Element()       evevt = Event()          e1 = element.findElementByName(u"1号店")       evevt.touch(e1[0], e1[1])       time.sleep(1)          e2 = element.findElementByName(u"手机充值")       evevt.touch(e2[0], e2[1])   这是一个简单的思路,使用的前提是需要开启view server,否则无法获取到uidump.xml这个文件。另外程序运行的会有点慢,可以有优化的方法。

另外如果属性值相同,使用elements,返回的是含坐标元组的列表,如何使用,这里就不讲了。

该文转自:http://blog.csdn.net/gb112211/article/details/33730221

WEL测试 认证博客专家 软件测试 性能测试 接口测试 一线的测试工作人员。喜欢专研并应用新的技术,用于提升测试效率。擅长:测试新人培训、测试进阶、接口测试、性能测试、问题定位、自动化、数据测试、渗透测试! 如果对测试感兴趣或者遇到一些难题,可以加我微信:Wel_Test,加时填好备注!
转载请注明原文地址: https://www.6miu.com/read-31698.html

最新回复(0)