Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉

系统 1846 0

简介

  你有道灵光从天灵盖喷出来你知道吗,年纪轻轻就有一身横练的筋骨,简直百年一见的练武奇才啊,如果有一天让你打通任督二脉,那还不飞龙上天啊。正所谓我不入地狱谁入地狱,警恶惩奸维护世界和平这个任务就交个你了,好吗。这本如来神掌秘籍是无价之宝,我看与你有缘,收你十块钱传授给你吧。想必这段经典台词给为都可以的耳熟能详吧,宏哥,没这么牛叉呼啦带闪电,就是希望对你有帮助就可以了。

  上一篇宏哥给小伙伴们介绍完定位工具这两个异性兄弟,这篇就给小伙伴们介绍一下定位方法。早就有小伙伴问,这个这个怎么定位,那个那个怎么定位?那么宏哥今天就告诉你,怎么怎么定位。其实定位前边也有所涉及,只不过是一笔带过的。这篇宏哥就给小伙伴们详细的介绍一下。

1、 常用定位方法讲解

  对象定位是自动化测试中很关键的一步,也可以说是最关键的一步,毕竟你对象都没定位那么你想操作也不行。所以本章节的知识宏哥希望小伙伴们多动手去操作和实战,不要仅仅只是书本上的知识,毕竟这个我只能够举例说明。下面我们来看我们常用的一些定位方式。

1.1 ID定位

  无论是在web自动化还是app自动化中id都是唯一的,可能有的小伙伴看到这里会有疑问,因为有的资料说是通过name定位是唯一的,为什么你这里是id呢,其实这个在之前是不冲突的,但是如果你用的是appium较新版本是不行的,在新版本中name定位被去掉了,所以在以后的定位中不会有name定位了,通常情况下我们也更喜欢用id进行定位。这里可能刚学的小伙伴会有疑问,有的时候你的应用为什么没有id,或者说在这个手机上有但是另外的手机上没有。1、开发没有添加。2、android版本是4.4以下的。

我们直接看下面这张图片吧

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第1张图片

 

上面图片中左边部分用红色圈出来的对象的id我们在右边的属性中可以看到,它的id宏哥同样是用红色圈出,如果我们需要对“请输入淘宝账户”这个输入框进行输入信息,我们只需操作右边的id就行,下面我们直接看代码。

 

            
              1
            
             driver.find_element_by_id(
            
              "com.taobao.taobao:id/aliuser_login_account_et
            
            
              "
            
            ).send_keys(
            
              "北京宏哥
            
            
              "
            
            )
          

 

通过上面的代码我们能够直接在账户信息输入框中输入账户信息北京宏哥。可能对于无基础的人来说这里会又点儿迷糊,这个driver是哪里来的,driver在我们配置启动的时就已经初始化,我们只需要调用他的方法find_element_by_id。如果你的ide有自动补全功能,那么你在输入后面的方法时会发现一个问题,为什么还有一个find_elements_by_id呢?这个在后面宏哥会讲解,有兴趣的小伙伴可以思考一下。

1.2 className定位

在实际工作中className定位用得相对而言会比较少。当你经常去看class时你会发现很多的className是一样的,你没有办法对其进行唯一定位,下面我们看下面两张图片

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第2张图片

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第3张图片

 

我们可以仔细看一下这两张图片中淘宝账号、密码两个输入框中的className都是一样的,如果在这种情况下你使用下边这种方式去定位,你会发现你永远定位不了密码栏,这是为什么呢?因为在设计的时候如果你查找的元素在页面有多个,系统会自动给你选择第一个,所以你永远操作不了后面的,那么在实际工作或者实战的时候如果遇到此类问题如何解决这种问题呢?宏哥后面会讲解。

 

            driver.find_element_by_class_name(
            
              "
            
            
              android.widget.EditText
            
            
              "
            
            ).send_keys(
            
              "
            
            
              北京宏哥
            
            
              "
            
            )
          

 

1.3 xpath定位

xpath定位在web自动化中是最常见的,而且也是最有效的,使用xpath定位避免了找不到元素导致报错的问题,但是在app中使用xpath定位是一件很low的事情。为什么这么说呢?因为在宏哥过来人的经历中只要遇见使用xpath定位元素他的反应就会比较慢,自动化的目的是为了提高效率,但是使用xpath后会降低效率,所以这里说很 low。但很多时候我们不得不去了解,下面我们大概讲解一下。首先我们要熟悉一下web的xpath定位。

 

1)讲web的xpath之前大家先装一下fireFox浏览器,再在浏览器中安装fireBug以及FirePath两个插件。如下图:

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第4张图片

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第5张图片

在自动化或者学习xpath时这两个插件是必不可少的,这里我们直接讲xpath,我们来看下面一张图片理解一下

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第6张图片

