一、等待方式
为避免出现页面未完全加载出来,代码已经执行,而引起的报错NoSuchElement。需要在操作步骤中加入等待机制。
强制等待 time.sleep(5)
强制休眠一段时间,但实际测试过程中由于不同设备性能差异,网络问题等导致页面加载时间不确定,因此设置多少合理就变成了难题,所以在实际使用时不建议使用。
隐式等待 driver,implicity(15)
隐式等待是webdriver 提供的一个超时等待。在规定时间内动态等待设定的秒数后出现。如果设置了10秒会在10秒内不停的查找元素,在10秒内查找到就继续执行后面的代码,如果超过了10秒就会抛出异常。一旦设置了隐式等待,它则会在整个Web Driver对象的实例声明周期中。
显式等待 WebDriverWait(driver,10)
显示等待是针对页面某个特定元素设置的等待时间,在设置事件内,默认每隔一段时间(0.5秒)检测一次当前页面某个元素是否存在。找到则执行相关操作,超时则抛出异常:NosuchElementException.显示等待必须在每个需要等待的元素前面进行声明。
显示等待可以等待动态加载的ajax元素,比隐式等待更加灵活。显式等待用到两个类:WebDriverWait和expected_conditions。
WebDriverWait解析&用法
WebDriverWait(driver, timeout, poll_frequency=0.5, ignore_exceptions=None)
driver:webdriver实例
timeout 最长等待时间,单位秒
poll_frequency 检测步长 默认0.5秒
ignore_exceptions 执行过程中忽略的异常对象,默认只忽略timeout
expected_conditions解析
expected_conditions类是selenium的一个模块,其中包含一系列可用于判断的条件,可以用来判断页面元素是否可见,是否可点击等。
from selenium.wendriver.support import expected_conditions
方法介绍
1、presence_of_element_located(locator)方法,用来判断元素是否被加载到了DOM树中,并不代表元素一定可见
WebDriverWait().util(expected_conditions.presence_of_element_located(元素对象))
2、visibility_of_element_located(locator)方法,用来判断某个元素是否可见(非隐藏且宽高都!=0)
WebDriverWait().util(expected_conditions.visibility_of_element_located(元素定位符))
3、element_to_be_clickable(locator)方法,判断元素是否可见并能够点击
WebDriverWait().util(expected_conditions.element_to_be_clickable((By.ID, "kw"))
二、元素定位方式
Appium常用元素定位方式
通过ID定位:android系统称为: resource-id
driver.find_element_by_id()
通过content- desc定位: 当inspector能抓到唯一的content-desc时候,可采用content-desc定位
driver.find_element_by_accessiblity_id()
通过name定位
driver.find_element_by_name()
通过class- name定位
driver.find_element_by_class_name()
通过xpath定位:相对路径和绝对路径
driver.find_element_by_xpath()
相对路径:利用元素属性中的唯一标识
xpath:text属性定位 driver.find_element(By.XPATH,’//*[@text="我的"]‘).click()
xpath:resource-id属性定位 driver.find_element(By.XPATH,’//*[@resource-id="login"]‘).click()
xpath:class属性定位 driver.find_element(By.XPATH,’//*[@class="android.login"]‘).click()
xpath:content-desc属性定位 driver.find_element(By.XPATH,’//*[@conten-desc="索搜"]‘).click()
XPATH高级用法
xpath模糊定位
contains()方法是模糊匹配的定位方法,对于一个元素的id或者text不是固定的,但有一部分是固定,这种就可以模糊匹配如://*[contains(@content-desc,"帮助")],//*[contains(@text,"注册")]
xpath组合定位
同时匹配2个甚至多个属性来完成。包括text、resource-id、class、index、content-desc等任意组合
'//*[@text="我的" and @resource-id="tab_name"]'或'//*[@text="注册/登录" and @index="1"]'
xpath层级定位
定位元素时可能涉及到用子元素去定位父元素,或者父元素定位子元素或者兄弟元素
子元素定位父元素
方法一: driver.find_element_by_xpath('//*[@text="手机号"]/..').tag_name
方法一: driver.find_element_by_xpath('//*[@text="手机号"]/parent::*').tag_name
通过元素定位兄弟元素
driver.find_element_by_xpath('//*[@text="手机号"]/../li').tag_name
Android Uiautomator定位技巧
android uiautomator是android SDK自带的一个测试框架,提供了一系列的Api可以与android APP进行交互,例如打开菜单,点击,滑动等。当appium脚本的uiautomationName设置为UiAutomator2时,就能够实现与手机端的Uiautomator进行通信并使用UIautomator执行测试代码。基础语法:
driver.find_element_by_android_uiautomator()
常用的方式有:UiSelector() UiScrollable()
通过text文本定位
UiSelector()与xpath类似可以通过元素的text属性定位 new UiSelector().text("text 文本"),还可以使用包含、以某个文字开头等用法new UiSelector().textContains("login"),new UiSelector().textStartsWith("log")
通过resource-id定位
new UiSelector().resourceId("resource-id 属性")
通过class定位
new UiSelector().className("classname")
通过content- desc定位
new UiSelector().description("content-desc 属性")
组合定位
driver.find_element_by_android_uiautomator('new UiSelector().resouceId(\
"com.xueqiu.android:id/tv_login_phone").text("手机号")').click()
滑动查找元素
driver.find_element_by_android_uiautomator(
'new UiScrollable(new UiSelector().scrollable(true)\
.instance(0)).scrollIntoView(new UiSelector().text("我的").instance(0));').click()
上面的代码,在当前页面滚动查找text文本是“我的”这个元素,找到后执行点击操作
三、控件API交互
查看全部API以pycharm为例
1、在IDE中将鼠标放在REmote()方法上,按住ctrl+鼠标左键,点击进入到方法定义的类
2、点击后进入到webdriver.py文件,在pycharm左下侧边栏找到并点击Structure能够看到WebDriver下面的方法和属性,灰色的是从其他类继承来的。
常用API介绍
点击操作 self.driver.find_element_by_id("id").click()
输入操作 self.driver.find_element_by_id("id").send_keys("hell")
获取元素属性 self.driver.find_element_by_id("id").get_attribute("class")
能够被get_attribute()获取到的属性有:
获取text属性 self.driver.find_element_by_id("id").get_attribute("text")
获取class属性 self.driver.find_element_by_id("id").get_attribute("class")
获取resource-id属性 self.driver.find_element_by_id("id").get_attribute("resource-id")
获取content-desc属性 self.driver.find_element_by_id("id").get_attribute("content-desc")
获取元素的其他属性
get_attribute("clickable") 可点击的状态,返回true或false
get_attribute("checked") 选中的状态,返回true或false
get_attribute("displayed") 可见的状态,返回true或false
get_attribute("enable") 可用的状态,返回true或false
获取页面源码
driver.page_source可以获取页面的源代码。与selenium不一样,appium的方法打印的是XML格式,而selenium输出的是HTML格式。它实现的基本上就是appium inspector中所呈现的内容,只不过是XML结构。
触屏操作自动化
工作中我们经常要对页面进行手势操作,比如滑动、长按、拖动等。AppiumDriver为我们提供了一个模拟手势的辅助类Touch Action,可以通过它实现对屏幕的手势操作
from appium.webdriver.common.touch_actionimport TouchAction
常用手势操作
Press按下:对某个元素或者坐标,通常会结合release()方法实现对元素的点击
在某控件上执行 press(WebElement el)
在某坐标上执行 press(int x, int y)
在某控件的左上角x坐标偏移x个单位,左边y坐标偏移y个单位上执行 press(WebElement el,int x, int y)
release: 可结合其他事件使用,代表该系列动作的一个结束
在某控件上执行释放 release(element el)
在上一个操作结束后执行release,不添加任何参数 release()
move to: 移动到目标(控件或位置)
以控件为目标,从另一个点移动到该目标上 move_to(element el)
以坐标为目标,从另一点移动到该点 move_to(element, int x, int y)
tap: 在某控件中心点击一下
在某控件中心点击 tap(WebElement el)
在某坐标上点击 tap(int x, int y)
以控件的左上角为基准,X轴向右移动X个单位,y轴向下移动y个单位 tap(WebElement el,int x, int y)
wait: 等待,单位为毫秒,可精确到纳秒
wait()
wait(long timeout)
wait(long timeout, int nanos)
longpress:实现长按,源代码self._add_action('longPress', self._get_opts(el, x, y, duration))
参数描述:el 元素;x,y坐标;duration持续时间;元素和坐标提供一个即可。
在某控件上执行 longpress(WebElement el)
在某坐标上执行 longpress(int x, int y)
在某控件的左上角x坐标偏移x个单位,左边y坐标偏移y个单位上执行 longpress(WebElement el,int x, int y)
cancel:取消事件链中的事件 cancel()
perform:执行的操作发送到服务器,一般最后调用 perform()