Appium+python自动化3-定位元素
3.1常用定位方法讲解
对象定位是自动化测试中很关键的一步,也可以说是最关键的一步,毕竟你对象都没定位那么你想操作也不行。所以本章节的知识我希望大家多动手去操作,不要仅仅只是书本上的知识,毕竟这个我只能够举例说明。下面我们来看我们常用的一些定位方式
find_element_by_id()
find_element_by_name() #appium较新版本name定位被去掉
find_element_by_class_name()
find_element_by_xpath()
项目使用的工具是uiautomatorviewer,在安卓sdk的tools目录下(C:\Program Files (x86)\Android\androidSDK\tools,查看环境搭建章节)
3.1.1 ID定位
无论是在web自动化还是app自动化中id都是唯一的

面图片中左边部分用红色圈出来的对象的id我们在右边的属性中可以看到,他的id我同样是用红色圈出,如果我们需要对“点击相机,搜你所见”这个输入框进行输入信息,我们只需操作右边的id就行,下面我们直接看代码
#!/usr/bin/env python
# -*- codinfg:utf-8 -*-
'''
@author: Jeff LEE
@file: 启动百度.py
@time: 2018-07-25 15:24
@desc:
'''
import time from appium import webdriver desired_caps={
'platformName':'Android',
'deviceName':'D3F021C19001219', #手机设备名称,通过adb devices查看
'platformVersion':'4.4', #android系统的版本号
'unicodeKeyboard':'True',
'resetKeyboard':'True',
'appPackage':'com.baidu.searchbox',#apk包名
'appActivity':'com.baidu.searchbox.SplashActivity', #apk的launcherActivity
} driver=webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
time.sleep(5)
# 点击“输入框”
driver.find_element_by_id("com.baidu.searchbox:id/baidu_searchbox").click()
time.sleep(3)
# 输入字段
searchInputBox = driver.find_element_by_id('com.baidu.searchbox:id/SearchTextInput')
searchInputBox.send_keys("Appium") time.sleep(3) driver.quit()
通过上面的代码我们能够直接在输入框中输入Appium,如下图所示

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


通过className定位的代码
driver.find_element_by_class_name('android.widget.TextView')
这种方式去定位,你会发现你永远定位不了‘appium原理’,这是为什么呢?因为在设计的时候如果你查找的元素在页面有多个,系统会自动给你选择第一个,所以你永远操作不了后面的,那如何解决这种问题呢?我们看后面讲解。
3.1.3 xpath定位
xpath定位在web自动化中是最常见的,而且也是最有效的,使用xpath定位避免了找不到元素导致报错的问题,但是在app中使用xpath定位是一件很low的事情。为什么这么说呢?因为在作者的经历中只要遇见使用xpath定位元素他的反应就会比较慢,自动化的目的是为了提高效率,但是使用xpath后会降低效率,所以这里说很 low。
通过xpath定位的代码
driver.find_element_by_xpath('//android.widget.TextView[@text="appium原理"]').click()
运行结果

在xpath里面我们的语法是这样'//android.widget.TextView[@text="appium原理"]',这个和我们之前web的xpath一样,意思是查找所有节点中节点为android.widget.TextView (这里使用的是text,也可以使用id或class等元素,系统会依次去找)并且他的text属性值为appium原理,这样是否更容易理解呢?下来多练习。这样的定位方式不推荐,效率很慢。
3.2 层级定位
3.2.1 概念
在前面的章节中我们已经提到了层级定位,只是不知道具体怎么操作而已。在很多的自动化中如果只是靠简单的定位是没有办法完成自动化的,就像刚xpath定位一样,有的元素的id、className都是一样的,xpath定位效率低下,这个时候我们大多数都会采用层级定位。
3.2.2 项目中层级定位如何运用

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