用红色圈出有虚线的输入框我们看一下xFirePath给我们的定位,在定位的xpath中显示的是“.//*[@id='kw']”,这个是什么意思呢?我们来一步一步讲解。1、//*  选取文档中的所有元素 。2、@id='kw']  匹配属性为id且值为kw的节点。这里有的小伙伴可能不是很理解,说这里直接使用id进行定位就行。其实也是,但是当没有这个属性的时候呢?我们看下面这张图片

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第7张图片

  name定位无效的情况下,当你看到这张图片的时候如果你不用xpath怎么定位呢?有一些抓狂的感觉吧。小伙伴可以尝试着自己使用xpath进行定位,可能有一些人发现xpath中定位不是很明白了,为什么呢?.//*[@id='u1']/a[4]  在这个xpath中我们没有像之前那样思路清晰了他多了一些层级关系,这个后面我们会仔细讲。这个xpath中首先第一步1、@id='u1'和之前的一样匹配属性为id值为ul的节点,然后再在他的下面进行定位第二步2、/a[4]  意思就是从根节点下选取第四个a元素。这样一步一步解析是否更加容易理解了呢?下面我们看一下在xpath定位中经常用到的一些语法,下来大家多多练习。

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第8张图片

这个是我们经常用到的,而且是最基础的知识,只有这些没有办法完成很多古怪的需求,那么就有更难的,下面我们看下面的列表

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第9张图片

上面这些知识都是在http://www.w3school.com.cn/xpath/xpath_examples.asp 里面,大家可以多看看,多练习。

下面我们直接看在app中xpath的使用

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第10张图片

 

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第11张图片

 

在上面两张图片中我们能够清除的看见他们的id、className都是一样的,这样的情况下不用层级定位方式我们只能够采用xpath来进行定位,首先根据前面web的学习大家可以思考一下该怎么定位。我们直接看代码

 

            
              1
            
             driver.find_element_by_xpath(
            
              "
            
            
              //android.widget.TextView[@text='聚划算']
            
            
              "
            
            ).click()
          

 

在xpath里面我们的语法是这样“//android.widget.TextView[@text='JavaScript']”,这个和我们之前web的xpath一样,意思是查找所有节点中节点为android.widget.TextView (这里使用的是className,也可以使用id,系统会依次去找)并且他的text属性值为JavaScript,这样是否更容易理解呢?下来多练习。这样的定位方式不推荐,效率很慢。

2 、层级定位

2.1 什么是层级定位

  在前面的章节中我们已经提到了层级定位,只是不知道具体怎么操作而已。在很多的自动化中如果只是靠简单的定位是没有办法完成自动化的,就像刚xpath定位一样,有的元素的id、name、className都是一样的,xpath定位效率低下,这个时候我们大多数都会采用层级定位。

2.2 项目中层级定位如何运用

下面我们举一个简单的例子来理解层级定位。

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第12张图片

 

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第13张图片

 

从上面的图片我们可以看出id为com.taobao.taobao:id/rv_main_container的节点下面包含了很多的android.widget.FrameLayout

从下面的图片我们可以看出id为android.widget.FrameLayout的节点下面包含了很多的android.widget.LinearLayout

  Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第14张图片

 

从这张图片我们不难看出,如果我们要定位这个元素我们是没办法去定位的,这种情况我们大多数使用的是层级定位以及xpath,这里我们来看如何使用层级定位。

首先我们可以看出三幅图的结构上的区别,第三幅图的元素它是在第二幅图里面的,第二幅图元素它是在第一幅图里面的,这里我们称第一幅图id(com.taobao.taobao:id/rv_main_container)为android.widget.FrameLayout的节点为第二幅图元素的父节点,第二幅图id(android.widget.FrameLayout)为android.widget.FrameLayout的节点为第三幅图元素的父节点,第一幅图id(com.taobao.taobao:id/rv_main_container)为android.widget.LinearLayout的节点为第三幅图元素的祖父节点;我们只需要先通过id定位到祖父节点,然后再从祖父节点往下面依次进行定位就好。现在你可以练习一下,看和我的结果一样吗?看代码:

 

            
              1
            
             element= driver.find_element_by_id(
            
              "
            
            
              com.taobao.taobao:id/rv_main_container
            
            
              "
            
            
              )

            
            
              2
            
             element1 = element.driver.find_elements_by_class_name(
            
              "
            
            
              android.widget.FrameLayout
            
            
              "
            
            
              )

            
            
              3
            
             element2 = element1[
            
              1
            
            ].find_element_by_class_name(
            
              "
            
            
              android.widget.LinearLayout
            
            
              "
            
            
              )

            
            
              4
            
             element2.click()
          

 

按照思维我们的代码会是上面的结果,但是你去运行会发现不报错,可也不会点击,这个是为什么呢?我们看下面的图片(宏哥亲测,它会点击第一个天猫,可能是默认点击第一个吧)

 

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第15张图片

 

在祖父节点下的所有子节点他的className都是“android.widget.FrameLayout”,在父节点下的所有子节点他的className都是“android.widget.LinearLayout”,这种情况下他怎么去点击操作呢?所以在这种情况下会引发一个新的定位问题,就是宏哥在接下来要讲的List定位。

