技術(shù)分享 | app自動化測試(Android)--顯式等待機制
WebDriverWait類解析
WebDriverWait 用法代碼
Python 版本
WebDriverWait(
? ?driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
參數(shù)解析:
driver:WebDriver 實例對象
timeout: 最長等待時間,單位秒
poll_frequency: 檢測的間隔步長,默認為 0.5s
ignored_exceptions: 執(zhí)行過程中忽略的異常對象,默認只忽略 TimeoutException 異常類
Java 版本
WebDriverWait(WebDriver driver, long timeOutInSeconds)
Java 版本常用的有兩個參數(shù),參數(shù)解析:
driver:WebDriver 實例對象
timeOutInSeconds: 最長等待時間,單位秒
until、util_not用法
WebDriverWait 通常與 until 和 util_not 結(jié)合使用,Java 與 Python 用法相同。
until(method, message=’’) 在規(guī)定時間內(nèi),每隔一段時間調(diào)用一下 method 方法,直到返回值為 True,如果超時拋出帶有 message 的 TimeoutException 異常信息
until_not(method, message=’’) 與 until( ) 方法相反,表示在規(guī)定時間內(nèi),每隔一段時間調(diào)用一下 method 方法,直到返回值為 False,如果超時拋出帶有 message 的 TimeoutException 異常信息
expected_conditions介紹
expected_conditions 是 Selenium 的一個模塊,其中包含一系列可用于判斷的條件??梢杂脕砼袛囗撁娴脑厥欠窨梢姡欠窨牲c擊等操作。
導入
需要先導入這個模塊,導入代碼如下:
Python 版本:
from selenium.webdriver.support import expected_conditions
Java 版本:
import org.openqa.selenium.support.ui.ExpectedConditions;
方法介紹
1.判斷元素是否被加到了 DOM 樹里,并不代表該元素一定可見,用法如下:
Python 版本
WebDriverWait().until(
? ?expected_conditions.presence_of_element_located(locator))
Java 版本
new WebDriverWait( )\
? ?.until(ExpectedConditions.presenceOfElementLocated(locator));
2.visibility_of_element_located(locator) 方法,用來判斷某個元素是否可見(可見代表元素非隱藏,并且元素的寬和高都不等于 0,用法如下:
Python 版本
WebDriverWait().until(
? ?expected_conditions.visibility_of_element_located(locator))
Java 版本
new WebDriverWait( ).until(
? ? ? ?ExpectedConditions.visibilityOfElementLocated(locator));
3.element_to_be_clickable(locator) 方法,判斷某元素是否可見并能點擊,用法如下:
Python 版本
WebDriverWait().until(
? ?expected_conditions.element_to_be_clickable((By.ID, "kw")))
Java 版本
new WebDriverWait( ).until(
? ?ExpectedConditions.elementToBeClickable(locator));
案例
使用“雪球”應用,打開雪球 APP,點擊頁面上的搜索輸入框輸入“alibaba”,然后在搜索聯(lián)想出來的列表里面點擊“阿里巴巴”,選擇股票分類,獲取股票類型為“09988”的股票價格,最后驗證價格大于 170,核心代碼如下:
Python 版本
...
def test_wait(self):
? ?# 點擊搜索輸入框
? ?self.driver.find_element_by_id(
? ? ? ?"com.xueqiu.android:id/tv_search").click()
? ?# 輸入 “alibaba”
? ?self.driver.find_element_by_id(
? ? ? ?"com.xueqiu.android:id/search_input_text"
? ? ? ?).send_keys("alibaba")
? ?# 點擊“阿里巴巴”
? ?self.driver.find_element_by_xpath("//*[@text='阿里巴巴']").click()
? ?# 點擊“股票”
? ?self.driver.find_element_by_xpath(
? ? ? ?"//*[contains(@resource-id,'title_container')]//*[@text='股票']"
? ? ? ?).click()
? ?# 獲取股票價格
? ?locator = (MobileBy.XPATH,
? ?"//*[@text='09988']/../../..\
? ?//*[@resource-id='com.xueqiu.android:id/current_price'")
? ?ele = WebDriverWait(self.driver,10)\
? ?.until(expected_conditions.element_to_be_clickable(locator))
? ?print(ele.text)
? ?current_price = float(ele.text)
? ?expect_price = 170
? ?# 判斷價格大于 expect_price
? ?assert current_price > expect_price
...
Java 版本
...
private final By locator = By.xpath("//*[@text='09988']/../../..\
? ?//*[@resource-id='com.xueqiu.android:id/current_price'");
@Test
public void waitTest(){
? ?// 點擊搜索輸入框
? ?driver.findElementById("com.xueqiu.android:id/tv_search").click();
? ?// 輸入 “alibaba”
? ?driver.findElementById("com.xueqiu.android:id/\
? ? ? ?search_input_text").sendKeys("alibaba");
? ?// 點擊“阿里巴巴”
? ?driver.findElementByXPath("//*[@text='阿里巴巴']").click();
? ?// 點擊“股票”
? ?driver.findElementByXPath("//*[contains(@resource-id,\
? ? ? ?'title_container')]//*[@text='股票']").click();
? ?// 獲取股票價格
? ?WebDriverWait wait=new WebDriverWait(driver, 10);
? ?wait.until(ExpectedConditions.elementToBeClickable(locator));
? ?String locatorText = driver.findElement(locator).getText();
? ?System.out.println(locatorText);
? ?float currentPrice = Float.parseFloat(locatorText);
? ?float expectPrice = 170;
? ?//判斷價格大于 expect_price
? ?assertThat(currentPrice, greaterThan(expectPrice));
}
...
這條測試用例僅僅使用隱式等待是解決不了問題的,因為【當前價格】這個元素一直在,而實際需要等待的是這個元素是否處于可點擊的狀態(tài)。
上面的代碼通過判斷元素是否可點擊的方法來判斷元素是否處于可點擊狀態(tài),中間添加了 10 秒的等待時間,在 10 秒之內(nèi)每隔 0.5 秒查找一次元素,如果找到了這個元素,就繼續(xù)向下執(zhí)行,如果沒找到就拋出 TimeoutException 異常信息。顯式等待可以在某個元素上靈活的添加等待時長,尤其是文件上傳,或者資源文件下載的場景中,可以添加顯式等待,提高腳本的穩(wěn)定性。
一般來說,在項目中會使用隱式等待與顯式等待結(jié)合的方式,定義完 driver 之后立即設置一個隱式等待,在測試過程中需要判斷某個元素屬性的時候,再加上顯式等待。