当前位置: 首页 > 后端技术 > Python

带你用Python实现自动化群控设备

时间:2023-03-26 11:23:28 Python

一、前言群控,相信大多数人都不陌生吧!印象是一台电脑控制多台设备完成一系列操作,更多人喜欢用灰品绑定!其实群控在自动化测试中的应用也很广泛!在接下来的几篇文章中,我将带大家一起聊一聊企业级自动化中群控的正确使用姿势!本文从基础入手,讲述如何使用“Python+adb”命令编写一套群控脚本。2、准备在本机安装Android开发环境,确保环境变量中添加了adb,以准备多台设备。使用数据线(或者通过Hub)连接电脑,通过adbdevices命令查看所有连接的设备#下面显示连接了3台设备xag:testxingag$adbdevicesListofdevicesattached822QEDTL225T7deviceca2b3455deviceDE45d9323SE96device3.以Fish应用程序中的关键字搜索为例。步骤包括:打开应用,点击进入搜索界面,输入内容,点击搜索按钮通过以下7个步骤完成这个操作1.获取目标应用的包名,初始化获取方法Activity的方式有很多种,主流的方式有:adb命令、APK解析、第三方APK、无障碍服务这里推荐使用adb命令这种方式#获取当前Activity的包名和初始Activity运行应用程序adbshelldumpsys活动|grep-irunopenidleFishApp,在命令终端输入以上命令,终端会显示包名和activity名2.通过adbdevices命令获取所有在线设备,通过输出内容进行过滤得到所有连接到PC的设备#AllDeviceIDdevices=[]defget_online_devices(self):"""获取所有在线设备:return:"""globaldevicestry:fordevice_serias_nameinexec_cmd("adbdevices"):#Filterout第一条数据和下线设备if"device"indevice_serias_name:devices.append(device_serias_name.split("\t")[0])devices=devices[1:]exceptExceptionase:print(e)#所有连接的设备及其数量返回devices3,群控开启目标应用遍历Devicelist,使用adb-sdeviceIDshellamstart-W命令分别打开目标应用defstart_app(self):"""OpenApp:return:"""fordeviceindevices:os.popen("adb-s"+device+"shellamstart-W{}/{}".format(self.packageName,self.home_activity))print('等待加载完成...')sleep(10)4.封装执行步骤为了便于管理Device,将每一步操作写入YAML文件,可以通过ID查找元素并进行点击操作,在输入框中输入内容,调用本地方法,这里输入参数对应:保存UI树控件,找到输入框元素并执行点击操作,保存UI树形控件(界面变了),输入文字内容,查看搜索按钮元素和执行点击操作#steps_adb.yaml#包名和Activitypackage_name:com.taobao.idlefishhome_activity:com.taobao.fleamarket.home。activity.InitActivity#执行步骤steps:-save_ui_tree_to_local:method:save_ui_tree_to_localargs:-find_element_and_click:id:com.taobao.idlefish:id/tx_id-save_ui_tree_to_local:method:save_ui_tree_to_local-input_content:content:Python-find_element_and_click:id:com.taobao.idlefish:id/search_button需要指出的是,为了提高群控的适配性,需要通过以下步骤获取控件的实际坐标:导出界面的控件树解析控件树的XML文件,使用正则表达式获取目标控件的坐标,计算控件的中心点坐标。使用控件ID获取元素中心点的坐标。实现代码如下:defget_element_position(element_id,uidump_name):"""通过元素id,使用ElementTree,解析元素控制树,找到元素的坐标中心点:paramelement_id:元素id,例如::return:elementcoordinate"""#parseXMLtree=ET.parse('./../%s.xml'%uidump_name)root=tree.getroot()#要查找的元素result_element=None#print('Numberofsearches',len(root.findall('.//node')))#遍历寻找节点元素#通过元素idfornode_elementinroot.findall('.//node'):ifnode_element.attrib['resource-id']==element_id:result_element=node_elementbreak#如果没有找到元素,如果result_element为None则直接返回空:print('Sorry!Elementnotfound!')returnNone#解析数据coord=re.compile(r"\d+").findall(result_element.attrib['bounds'])#中心点坐标position_center=int((int(coord[0])+int(coord[2]))/2),int((int(coord[1])+int(coord[3]))/2)返回position_center5,以保证group的执行区分设备控制脚本不会造成干扰,在每一步执行之前,需要区分设备ID作为参数。例如:将控件的界面控件树根据设备保存为不同的名称,点击界面输入命令将对应的设备ID作为入参传递。defsave_ui_tree_to_local(dName):"""获取当前Activity控件树并保存到本地,文件名固定为:uidump.xml:paramdName:deviceid:return:"""exec_cmd("adb-s%sshelluiautomatordump/data/local/tmp/%s.xml"%(dName,dName))sleep(2)exec_cmd("adb-s%spull/data/local/tmp/%s.xml./../"%(dName,dName))6.执行步骤从YAML文件中读取执行步骤,遍历步骤集合,内部遍历设备列表,保证每个步骤分别在每个设备上执行pass然后,将不同的操作与step名称匹配来操作设备#Operationnamestep_name=list(step)[0]ifstep_name=='save_ui_tree_to_local':#将UI编号保存到本地method=step.get(step_name).get('method')save_ui_tree_to_local(device)elifstep_name=='find_element_and_click':element_id=step.get(step_name).get('id')#获取元素的坐标bound_search_input=get_element_position(element_id,device)#点击元素exec_cmd('adb-s%sshellinputtap%s%s'%(device,bound_search_input[0],bound_search_input[1]))elifstep_name=='input_content':input_content=step.get(step_name).get('content')#模拟输入exec_cmd('adb-s%sshellinputtext%s'%(device,input_content))else:print('其他操作步骤')7.关闭应用程序的所有操作完成后,同样遍历设备,使用adb命令关闭应用程序。defstop_all(self):"""关闭应用程序:return:"""fordeviceindevices:os.popen("adb-s"+device+"shellamforce-stop%s"%self.packageName)4.最后,本文只是最简单的Python自动化群控实现,更复杂的实现会在后面讨论。文中所有源码我都上传到后台了,关注公众号「AirPython」回复“qk”获取所有源码如果觉得文章还不错,请点赞分享留言,因为这将是我持续输出更多优质文章的最强动力!推荐阅读,教你如何批量运行自动化脚本,高效工作!自动化|朋友圈被折叠了?不存在的自动化|再也不用担心老人用智能手机了