2.3参考代码

            
               1
            
             # coding=utf-
            
              8
            
            
               2
            
             # 
            
              1
            
            .先设置编码,utf-
            
              8可支持中英文,如上,一般放在第一行

            
            
               3
            
            
               4
            
             # 
            
              2
            
            
              .注释:包括记录创建时间,创建人,项目名称。

            
            
               5
            
            
              '''

            
            
               6
            
             Created on 
            
              2019
            
            -
            
              7
            
            -
            
              01
            
            
               7
            
             @author: 北京-宏哥   QQ交流群:
            
              707699217
            
            
               8
            
            
              Project:学习和使用定位元素

            
            
               9
            
            
              '''

            
            
              10
            
             # 
            
              3
            
            
              .导入模块

            
            
              11
            
            
              from
            
            
               appium import webdriver

            
            
              12
            
            
              import time

            
            
              13
            
             desired_caps =
            
               {}

            
            
              14
            
             desired_caps[
            
              '
            
            
              platformName
            
            
              '
            
            ] = 
            
              '
            
            
              Android
            
            
              '
            
            
                 #android的apk还是IOS的ipa

            
            
              15
            
             desired_caps[
            
              '
            
            
              platformVersion
            
            
              '
            
            ] = 
            
              '
            
            
              8.0
            
            
              '
            
            
                #android系统的版本号

            
            
              16
            
             desired_caps[
            
              '
            
            
              deviceName
            
            
              '
            
            ] = 
            
              '
            
            
              127.0.0.1:62001
            
            
              '
            
            
                  #手机设备名称,通过adb devices  查看

            
            
              17
            
             desired_caps[
            
              '
            
            
              appPackage
            
            
              '
            
            ] = 
            
              '
            
            
              com.taobao.taobao
            
            
              '
            
            
                #apk的包名

            
            
              18
            
             desired_caps[
            
              '
            
            
              appActivity
            
            
              '
            
            ] = 
            
              '
            
            
              com.taobao.tao.welcome.Welcome
            
            
              '
            
            
                #apk的launcherActivity

            
            
              19
            
             #desired_caps[
            
              '
            
            
              unicodeKeyboard
            
            
              '
            
            ] =
            
               True   #使用unicodeKeyboard的编码方式来发送字符串

            
            
              20
            
             #desired_caps[
            
              '
            
            
              resetKeyboard
            
            
              '
            
            ] =
            
               True   #将键盘给隐藏起来

            
            
              21
            
             driver = webdriver.Remote(
            
              '
            
            
              http://127.0.0.1:4723/wd/hub
            
            
              '
            
            
              , desired_caps) #启动服务器地址,后面跟的是手机信息

            
            
              22
            
            
              # 休眠五秒等待页面加载完成

            
            
              23
            
             time.sleep(
            
              5
            
            
              )

            
            
              24
            
            
              25
            
             element= driver.find_element_by_id(
            
              "
            
            
              com.taobao.taobao:id/rv_main_container
            
            
              "
            
            
              )

            
            
              26
            
             element1 = element.find_elements_by_class_name(
            
              "
            
            
              android.widget.FrameLayout
            
            
              "
            
            
              )

            
            
              27
            
             element2 = element1[
            
              1
            
            ].find_element_by_class_name(
            
              "
            
            
              android.widget.LinearLayout
            
            
              "
            
            
              )

            
            
              28
            
            
              element2.click()

            
            
              29
            
            
              30
            
             # driver.quit()
          

小结

1、前边介绍了一下火狐浏览器,这里宏哥再给小伙伴们总结一下谷歌浏览器如何用xpath定位,当然了,大神和大佬可以忽略不看,因为可以直接手写xpath定位。其实看看他们的语法也很简单,自己后期也可以尝试手写,看看和工具的有哪些区别,这样可以有助于自己的提高和提升。

2、谷歌浏览器xpath插件下载地址https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl

3、安装方法,用谷歌浏览器直接访问上边的地址,添加以后即可。

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第16张图片

 

 

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第17张图片

 4、看一下如何使用和其效果

(1)谷歌浏览器,F12,不可以的话,可以打开“开发者工具”

(2)点击左边的“箭头”,查找到要定位的元素

(3)选中控制台的元素,鼠标右键,在copy里,选中“Copy XPath”

(4)copy的内容:(//*[@id="kw"])

5、注意find_element和find_elements的区别!!!

  好了,时间不多了,天也很晚了,大致就这些吧,今天就给小伙伴们就说到这里吧。

宏哥不能保证所整理都符合大家的口味,但我能保证每一篇都是用心去写和用心去整理,我始终认同“分享的越多,你的价值增值越大”,欢迎大家关注我的博客和个人公众号的技术分享。在分享中进步,越努力越幸运,期待我们都有美好的明天!

有的小伙伴们等不急了,留言催宏哥了,不好意思哈,宏哥说实话最近特变的忙,没时间更新,这还是点灯熬油赶了一篇,能力有限,希望大家喜欢!!!

支持宏哥的朋友们和宏哥的宏粉记得点波推荐哦,您的肯定就是我进步的动力。鄙人先在这里给您道谢了,谢您嘞~~

个人公众号

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第18张图片

微信群

Appium+python自动化(十)- 元素定位秘籍助你打通任督二脉 - 上卷(超详解)_第19张图片


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论