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定位 ...
随机推荐
- 选择、操作web元素-2
11月3日 等待web元素的出现 例子:百度搜索松勤网,点击操作后不等待页面刷新,下面选择页面元素的时候,该元素还是未出现 sleep方案的弊病:固定的等待时间,导致测试用例执行时间很长 为什么cli ...
- MongoDB 全部笔记
1. MongoDB: 是NOSQL的一种, 特长是分布式用的,用于处理爬虫数据 2. mongoDB 与 redis mongoDB是最像关系型的非关系型数据,更加适用于大数据,redis则更倾向于 ...
- 20165304《Java程序设计》第五周学习总结
教材学习内容总结 第七章 1.内部类 注意内部类和外嵌类的关系: 外嵌类的成员变量和方法在内部类有效 内部类的类体不可以声明static变量和方法.外嵌类的类体可以用内部类声明对象. 内部类仅供它的外 ...
- golang判断文件/文件夹是否存在
使用os包,os.stat返回err==nil,说明存在: os.IsNotExist(err)为true,说明不存在:否则不确定是否存在 func DelJar(fileName string) e ...
- PHP中Notice: unserialize(): Error at offset of bytes in on line 的解决方法
使用unserialize函数将数据储存到数据库的时候遇到了这个报错,后来发现是将gb2312转换成utf-8格式之后,每个中文的字节数从2个增加到3个之后导致了反序列化的时候判断字符长度出现了问题, ...
- easyUi弹出window窗口传值与调用父页面的方法,子页面给父页面赋值
<!-- 父页面 --> <!DOCTYPE html PUBLIC "-/W3C/DTD HTML 4.01 Transitional/EN" "ht ...
- linux mce的一些相关内容和用户态监控的设计方法
之所以想起写一点关于mce的东西,倒不是因为遇到mce的异常了,之前遇到过很多mce的异常,内存居多,但没有好好记录下来,写这个是因为参加2018 clk南京会议的一点想法. void __init ...
- ReactiveX 学习笔记(2)创建数据流
操作符(Operators) Rx 的操作符能够操作(创建/转换/组合) Observable. Creating Observables 本文主题为创建/生成 Observable 的操作符. 这里 ...
- RxJava2.0学习笔记2 2018年7月3日 周二
摘记: 1.map -- 转换 有些服务端的接口设计,会在返回的数据外层包裹一些额外信息,这些信息对于调试很有用,但本地显示是用不到的.使用 map() 可以把外层的格式剥掉,只留下本地会用到的核心 ...
- C# 如何获取屏幕的截图,以及如何在图像上添加文字
关键代码为 Screen sc = Screen.PrimaryScreen; Rectangle rct = sc.Bounds; Image img = new Bitmap(rct.Width, ...