Appium+python自动化(十一)- 元素定位秘籍助你打通任督二脉 - 下卷(超详解)
简介
宏哥看你骨骼惊奇,印堂发亮,必是练武之奇才! 按照上一篇的节目预告,这一篇还是继续由宏哥给小伙伴们分享元素定位,是不是按照上一篇的秘籍修炼,是不是感觉到头顶盖好像被掀开,内气从头上冒出去,顿时觉得整个身体都融化了,而且身轻如燕啊!而且控制不住手,想要动手操作一番呢?那还在等什么呢,和宏哥一起练起来吧!!!
1、 List定位
List故名思义就是一个列表,在python里面也有list这一个说法,如果你不是很理解什么是list,这里暂且理解为一个数组或者说一个集合。首先一个list是一个集合,那么他的个数也就成了不确定性,所以这里需要用复数,所以在我们定位时我们不能够接着用find_element_by_id等等定位方式了,我们需要用他的复数形式find_elements_by_id,所有的定位方式都一样需要采用复数加s。这里我们接着上篇的案例讲,如何使用list定位想定位的元素。首先看一下图片:
我们查看图片可以知道我们能够很轻松的通过id定位到整个祖父节点,我们接下来需要做的事定位这个祖父节点下所有的“android.widget.RelativeLayout”父节点,同样的首先我们看一张图:
这里我们需要直接使用定位复数的方法来操作,直接看代码(祖父节点定位到父节点):
element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container") elements = element.find_elements_by_class_name("android.widget.FrameLayout")
通过上面的代码我们直接定位了com.taobao.taobao:id/rv_main_container父节点下的所有android.widget.FrameLayout子节点,但是由于这个android.widget.FrameLayout子节点下边还有许多相同的android.widget.LinearLayout孙节点。
这里我们需要直接使用定位复数的方法来操作,直接看代码(父节点定位到孙节点):
elements = element.find_elements_by_class_name("android.widget.FrameLayout") elements1 = elements[].find_elements_by_class_name("android.widget.LinearLayout")
现在我们需要怎么去操作这个子节点了,这里有两种方法:
1、前面我们讲了List你可以理解为一个数组或者一个集合,这里定位的所有子节点最后就成了个list,如果我们要访问这个list里面的某一个元素我们可以像访问数组中的数据一样通过下标访问。最后的代码就是下面这个样子:
element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container") elements = element.find_elements_by_class_name("android.widget.FrameLayout") elements1 = elements[].find_elements_by_class_name("android.widget.LinearLayout") elements1[].click()
上面的代码最后的结果是选择了“聚划算”这个标签页面,然后点击进入。
备注:如果初学者不理解是如何通过下标访问的,这里说一下下标是从0开始,如果要访问list i中的第一个元素结果就是i[0],这部分知识可以看一下python基础。
2、如果你要访问List里面的元素,那么我们是否可以通过for循环语句来依次访问呢?这个在自动化中会经常用到。下面你可以通过这个思路自己去实战一下,看能否达到预期效果。下面看我的代码:
element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container") elements = element.find_elements_by_class_name("android.widget.FrameLayout") elements1 = elements[].find_elements_by_class_name("android.widget.LinearLayout") for ele in elements1: ele.click()
看上面的代码,我们通过循环去访问这个list里面的每一个元素,因为每次循环得到的都是其中一个元素,那么我们只需要在这个元素上加上你想要的操作即可,所以我们这里可以直接点击进去。
如果你动手做到这里会发现一个问题,你进入到第一个标签后没一会儿系统就会报错,为什么呢?你也可以试着去解决这个问题,后面我们会讲解这块儿知识。
2、 内嵌H5定位
2.1 hybrid定位思考
在web自动化中我们会遇见frame的问题,在遇见这些内嵌的标签后我们需要做的就是切换窗口,那么在app自动化测试也有类似的情况就是我们经常看见的内嵌html,在我们原生的app中增加一个由html做成的页面。大家可以思考一下这种情况怎么操作。
2.2 hybrid常见定位问题分析
首先我们看一下下面一张图片:
通过右边的结构图我们能够清晰的看见整个页面就是一个webview,无论从什么角度来定位我们都不能够很好的进行,如果这个时候我们需要操作页面的元素就需要通过切换contexts来完成。但是在讲这个知识点之前大家先按照网上的知识来试一下处理这个页面,看能否成功。下面先说大家会遇见的问题:
1、可能你看到有的文章显示我们不需要通过切换contexts就能够完成定位,这样的情况有,但是那种情况作者只在微博登录、qq登录等第三方登录时遇见过,如果不是这样的情况而像上面的情况就没办法通过类似的方法进行完成,所以我希望读者遇见这种情况时自己动手去操作,看什么方式更加适合自己的项目。
2、需要切换contexts那么就需要获取页面的所有contexts,此时你通过官网或者其他文章的知识通过下面的方法来获取,可能会报错,这种情况关系不大。
webview = self.driver.contexts print webview
如果你通过上面的代码来调试但是却报错,但是其他资料却没问题时你也不要着急,这里你需要确定两件事情:(1)、app打包的时候需要开启webview 的debug属性setWebContentDebuggingEnabled(true),这个直接让开发加上就好。一般情况是开启的,毕竟他们也要调试。(2)、你用很多手机去调试,发现有一些可以有一些不可以,但是你用模拟器却都可以,根据官方给出的答案是这个时候你需要去将手机root,然后再试。目前作者遇见了这两种情况,第二种我也是调试了很久才找到原因。
2.3 hybrid定位讲解
这两个问题解决后那么定位webview就轻松搞定,直接看代码:
webview = driver.contexts driver.switch_to.context(webview[]) driver.find_element_by_link_text('PHP').click()
对于初学者对于上面的代码可能不是很理解,下面我们看一下日志:
大家这里不用管我执行代码和之前的区别(多了一个self),我们看下面控制台的输出,输出的是一个list,前面说过list和数组类似,在这个list里面有两个元素“NATIVE_APP”,“WEBVIEW_cn_com_open_mooc”,第一个元素是我们原生的app的contexts,后面的则是我们的webview的context,所以我们需要获取webview的context时只需要通过这个list的下表来进行访问。
我们获取到webview的context后只需要通过driver.switch_to.context()进行切换就好。当切换后我们就可以像定位web一样进行定位。
看下面一张图片我们通过浏览器将h5页面打开:
通过上面的图片我们就能够很轻松的像web一样进行定位,也就可以使用web的一些定位方式。看到这里是不是觉得解决了一个难题呢?动手去吧。
2.4 hybrid问题实战
通过前面的学习我相信你已经有了一些实战能力,这里给大家提一个问题,我们获取到的contexts每次一定是两个吗?如果不是两个那么我们上面的脚本是不是就没办法用了呢?可以思考一下这里怎么解决,在看我们下面的思路以及解决方案。
无论在什么页面我们去获取contexts时他无论有几个但是他的类型是不是肯定都是一个list呢?既然是list那么我们是否可以取到里面的每一个值,然后把每一个值进行判断,只要找出我们的webview就可以了呢?下面看代码:
#获取当前页面所有的contexts webview = driver.contexts #在获取到的contexts list里面去挨个循环 for context in webview: #判断循环中单个的context是否是webview,如果是就进行切换,并且跳出循环 if 'WEBVIEW' in context: driver.switch_to.context(context) break driver.find_element_by_link_text('PHP').click()
通过上面的代码我们是否完美的解决了内嵌H5的定位问题呢?动手吧
3、 滑动定位
3.1 滑动定位方式
在app自动化中我们经常会遇见一个问题,我们需要查找的元素不在当前可展示的屏幕,至于在什么地方我们不知道,如果这个时候我们一直使用在当前页面查找,那么系统就会报错,为了解决这个问题我们就需要使用滑动查找。
首先的思路是我们在需要查找对象的页面查找一下该元素,判断该元素是否在当前页面,如果该元素不在该页面那么我们就需要去互动屏幕,到我们的下一屏幕,然后再进行查找,依次类推到找到为止。
3.2 滑动定位思路分析
方式我们有了,那么我们就需要知道实现这个功能应该有哪些点。下面跟着我一起来分析一下:
1、需要查找的元素我们是不是需要知道是什么呢?这个需要先确定
2、我们需要找的页面是在我们的当前页面的上方还是下方还是左方还是右方,我们不能确定,那么我们是否需要确定我们需要滑动的方向?
3、元素和方向有了,但是你知道我们每次需要滑动屏幕的多少吗?那么我们是否需要先去获取屏幕的大小,然后针对不同的方向去计算一个滑动的值呢?
万事具备只欠东风,去按照这个思路动手练习一吧。
3.3 滑动定位实战
一、根据上面的思路我们能首先来确定我们需要查找的元素,看下面图片:
我们要找实战推荐后面的“换一换”按钮,然后进行点击。首先我们查看他的定位信息
最后我们查找元素的定位信息代码如下:
self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click()
对于有一定基础的人可能会觉得这个很low,但是有没有思考过一个问题,我们可以通过这个代码去执行,在没有这按钮的时候却会报错,也就没有办法执行下去了,那么需要怎么处理呢?所以这个时候我们需要有一些python的容错知识,即使我们的代码执行出错了,那么也要让他按照我们的意思执行下去。try.......except.......,这个就是我们python中的容错处理 ,下面我们看添加后的代码:
try: self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click() except Exception,e: print e
try的意思就是告诉编译器试着去执行他下面这一段代码,如果报错了,那么你就把except里面的错误信息打印出来。
二、有了元素现在我们需要知道的是不是就是该怎么滑动界面了呢?首先我们看一下下面这张图片:
在我们使用app的过程中存在上面几种滑动情况,我们把整个界面看作为一个坐标系(x,y),如果我们需要往上滑动,那么我们是不是就是x轴不动,y轴从下往上动呢?往下就是x轴不动,y轴从上往下呢?同理左右滑动是不是就是应该y轴不动x轴左右滑动呢?可以好好去体会一下,脑海中有个画面。
在appium中滑动我们所需要使用的方法就是swipe函数,至于往哪个方向滑动就是看我们里面的x,y的值,如果我们需要下往上滑动那么我们就应该是:
self.driver.swipe(x1,y1,x1,y2,t)
上面的代码x轴的值不变,y轴的值进行了变化,所以是沿着上下进行滑动的,从y2滑动到了y1点。t代表的是多少时间完成这个动作,或者说这个时间持续多久。
备注:这里需要注意的是屏幕的x,y的值是从左上角开始取的,左上角为(0,0),右下角是最大。
三、上面滑动的方法看着是好用,但是我们不可能每次都去填写一个坐标,那样太low,所以我们需要获取屏幕大小,直接看代码:
x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height']
上面的代码就是我们获取到的x,y轴。通过思路我们的代码都有了,下面我们要做的就是对原来的代码进行修改,进行一个封装。下面看代码,这个暂时看不懂没关系,到后面我们学了python'基础就能够看懂了。先思路,然后了解。
#获取屏幕大小 def getSize(self): x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] return (x,y) #向左滑动 def swipeLeft(self,t): l=self.getSize() x1=]*0.9) y1=]*0.5) x2=]*0.1) self.driver.swipe(x1,y1,x2,y1,t) #向右滑动 def swipeRight(self,t): l=self.getSize() x1=]*0.25) y1=]*0.5) x2=]*0.75) self.driver.swipe(x1,y1,x2,y1,t) #向上滑动 def swipeUp(self,t): l=self.getSize() x1=]*0.5) y1=]*0.8) y2=]*0.4) self.driver.swipe(x1,y1,x1,y2,t) time.sleep() #向下滑动 def swipeDown(self,t): l=self.getSize() x1=]*0.5) y1=]*0.25) y2=]*0.75) self.driver.swipe(x1,y1,x1,y2,t) #查找元素,没找到滑动 def findLocal(self): x = : : self.swipeUp() time.sleep() self.fact() else: print "找到了" x= #递归 def fact(self): n = try: self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click() except Exception,e: return n
通过查看上面代码的整个逻辑就是1、首先去查找元素,如果找到了我就直接点击。2、如果没有找到元素那么我就往上滑动(这里可以自己选择),滑动后再次进行查找,如果找到就点击,没有找到继续滑动。动手动手,这里知识点很重要!虽然后面会有一些替代方法,但是思路、算法很重要。
4、小结
好了,元素定位,常见的大致就这些,这个目前就分享到这里吧,以后如果遇到,宏哥给小伙伴再补上!!!
支持宏哥的朋友们和宏哥的宏粉记得点波推荐哦,您的肯定就是我进步的动力。鄙人先在这里给您道谢了,谢您嘞~~
个人公众号
微信群
Appium+python自动化(十一)- 元素定位秘籍助你打通任督二脉 - 下卷(超详解)的更多相关文章
- Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)
简介 你有道灵光从天灵盖喷出来你知道吗,年纪轻轻就有一身横练的筋骨,简直百年一见的练武奇才啊,如果有一天让你打通任督二脉,那还不飞龙上天啊.正所谓我不入地狱谁入地狱,警恶惩奸维护世界和平这个任务就交个 ...
- Appium+python自动化(十三)- 与Capability完美懈垢之解读(超详解)
简介 Capability又叫Appium Desired Capabilities,前边写了那么多实例代码,小伙伴可以发现一些规律,就是有一部分代码总是重复的出现在你的视线中.这部分就是对Capab ...
- Appium+python自动化(十三)- 输入中文 - 一次填坑记(超详解)
简介 无论你在哪里,在做什么都会遇到很多坑,这些坑有些事别人挖的,有些是自己挖的.别人挖的叫坑人,自己挖的叫自杀,儿子挖的叫坑爹.因此在做app自动化道路上也不会是一帆风顺的,你会踩很多坑,这些坑和你 ...
- Appium+python自动化12-appium元素定位
前言 appium定位app上的元素,可以通过id,name.class这些属性定位到 一.id定位 1.appium的id属性也就是通过UI Automator工具查看的resource-id属性
- Appium+python自动化12-appium元素定位【转载】
前言 appium定位app上的元素,可以通过id,name.class这些属性定位到 一.id定位 1.appium的id属性也就是通过UI Automator工具查看的resource-id属性
- appium+python自动化50-生成定位对象模板templet(jinja2)
前言 每次自己写pageobject定位元素对象太繁琐,格式都差不多,只是换个定位方法,这种就可以才有模板的方式,批量生成pageobject定位元素对象的模板 python里面生成模板有两个模块可以 ...
- Appium+python自动化4-元素定位uiautomatorviewer
前言 环境搭建好了,下一步元素定位,元素定位本篇主要介绍如何使用uiautomatorviewer,通过定位到页面上的元素,然后进行相应的点击等操作. uiautomatorviewer是androi ...
- appium+python自动化49-yaml管理定位元素
前言 如何高效管理定位元素,这个是很有学问的问题,也是面试必问的[以下纯属个人观点,勿喷!]. 有的人用xml管理页面定位元素,这种逼格略高,但是小编认为学习成本大,贼麻烦. 有的人提到用excel管 ...
- selenium+python自动化之元素定位
自动化按步骤拆分的话,可以分为四步操作:定位元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告.本篇接下来讲基本的八种元素定位方法.说的通俗一点,就是教大家找对象. ...
随机推荐
- CentOS 由 JavaCPP 转让 FFMPEG
1. Java 与 FFMPEG FFMPEG 它是一种广泛使用的媒体处理库,于Java天地,处理视频较弱的能力,因此,有非常大的需求需求Java 转让 FFMPEG. Java 转让C 的方式有非常 ...
- thread、Task、async & await
学习 Jesse 的文章 async & await 的前世今生(Updated) 而来 Thread是最开始使用的多线程.new一个Thread对象,将方法传进去.手动Start() 还可以 ...
- windows下Redis 主从读写分离部署
原文:windows下Redis 主从读写分离部署 1.可直接下载window下的运行文件(下面这个链接) 也可以浏览github 查看相应的版本说明文档 https://github.com/Ser ...
- JavaScript:undefined And null差异
班吃饭的时候,同事偶然问了一个问题:undefined和null究竟有什么差别?无法回答,回去查阅相关文档,算了有了一个了解,做相关的总结.在開始之前,请看例如以下代码,算是抛出这个问题: conso ...
- Emgu-WPF学习使用-中值模糊
原文:Emgu-WPF学习使用-中值模糊 实现效果: 实现途径: 前提:Image File-> System.Drawing.Bitmap->Image<Bgr, byte> ...
- Bootstrap路径导航
@{ Layout = null;}<!DOCTYPE html><html><head> <meta name="viewport&q ...
- jquery表单过滤器
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- wpf怎么使用WindowsFormsHost(即winform控件)
原文:wpf怎么使用WindowsFormsHost(即winform控件) 使用方法: 1.首先,我们需要向项目中的引用(reference)中添加两个动态库dll,一个是.NET库中的System ...
- 初探WINDOWS下IME编程
初探WINDOWS下IME编程作者:广东南海市昭信科技有限公司-李建国 大家知道,DELPHI许多控件有IME属性.这么好用的东西VC可没自带,怎么办呢?其实,可通过注册表,用API实现.下面说一下本 ...
- Microsoft Enterprise Library 5.0 系列(四)
企业库日志应用程序模块工作原理图: 从上图我们可以看清楚企业库日志应用程序模块的工作原理,其中LogFilter,Trace Source,Trace Listener,Log Formatter的信 ...