selenium 等待_Selenium等待:内隐,外显,流利和睡眠
selenium 等待
Selenium等待頁面加載在Selenium腳本中起著重要的作用。 它們有助于使它們不易剝落,更可靠。 Selenium提供多次等待,以根據(jù)某些條件在腳本執(zhí)行中提供足夠的等待或暫停。 從而確保您在使用Selenium執(zhí)行自動(dòng)化測(cè)試時(shí)不會(huì)導(dǎo)致腳本失敗。 在本教程中,我們將解釋Selenium等待和睡眠的類型,并提供實(shí)時(shí)示例以及對(duì)它們的比較研究。 讓我們首先回答一個(gè)關(guān)鍵問題:“為什么要使用Selenium等待?”
為什么我們需要Selenium等待?
大多數(shù)現(xiàn)代應(yīng)用程序的前端都是基于JavaScript或Ajax構(gòu)建的,使用諸如React,Angular之類的框架,或任何其他需要花費(fèi)一定時(shí)間才能在頁面上加載或刷新Web元素的框架。 因此,如果您傾向于在腳本中找到尚未加載到頁面上的元素,則selenium會(huì)向您拋出“ ElementNotVisibleException ”消息。
下面的代碼段將幫助您展示與使用Selenium執(zhí)行自動(dòng)化測(cè)試時(shí)相同的問題。 在此代碼段中,我使用的是easymytrip.com的示例,在該示例中,post用戶選擇行程日期的“ From”和“ To”目的地,Web應(yīng)用程序需要花費(fèi)一些時(shí)間來加載所需的航班詳細(xì)信息。 在這種情況下,用戶無需等待就可以從列表中預(yù)訂第一個(gè)航班。 現(xiàn)在,由于頁面尚未加載,腳本無法找到“立即預(yù)訂”按鈕。 結(jié)果拋出“ NoSuchElementException ”。 下面的代碼段和控制臺(tái)輸出:
import java.util.concurrent.TimeUnit; ? import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; ? import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor; ? public class NoWaitImplemented { ?public static void main(String[] args) throws InterruptedException { ????????System.setProperty( "webdriver.chrome.driver" , ".\\Driver\\chromedriver.exe" ); ????????WebDriver driver= new ChromeDriver(); ????????driver.manage().window().maximize(); ????????????????driver.get( " https://www.easemytrip.com/ " ); ????????driver.findElement(By.id( "FromSector_show" )).sendKeys( "Delhi" , Keys.ENTER); driver.findElement(By.id( "Editbox13_show" )).sendKeys( "Mumbai" , Keys.ENTER); driver.findElement(By.id( "ddate" )).click(); driver.findElement(By.id( "snd_4_08/08/2019" )).click(); driver.findElement(By.className( "src_btn" )).click(); driver.findElement(By.xpath( "//button[text()='Book Now']" )).click(); ?????????????????????????????} ? } 控制臺(tái)輸出:
我已經(jīng)使用XPath通過腳本對(duì)Selenium進(jìn)行自動(dòng)化測(cè)試來查找Web元素。
:帶有示例的Selenium中使用XPath的完整指南
Selenium等待頁面加載有助于解決此問題。 Selenium等待有不同類型,例如隱式等待和顯式等待,可確保在Selenium腳本發(fā)現(xiàn)元素之前,將元素加載到頁面中以進(jìn)行進(jìn)一步的操作。
Selenium類型等待頁面加載
使用Selenium執(zhí)行自動(dòng)化測(cè)試時(shí),我們?cè)谏蒘elenium腳本時(shí)使用以下類型的等待:
- Thread.Sleep()方法
- 隱式等待
- 顯式等待
- 流利的等待
讓我們深入了解其中的每一個(gè)。
Thread.Sleep()用于使用Selenium進(jìn)行自動(dòng)化測(cè)試
Sleep是屬于線程類的靜態(tài)方法。 可以使用類名(即Thread)的引用來調(diào)用此方法。 如果在使用Selenium執(zhí)行自動(dòng)化測(cè)試時(shí)使用Thread.sleep ,則此方法將在指定的時(shí)間段內(nèi)停止腳本的執(zhí)行,無論在網(wǎng)頁上是否找到該元素。 它接受持續(xù)時(shí)間(以毫秒為單位)。 相同的語法是:
Thread.sleep(3000);
睡眠函數(shù)拋出InterruptedException,因此應(yīng)使用try-catch塊進(jìn)行處理,如下所示:
try { Thread.sleep( 5000 ); } catch (InterruptedException ie){ }為什么使用Thread.Sleep()不是一個(gè)好主意?
現(xiàn)在,我將重點(diǎn)介紹使用thread.sleep()的一些缺點(diǎn)。
- Selenium Webdriver等待指定的時(shí)間,無論是否找到元素。 如果在指定的持續(xù)時(shí)間之前找到元素,腳本將仍然等待持續(xù)的時(shí)間,從而增加了腳本的執(zhí)行時(shí)間。
- 如果要顯示的元素在靜態(tài)時(shí)間后沒有出現(xiàn)并且一直在變化,那么您將永遠(yuǎn)不會(huì)知道睡眠功能所需的估計(jì)時(shí)間。 如果花費(fèi)的時(shí)間超過了定義的時(shí)間,腳本將拋出錯(cuò)誤。 這就是為什么,如果您正在使用Selenium waits處理動(dòng)態(tài)元素,那么最好不要使用Thread.sleep()。
- Thread.sleep僅適用于之前編寫的元素。 如果您有兩到四個(gè)元素需要等待一定的時(shí)間才能加載,則在這種情況下,需要多次指定Thread.sleep。 如果這樣做的話! 好吧,您到處都會(huì)發(fā)現(xiàn)腳本中充滿了Thread.sleep()語法。
由于上述缺點(diǎn),在腳本創(chuàng)建中使用Thread.Sleep()被認(rèn)為是一種不好的做法。
下面的代碼片段突出顯示了Thread.Sleep()在Selenium自動(dòng)化測(cè)試中的用法。 在此示例中,我們使用與上面的easymytrip相同的示例,在該示例中,一旦用戶單擊搜索,我們將停止線程執(zhí)行。 在這種情況下,代碼可以正常運(yùn)行,而不會(huì)引發(fā)任何錯(cuò)誤。
import java.util.concurrent.TimeUnit; ? import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; ? import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor; ? public class ThreadWait { ?public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub ????????//setting the driver executable System.setProperty( "webdriver.chrome.driver" , ".\\Driver\\chromedriver.exe" ); ????????//Initiating your chromedriver WebDriver driver= new ChromeDriver(); ????????driver.manage().window().maximize(); ????????????????driver.get( " https://www.easemytrip.com/ " ); ????????driver.findElement(By.id( "FromSector_show" )).sendKeys( "Delhi" , Keys.ENTER); driver.findElement(By.id( "Editbox13_show" )).sendKeys( "Mumbai" , Keys.ENTER); driver.findElement(By.id( "ddate" )).click(); driver.findElement(By.id( "snd_4_08/08/2019" )).click(); driver.findElement(By.className( "src_btn" )).click(); Thread.sleep( 5000 ); driver.findElement(By.xpath( "//button[text()='Book Now']" )).click(); ?????????????????????????????????} ? }現(xiàn)在,如果我有同一應(yīng)用程序的另一個(gè)頁面需要花費(fèi)一些時(shí)間來加載,該怎么辦? 在這種情況下,我不想在腳本中多次使用thread.sleep()。
您可能會(huì)認(rèn)為,如果不是Thread.sleep(),那么哪個(gè)Selenium等待頁面加載就足以滿足測(cè)試要求?
在這種情況下,這就是隱式等待的地方。 讓我們?cè)敿?xì)檢查隱式Selenium。
Selenium隱式等待自動(dòng)化測(cè)試
Selenium克服了Thread.sleep()提供的問題,提出了兩個(gè)Selenium等待頁面加載的方法。 其中之一是隱式等待,它允許您將WebDriver暫停特定的時(shí)間,直到WebDriver在網(wǎng)頁上找到所需的元素為止。
這里要注意的關(guān)鍵點(diǎn)是,與Thread.sleep()不同,它不等待整個(gè)時(shí)間段。 如果在指定的持續(xù)時(shí)間之前找到元素,它將繼續(xù)執(zhí)行代碼的下一行,從而減少了腳本執(zhí)行的時(shí)間。 這就是為什么隱式等待也稱為動(dòng)態(tài)等待的原因。 如果未在指定的持續(xù)時(shí)間內(nèi)找到該元素,則拋出ElementNotVisibleException 。
關(guān)于隱式等待的另一件值得注意的事情是它是全局應(yīng)用的,這使其比Thread.sleep()更好。 這意味著您只需編寫一次即可,它適用于整個(gè)WebDriver實(shí)例中腳本上指定的所有Web元素。 方便嗎? 實(shí)現(xiàn)相同的語法是:
driver.manage().timeouts().implicitlyWait(Time Interval to wait for , TimeUnit.SECONDS);隱式等待的默認(rèn)時(shí)間為零,并且每隔500毫秒會(huì)不斷輪詢所需的元素。 讓我們看下面的代碼片段,展示隱式等待的用法。 在此示例中,我使用了相同的easymytrip示例。 在這種情況下,我們將向前邁進(jìn)并繼續(xù)進(jìn)行預(yù)訂過程,在此過程中頁面需要花費(fèi)更多的時(shí)間來加載。 這里有兩個(gè)頁面的頁面加載問題,我們使用隱式等待而不是多次使用Thread.sleep()來處理一行代碼。
import java.util.concurrent.TimeUnit; ? import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.Select; ? import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor; ? public class ImplicitWait { ?public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub ????????//setting the driver executable System.setProperty( "webdriver.chrome.driver" , ".\\Driver\\chromedriver.exe" ); ????????//Initiating your chromedriver WebDriver driver= new ChromeDriver(); ????????driver.manage().window().maximize(); ????????driver.manage().timeouts().implicitlyWait( 30 , TimeUnit.SECONDS); driver.get( " https://www.easemytrip.com/ " ); ????????driver.findElement(By.id( "FromSector_show" )).sendKeys( "Delhi" , Keys.ENTER); driver.findElement(By.id( "Editbox13_show" )).sendKeys( "Mumbai" , Keys.ENTER); driver.findElement(By.id( "ddate" )).click(); driver.findElement(By.id( "snd_4_08/08/2019" )).click(); driver.findElement(By.className( "src_btn" )).click(); ?driver.findElement(By.xpath( "//button[text()='Book Now']" )).click(); ????????JavascriptExecutor jse = (JavascriptExecutor)driver; jse.executeScript( "window.scrollBy(0,750)" ); ????????driver.findElement(By.xpath( "//input[@type='email']" )).sendKeys( "sadhvisingh9049@gmail.com" ); ????????driver.findElement(By.xpath( "//span[text()='Continue Booking']" )).click(); ????????WebElement title=driver.findElement(By.id( "titleAdult0" )); ????????Select titleTraveller= new Select(title); ????????titleTraveller.selectByVisibleText( "MS" ); driver.findElement(By.xpath( "//input[@placeholder='Enter First Name']" )).sendKeys( "Sadhvi" ); driver.findElement(By.xpath( "//input[@placeholder='Enter Last Name']" )).sendKeys( "Singh" ); ????????driver.findElement(By.xpath( "//input[@placeholder='Mobile Number']" )).sendKeys( "9958468819" ); ????????driver.findElement(By.xpath( "//div[@class='con1']/span[@class='co1']" )).click(); ?????????} ? }現(xiàn)在,在這里我們知道了一個(gè)事實(shí),即應(yīng)該在一定的持續(xù)時(shí)間內(nèi)加載頁面,但是如果我們不知道加載時(shí)元素是可見/可點(diǎn)擊的,該怎么辦。 由于它的出現(xiàn)是動(dòng)態(tài)的,并且會(huì)不時(shí)地變化。 在這種情況下,顯式等待將幫助您克服此問題。 讓我們研究它的細(xì)節(jié)。
明確等待使用Selenium進(jìn)行自動(dòng)化測(cè)試
顯式等待是動(dòng)態(tài)Selenium等待的另一種。 顯式等待幫助可在特定的時(shí)間內(nèi)基于特定條件停止腳本的執(zhí)行。 時(shí)間到頭后,您將獲得ElementNotVisibleException 。 在您不知道要等待的時(shí)間的情況下,此顯式等待會(huì)派上用場(chǎng)。 使用elementToBeClickable()或textToBePresentInElement()之類的條件 ,可以等待指定的持續(xù)時(shí)間。 可以結(jié)合使用WebDriverWait和ExpectedConditions類來使用這些預(yù)定義方法。 為了使用這種情況,請(qǐng)?jiān)谀恼n程中導(dǎo)入以下軟件包:
import org.openqa.selenium.support.ui.ExpectedConditions import org.openqa.selenium.support.ui.WebDriverWait發(fā)布此代碼后,需要為WebDriverWait類創(chuàng)建一個(gè)引用變量,并使用WebDriver實(shí)例實(shí)例化該變量,并提供可能需要的Selenium等待頁面加載的數(shù)量。 時(shí)間單位是秒。 可以如下定義它:
WebDriverWait wait = new WebDriverWait(driver, 30 );為了使用ExpectedCondition類的預(yù)定義方法,我們將使用如下的wait引用變量:
wait.until(ExpectedConditions.visibilityOfElementLocated(Reference of Element to be located using locator));預(yù)期條件的類型:
以下是在使用Selenium執(zhí)行自動(dòng)化測(cè)試時(shí)通常使用的幾種預(yù)期條件。
- visibleOfElementLocated()-驗(yàn)證給定元素是否存在
- alertIsPresent()-驗(yàn)證是否存在警報(bào)。
- elementToBeClickable()-驗(yàn)證給定元素是否在屏幕上存在/可單擊
- textToBePresentInElement()-驗(yàn)證給定元素是否具有必需的文本
- titlels()-驗(yàn)證條件,等待具有給定標(biāo)題的頁面
還有更多可用的預(yù)期條件,您可以通過Selenium官方GitHub頁面進(jìn)行引用。 像隱式等待一樣,顯式等待也會(huì)在每500毫秒后繼續(xù)輪詢。
下面是突出顯示顯式Selenium等待的用法的代碼段。 在此示例中,我們使用的是“ rentomojo”應(yīng)用程序,其中的模式在動(dòng)態(tài)時(shí)間顯示在主頁上。 使用顯式等待,根據(jù)元素的可見性,我們將等待元素并關(guān)閉彈出窗口。 參考代碼:
import java.util.concurrent.TimeUnit; ? import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; ? public class ExplicitWait { ?public static void main(String[] args) { // TODO Auto-generated method stub ????????//setting the driver executable System.setProperty( "webdriver.chrome.driver" , ".\\Driver\\chromedriver.exe" ); ????????????????//Initiating your chromedriver WebDriver driver= new ChromeDriver(); ????????????????????????????????????????????????driver.manage().window().maximize(); ????????????????driver.get( " https://www.rentomojo.com/ " ); ????????????????driver.findElement(By.xpath( "//span[@class='rm-city__selectorBoxLoca'][contains(text(),'Delhi')]" )).click(); ????????????????????????????????????????????????WebDriverWait wait= new WebDriverWait(driver, 120 ); ????????????????????????????????wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath( "//div[@class='Campaign__innerWrapper']/button" )))); driver.findElement(By.xpath( "//div[@class='Campaign__innerWrapper']/button" )).click(); ?} ? }注意-當(dāng)同時(shí)使用隱式等待和顯式等待時(shí),它們將在累積時(shí)間上工作,而不是在單個(gè)等待條件下工作。 例如,如果給定隱式等待30秒,給定顯式等待10秒,則它正在尋找的顯式元素將等待40秒。
Selenium等待之間的區(qū)別:顯式與隱式
現(xiàn)在,由于您已經(jīng)知道隱式等待和顯式等待的用法,因此讓我們研究一下這兩個(gè)Selenium等待之間的區(qū)別:
| 默認(rèn)情況下,它將應(yīng)用于腳本中的所有元素。 | 它僅適用于特定條件的特定元素。 |
| 我們不能根據(jù)指定條件(例如元素selectable / clickable)而不是顯式進(jìn)行等待。 | 明確地說,我們可以根據(jù)特定條件指定等待時(shí)間。 |
| 當(dāng)您確定該元素在特定時(shí)間內(nèi)可能可見時(shí),通常使用它 | 當(dāng)您不知道元素可見性的時(shí)間時(shí),通常使用它。 它具有動(dòng)態(tài)性質(zhì)。 |
Fluent等待使用Selenium進(jìn)行自動(dòng)化測(cè)試
就其功能而言,Fluent等待類似于顯式等待。 在Fluent等待中,當(dāng)您不知道某個(gè)元素可見或單擊所需的時(shí)間時(shí),將對(duì)它執(zhí)行Selenium等待。 Fluent等待提供的一些差異因素是:
- 輪詢頻率-在顯式等待的情況下,默認(rèn)情況下此輪詢頻率為500毫秒。 使用Fluent wait,您可以根據(jù)需要更改此輪詢頻率,即,您可以告訴腳本在每個(gè)“ x”秒之后繼續(xù)檢查元素。
- 忽略異常-在輪詢期間,如果找不到元素,則可以忽略任何異常,例如'NoSuchElement'異常等。
除了這些差異因素(例如顯式等待或隱式等待)之外,您還可以定義等待元素可見或可操作的時(shí)間。 以下語法或代碼行用于定義Selenium中的Fluent等待:
默認(rèn)情況下,它將應(yīng)用于腳本中的所有元素。語法似乎很復(fù)雜,但是一旦開始使用,它可能會(huì)變得很方便。 可能這是測(cè)試人員選擇進(jìn)行顯式等待而不是進(jìn)行Fluent等待的最大原因之一。 另外,Explicit等待和Fluent等待之間的主要區(qū)別在于Explicit Selenium Wait提供了預(yù)定義條件,這些條件適用于我們需要等待的元素,而對(duì)于Fluent Selenium Wait,則可以定義自己的自定義條件適用方法中的條件。
我對(duì)Fluent Selenium Wait的看法?
我個(gè)人還沒有在實(shí)時(shí)示例中找到任何有用的流暢等待的實(shí)現(xiàn),因此到目前為止,我希望自己不要執(zhí)行它。 我和您一樣渴望Selenium 4的發(fā)布 。 我希望在發(fā)布之后,我們可以對(duì)使用Fluent等待而不是其他Selenium等待的實(shí)際優(yōu)勢(shì)有更多的了解。 到目前為止,根據(jù)我的經(jīng)驗(yàn),我碰巧傾向于使用Explicit Selenium wait,因?yàn)樗菷luent Selenium wait更容易實(shí)現(xiàn)代碼。 如果您有其他意見,請(qǐng)?jiān)谙旅娴脑u(píng)論中告訴我。
Selenium的角色等待基于云的Selenium網(wǎng)格
大多數(shù)測(cè)試人員通常更喜歡使用基于云的服務(wù)提供商執(zhí)行自動(dòng)化的網(wǎng)站測(cè)試,以進(jìn)行Selenium測(cè)試,例如LambdaTest(云上的跨瀏覽器測(cè)試工具)。 想知道為什么嗎?
那么,如果您在基于云的Selenium網(wǎng)格(例如LambdaTest)上運(yùn)行自動(dòng)化腳本 ,會(huì)發(fā)生什么呢? Selenium等待如何有助于有效的測(cè)試結(jié)果?
每個(gè)基于云的提供程序都會(huì)在拋出Selenium超時(shí)異常之前提供默認(rèn)的時(shí)間限制。 這樣做是為了防止過度利用云資源。 在LamdaTest中,默認(rèn)超時(shí)為90秒。 現(xiàn)在,如果您對(duì)Web元素的加載時(shí)間超過90秒,那該怎么辦?
這就是Selenium等待出現(xiàn)的地方。 如果您的測(cè)試套件很復(fù)雜,可能會(huì)在云Selenium Grid上面臨超時(shí)問題,那么您可以使用Selenium wait將WebDriver暫停默認(rèn)時(shí)間超過90秒。 因此,避免在成功運(yùn)行自動(dòng)化腳本時(shí)發(fā)生超時(shí)錯(cuò)誤。
Selenium的最終裁決正在等待中!
Selenium Waits可以幫助您減少腳本的脆弱性和可靠性。 無論選擇哪種等待方式,都要確保它能幫助您實(shí)現(xiàn)Selenium自動(dòng)化測(cè)試背后的目標(biāo)。 另一要注意的關(guān)鍵是要確保在應(yīng)用程序中不保留不必要的Selenium等待。 Thread.sleep()過去可能是一個(gè)選項(xiàng),但是現(xiàn)在我們有了新的Selenium等待和來臨,我寧愿建議您遠(yuǎn)離Thread.sleep()來推動(dòng)Selenium自動(dòng)化測(cè)試。 因此,下一次您遇到了元素或頁面加載問題時(shí),便知道在哪里尋找。 測(cè)試愉快!
翻譯自: https://www.javacodegeeks.com/2019/08/selenium-waits-implicit-explicit-fluent-sleep.html
selenium 等待
總結(jié)
以上是生活随笔為你收集整理的selenium 等待_Selenium等待:内隐,外显,流利和睡眠的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何设计高效测试用例_高效的企业测试-单
- 下一篇: 都说给电脑安装操作系统难我就纳闷了,分段