从这张图片我们不难看出,如果我们要定位这个元素我们是没办法去定位的,这种情况我们大多数使用的是层级定位以及xpath,这里我们来看如何使用层级定位。
首先我们可以看出两幅图的结构上的区别,第二幅图元素他是在第一幅图里面的,这里我们称第一幅图id为android:id/tabs的节点为第二幅图元素的父节点,我们只需要先通过id定位到父节点,然后再从父节点往下面进行定位第二幅图就可以了
elemet =driver.find_element_by_id('android:id/tabs')
elemet.find_element_by_class_name('android.widget.FrameLayout').click()
运行会你会发现不报错,可也不会点击,这个是为什么呢?因为在父节点下的所有子节点他的className都是“android.widget.FrameLayout”,这种情况下他怎么去点击操作呢?所以在这种情况下会引发一个新的定位问题,就是我们接下来要讲的List定位
3.3 List定位
List故名思义就是一个列表,那么他的个数也就成了不确定性,所以这里需要用复数,所以在我们定位时我们不能够接着用find_element_by_id等等定位方式了,我们需要用他的复数形式find_elements_by_id,所有的定位方式都一样需要采用复数加s。
以上面例子为例,我要点击‘好看视频’,代码如下:
elemet =driver.find_element_by_id('android:id/tabs')
elemets=elemet.find_elements_by_class_name('android.widget.FrameLayout')
elemets[1].click()
运行结果如下:

