Selenium中的幾種等待方式,需特別注意implicitlyWait的用法
最近在專案過程中使用selenium 判斷元素是否存在的時候 遇到一個很坑爹的問題, 用以下方法執行的時候每次都會等待很長一段時間,原因是因為對selenium實現方法瞭解不足導致一直找不到解決方法。
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
不明所以, 經過追蹤原始碼才發現啟動Driver的時候 使用driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS); 此處設定的等待時間 是針對全域性設定的,webdriver中執行所有命令 的超時時間都設定為30秒了, 如上面的findElement方法,找不到元素會預設等待三十秒。 有些時候只需簡單判斷元素是否存在,立馬執行,而此處的設定導致 指令碼執行緩慢。 將Selenium中的等待時間貼出來給大家張張經驗。
Selenium的延遲等待分為 顯式等待(Explicit Wait) & 隱式等待(Implicit Wait).
1.顯式等待
顯式等待,就是明確的要等到某個元素的出現或者是某個元素的可點選等條件,等不到,就一直等,除非在規定的時間之內都沒找到,那麼就跳出Exception.
如:
1 |
new WebDriverWait(driver, 15 ).until( |
2 |
ExpectedConditions.presenceOfElementLocated(By.cssSelector( "css
locator" )) |
3 |
); |
這裡,15是要等待的秒數.如果沒有滿足until()方法中的條件,就會始終在這裡wait 15秒,依然找不到,就丟擲異常.
也可以這樣寫:
01 |
WebDriver driver = new FirefoxDriver(); |
03 |
WebElement e = ( new WebDriverWait(
driver, 10 ))
.until( |
04 |
new ExpectedCondition<
WebElement>(){ |
05 |
@Override |
06 |
public WebElement
apply( WebDriver d) { |
07 |
return d.findElement(
By.id( "id locator" )); |
08 |
} |
09 |
} |
10 |
); |
這樣就通過回撥函式,直接獲得了這個WebElement.也就是頁面元素.
如果只是僅僅想判斷頁面是不是載入到某個地方了,就可以用第一種方法; 但如果需要得到某個WebElement,兩種方式都可以,只是第一種方式還需要再多一步獲取的操作.
1 |
Wait w = new Wait(){ |
2 |
@Override |
3 |
public boolean until()
{ |
4 |
return webElement.isDisplayed(); |
5 |
} |
6 |
}; |
另外這種等待的方式,在載入js程式碼的時候做判斷會比較方便,反正我只在程式碼裡這麼見過,但是沒用過,有興趣的朋友可以研究一下.
2.隱式等待
1 |
driver.manage().timeouts().implicitlyWait(second,
TimeUnit.SECONDS); |
隱式等待, 此處的隱式等待是針對Driver 每次執行命令的 最長執行時間也可以理解為超時時間, 一些人對此處有誤解,認為是讓Driver等一段時間, 確實某些時候能讓Driver等一段時間, 但是影響是全域性的,每次Driver執行 找不到元素都會等待此處設定的時間, 假設某處將此值設定的太長,必須在執行完成之後還原回來,否則判斷一個元素是否存在的時候,就會遇到很坑爹的問題。 改進後的方法如下:
WebDriver會進行一個隱式等待,但引數只有時間,這就導致我需要什麼元素出現,我不一定能等到它,
private boolean isElementPresent(By by) {
try {
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}