Python Appium自动化测试 元素定位

2020-11-30  本文已影响0人  白码会说

Time will tell.

元素定位是自动化测试中关键的一步,因为你对象都没定位好,那么你想去操作这也是行不通的,所以本章节也是希望同学们多去动手实战,不要仅仅只是看过、看了。


一、 常用定位

1、ID定位

无论是在 web 自动化还是 app 自动化中id都是唯一的,那为什么有的地方说name定位是唯一的呢,在这里又为什么是id呢?

其实这个不冲突,但如果你用 appium 较新版本那是不行的,在新版本中 name定位被去掉了,所以在以后的定位中都不会有name定位了。

看到这里可能又有小伙伴会有疑问,有的时候你的应用为什么没有id,或者说在这个手机上有但在另外的手机上却没有?

原因:

  1. 开发没有添加
  2. android 版本是4.4以下的
image

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

driver.find_element_by_id("com.taobao.taobao:id/aliuser_login_account_et").send_keys("aaa")

2、className定位

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

image image

可以看一下这两张图片中淘宝账号、密码两个输入框中的className都是一样的,如果在这种情况下你使用下边这种方式去定位,你会发现你永远定位不了密码栏,这是为什么呢?

因为在设计的时候如果你查找的元素在页面有多个,系统会自动给你选择第一个,所以你永远操作不了后面的,那么在实际工作或实战中遇到此类问题如何解决?后面会讲到。

driver.find_element_by_class_name("android.widget.EditText").send_keys("aaa")

3、xpath定位
xpath定位在 web 自动化中是最常见的,而且也是最有效的,使用xpath定位避免了找不到元素导致报错的问题,但是在 app 中使用xpath定位是一件很low的事情。为什么?

因为在过来人的经历中,只要遇到使用xpath定位元素,它的反应就会比较慢,自动化的目的是为了提高效率,但使用xpath后会降低效率,所以这里说有点low。但很多时候不得不去了解,下面我们首先要熟悉一下 web 的xpath定位。

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

image image

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

image

用红色圈出有虚线的输入框我们看一下FirePath给我们的定位,在定位的xpath中显示的是:
py “.//*[@id='kw']”
这个是什么意思呢?我们一步一步说。

1、//* 选取文档中的所有元素

2、@id=‘kw’] 匹配属性为 id 且值为 kw 的节点。

这里可能有小伙伴不是很理解,说这里直接使用 id 进行定位就行。其实也是,但是当没有这个属性的时候呢?我们看下面这张图:


image

name定位无效的情况下,当你看到这张图片的时候如果你不用xpath怎么定位呢?有一些抓狂的感觉吧。小伙伴可以尝试着自己使用xpath进行定位,可能有一些人发现xpath中定位不是很明白了,为什么呢?

.//*[@id='u1']/a[4]  

在这个xpath中我们没有像之前那样思路清晰了他多了一些层级关系,这个后面我们会仔细讲。这个xpath中首先第一步:

1、@id='u1’和之前的一样匹配属性为id值为ul的节点,然后再在他的下面进行定位第二步

2、/a[4] 意思就是从根节点下选取第四个a元素。

这样一步一步解析是否更加容易理解了呢?下面我们看一下在xpath定位中经常用到的一些语法:


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


这些在:http://www.w3school.com.cn/xpath/xpath_examples.asp 当中可以看得到,大家也可以多看多练习一下。

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


image image

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

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

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


2 、层级定位

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

那么,在项目中层级定位如何运用呢?下面我们来看一个简单的例子理解层级定位。


image image

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

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

image

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

首先我们可以看出3张图结构上的区别,第3张图的元素它是在第2张图里面的,第2张图元素它是在第1张图里面的。

这里我们称第1张图id(com.taobao.taobao:id/rv_main_container)android.widget.FrameLayout的节点为第2张图元素的父节点,第2张图id(android.widget.FrameLayout)android.widget.FrameLayout的节点为第3张图元素的父节点,第1张图id(com.taobao.taobao:id/rv_main_container)android.widget.LinearLayout的节点为第3张图元素的祖父节点,我们只需先通过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()

按照思维我们的代码会是上面的结果,但是你去运行会发现不报错,可也不会点击,这是为什么呢?我们看下面的图片:


image

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

参考代码:

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

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

# 3.导入模块
from appium import webdriver
import time
desired_caps = {}
desired_caps['platformName'] = 'Android'  #android的apk还是IOS的ipa
desired_caps['platformVersion'] = '8.0'   #android系统的版本号
esired_caps['deviceName'] = '127.0.0.1:62001'    #手机设备名称,通过adb devices  查看
desired_caps['appPackage'] = 'com.taobao.taobao'  #apk的包名
desired_caps['appActivity'] = 'com.taobao.tao.welcome.Welcome'  #apk的launcherActivity
# desired_caps['unicodeKeyboard'] = True   #使用unicodeKeyboard的编码方式来发送字符串
# desired_caps['resetKeyboard'] = True   #将键盘给隐藏起来
driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) #启动服务器地址,后面跟的是手机信息
# 休眠五秒等待页面加载完成
time.sleep(5)

element= driver.find_element_by_id("com.taobao.taobao:id/rv_main_container")
element1 = element.find_elements_by_class_name("android.widget.FrameLayout")
element2 = element1[1].find_element_by_class_name("android.widget.LinearLayout")
element2.click()

# driver.quit()

OK,以上就到这里喽,如果你对Python自动化软件测试更多内容感兴趣可以加入我们扣裙一起学习175317069。有各项测试学习资源发放,更有行业深潜多年的技术人分析讲解。

最后希望看到这里的你终成为一名极具竞争力的高级测试工程师。

觉得还不错就【点赞】、【评论】、【关注】吧~

Time will tell.(时间会说明一切)

上一篇下一篇

猜你喜欢

热点阅读