3.4 内嵌H5定位
在web自动化中我们会遇见frame的问题,在遇见这些内嵌的标签后我们需要做的就是切换窗口,那么在app自动化测试也有类似的情况就是我们经常看见的内嵌html,在我们原生的app中增加一个由html做成的页面
后续补充,只要在测试之前加这个代码即可
#获取当前页面所有的contexts
webview = driver.contexts
#在获取到的contexts list里面去挨个循环
for context in webview:
#判断循环中单个的context是否是webview,如果是就进行切换,并且跳出循环
if 'WEBVIEW' in context:
driver.switch_to.context(context)
break
3.5 滑动定位
3.5.1 滑动定位方式
在app自动化中我们经常会遇见一个问题,我们需要查找的元素不在当前可展示的屏幕,至于在什么地方我们不知道,如果这个时候我们一直使用在当前页面查找,那么系统就会报错,为了解决这个问题我们就需要使用滑动查找。
首先的思路是我们在需要查找对象的页面查找一下该元素,判断该元素是否在当前页面,如果该元素不在该页面那么我们就需要去互动屏幕,到我们的下一屏幕,然后再进行查找,依次类推到找到为止。
3.5.2 滑动定位思路分析
方式我们有了,那么我们就需要知道实现这个功能应该有哪些点。下面跟着我一起来分析一下:
1、需要查找的元素我们是不是需要知道是什么呢?这个需要先确定
2、我们需要找的页面是在我们的当前页面的上方还是下方还是左方还是右方,我们不能确定,那么我们是否需要确定我们需要滑动的方向?
3、元素和方向有了,但是你知道我们每次需要滑动屏幕的多少吗?那么我们是否需要先去获取屏幕的大小,然后针对不同的方向去计算一个滑动的值呢?
3.5.3 滑动定位实战
class BaseOperate(object):
def __init__(self,driver):
self.driver =driver
self.get_size()
def get_size(self):
self.width = self.driver.get_window_size()['width']
self.height = self.driver.get_window_size()['height']
def swipe_left(self,t):
self.driver.swipe(self.width*9/10,self.height/2,self.width/10,self.height/2,t)
self.screenshot()
def swipe_right(self,t):
self.driver.swipe(self.width/10,self.height/2,self.width*9/10,self.height/2,t)
self.screenshot()
def swipe_up(self,t):
self.driver.swipe(self.width/2,self.height*9/10,self.width/2,self.height/10,t)
self.screenshot()
def swipe_down(self,t):
self.driver.swipe(self.width/2,self.height/5,self.width/2,self.height*9/10,t)
self.screenshot()
def findLocal(self):
x = 1
while x==1:
if self.fact() == 1:
self.swipe_up(2000)
time.sleep(3)
self.fact()
else:
print ("找到了")
x=2
def fact(self):
n =1
try:
self.driver.find_element_by_id('cn.com.open.mooc:id/tv_replace').click()
except Exception,e:
return n
Appium+python自动化3-定位元素的更多相关文章
- Appium+Python自动化 2 定位元素方式
1.找到 Android SDK安装路径tools 下面的 uiautomatorviewer.bat,如下截图 2.点击uiautomatorviewer.bat进行启动,左上角一共四个按钮,作用分 ...
- Appium+python自动化-查看app元素属性
本文转自:https://www.cnblogs.com/yoyoketang/p/7581831.html 前言 学UI自动化首先就是定位页面元素,玩过android版的appium小伙伴应该都知道 ...
- appium+python自动化32-android_uiautomator定位进阶版
前言 上一篇介绍uiautomator的定位方式都是类似这种'new UiSelector().xxx("xxx")',看起非常长,我也记不住,这很不python.于是本篇优化了定 ...
- appium+python自动化30-list定位(find_elements)
前言 有时候页面上没有id属性,并且其它的属性不唯一,平常用的比较多的是单数(element)的定位方法,遇到元素属性不唯一,就无法直接定位到了. 于是我们可以通过复数(elements)定位,先定位 ...
- appium+python自动化31-android_uiautomator定位
前言 appium就是封装android的uiautomator这个框架来的,所以uiautomator的一些定位方法也可以用 text 1.通过text文本定位语法 new UiSelector() ...
- appium+python自动化28-name定位
前言 appium1.5以下老的版本是可以通过name定位的,新版本从1.5以后都不支持name定位了 name定位报错 1.最新版appium V1.7用name定位,报错: selenium.co ...
- appium+python自动化34-获取元素属性get_attribute
获取text # coding:utf-8 from appium import webdriver from time import sleep desired_caps = { 'platform ...
- appium+python自动化58-xpath定位
基本属性定位 以淘宝app为例,定位左上角扫一扫按钮 1.可以通过text文本定位到 //*[@text='text文本属性'] # 定位text driver.find_element_by_xpa ...
- Appium+python自动化28-name定位【转载】
本篇转自博客:上海-悠悠 前言 appium1.5以下老的版本是可以通过name定位的,新版本从1.5以后都不支持name定位了 一. name定位报错 1.最新版appium V1.7用name定位 ...
随机推荐
- ubuntu oracle 环境搭建
安装 Oracle SQL Developer Oracle客户端安装 https://oracle.github.io/odpi/doc/installation.html#linux
- numpy笔记
numpy数组切片 import numpy as np arr = np.empty((8, 3))for i in range(8): arr[i] == i arr[1,2] # 选取第1行第2 ...
- 焊接关节(Weld Joint)
package{ import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.Joints ...
- linux 3.10 的又一次hung
最近又遇到一次hung,dmesg中堆栈如下: [176223.913270] ------------[ cut here ]------------ [ PID: at net/sched/sch ...
- Haskell语言学习笔记(91)Comprehension Extensions
Comprehension Extensions 关于解析式的相关语言扩展. List and Comprehension Extensions 24 Days of GHC Extensions: ...
- ReactiveX 学习笔记(11)对 LINQ 的扩展
Interactive Extensions(Ix) 本文的主题为对 Ix 库,对 LINQ 的扩展. Buffer Ix.NET Buffer Ix.NET BufferTest Buffer 方法 ...
- [SQL]UNPIVOT 多個欄位
有朋友問「如何直接unpivot成2個欄位」,如下所示, 先準備測試資料如下, view source print? 01 create table T ( 02 no varchar(10), 03 ...
- Nodejs 菜鸟教程学习-创建第一个应用
注:为了解学习,都是参照http://www.runoob.com/nodejs/nodejs-tutorial.html书写,做下笔记. 对于Nodejs开发来说,在开发一个应用时,我们不仅仅是实现 ...
- 18.4 运行脚本 sudo ./launcher.sh 必须先给他权限 才能使用
我们发现我们每次启动服务都要打一大堆命令,ng build --watch ,nodemon server.js ,等等 凡是重复的工作,我们要可以代码完成 要想运行它呢 你必须将你运行的上述(脚本中 ...
- C++ MFC 改变控件大小和位置
用CWnd类的函数MoveWindow()或SetWindowPos()可以改变控件的大小和位置. void MoveWindow(int x,int y,int nWidth,int nHeight ...