Selenium3 + Python3自動化測試系列六——等待方式
等待
一、等待是什麼,為什麼要等待
在做自動化測試,設計測試用例的時候,有時下一步的操作會依賴上一步的結果或者內容,上一步操作成功之後才能進行下一步操作等,
這時候,我們就需要使用等待,來判斷上一步操作是否完成,什麼時候可以進行下一步操作。否則,上一步操作如果花費的時間較長,
還沒有完成,就去進行下一步操作,這時就會產生無法定位到元素,元素狀態不正確,資料校驗結果不正確等異常。
在Selenium中常用的等待分為顯示等待WebDriverWait(),隱式等待implicitly_wait(),強制等待sleep()三種。
二、Selenium的3種等待方式
time.sleep(n)
強制等待n秒。Python本身的函式,包含在time包中,使用前需要匯入time包。我們之前的例項中經常會使用這種等待,方便大家能看清指令碼執行的結果。
這種等待方法十分笨拙,無論頁面載入得如何,都必須等待n秒,可以說是十分不智慧了。
WebDriverWait(n)
最長等待n秒,n秒內每隔一段時間去檢查需要定位的元素是否存在,若存在則提前結束等待。也是WebDriver提供的等待方法,也被稱為顯性等待,
這種等待比隱性等待更智慧了一些,無視整個頁面的載入,只要需要的元素存在了,就結束等待。
implicitly_wait(n)
最長等待n秒,若n秒內頁面載入完成,則提前結束等待。WebDriver提供的等待方法,也被稱為隱性等待,比強制等待聰明瞭一點,但如果頁面本身包含一個超大視訊之類的檔案,
就算我們需要定位的元素在最開始已經加載出來,卻依舊要等待所有檔案載入結束之後,指令碼才能繼續執行,依舊算是有些弊端。
三、強制等待(sleep)
舉個栗子,如下程式碼自動化開啟百度首頁,強制等待5秒,列印瀏覽器地址,並關閉瀏覽器。
from selenium.webdriver import Chrome import time driver = Chrome("C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe") driver.get('https://www.baidu.com/') #強制等待5秒 time.sleep(5) print(driver.current_url) driver.quit()
強制等待時間。不管瀏覽器是否載入完成,都必須強制等待5s時間,方法太粗暴,不建議經常使用這種強制等待方法~
四、顯示等待(WebDriverWait)
匯入顯示等待:from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait類是由WebDirver 提供的等待方法。在設定時間內,預設每隔一段時間檢測一次當前頁面元素是否存在,如果超過設定時間檢測不到則丟擲異常。顯式等待使WebdDriver等待某個條件成立時繼續執行,否則在達
到最大時長時丟擲超時異常(TimeoutException)。
顯示等待格式如下:WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver :瀏覽器驅動 timeout :最長超時時間,預設以秒為單位 poll_frequency :檢測的間隔(步長)時間,預設為0.5S
ignored_exceptions :超時後的異常資訊,預設情況下拋NoSuchElementException異常。
WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的說明。
(1)until(method, message=‘’)
呼叫該方法提供的驅動程式作為一個引數,直到返回值為True。
(2)until_not(method, message=‘’)
呼叫該方法提供的驅動程式作為一個引數,直到返回值為False。
我們舉個栗子,如下程式碼所示,在丟擲TimeoutException異常之前將等待10秒或者在10秒內發現了查詢的元素。開啟百度首頁,查詢是否有ID為kw的元素。
from selenium.webdriver import Chrome from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = Chrome("C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe") driver.get('https://www.baidu.com/') #顯式等待 element = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.ID, "kw"))) driver.quit()
selenium的expected_conditions模組收集了一系列的場景判斷方法,如上述程式碼中EC.presence_of_all_elements_located方法,介紹一下expected_conditions幾種常用的場景判斷方法。
title_is: 判斷當前頁面的title是否精確等於預期
title_contains: 判斷當前頁面的title是否包含預期字串
presence_of_element_located: 判斷某個元素是否被加到了dom樹裡,並不代表該元素一定可見
visibility_of_element_located: 判斷某個元素是否可見.可見代表元素非隱藏,並且元素的寬和高都不等於0
visibility_of: 跟上面的方法做一樣的事情,只是上面的方法要傳入locator,這個方法直接傳定位到的element就好了
presence_of_all_elements_located: 判斷是否至少有1個元素存在於dom樹中。舉個例子,如果頁面上有n個元素的class都是‘column-md-3‘,那麼只要有1個元素存在,這個方法就返回True
text_to_be_present_in_element: 判斷某個元素中的text是否包含了預期的字串
text_to_be_present_in_element_value: 判斷某個元素中的value屬性是否包含了預期的字串
frame_to_be_available_and_switch_to_it: 判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False
invisibility_of_element_located: 判斷某個元素中是否不存在於dom樹或不可見
element_to_be_clickable: 判斷某個元素中是否可見並且是enable的,這樣的話才叫clickable
staleness_of: 等某個元素從dom樹中移除,注意,這個方法也是返回True或False
element_to_be_selected: 判斷某個元素是否被選中了,一般用在下拉列表
element_selection_state_to_be: 判斷某個元素的選中狀態是否符合預期
element_located_selection_state_to_be: 跟上面的方法作用一樣,只是上面的方法傳入定位到的element,而這個方法傳入locator
alert_is_present: 判斷頁面上是否存在alert
五、隱式等待(implicitly_wait)
隱式等待是指在嘗試查詢一個或多個元素(如果它們不是立即可用)時,WebDriver輪詢DOM一段時間。預設設定為0
。設定後,將為WebDriver物件例項的生命週期設定隱式等待
隱式等待舉個栗子,開啟百度頁面,查詢id為su的元素
from selenium.webdriver import Chrome driver = Chrome("C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe") #隱式等待 driver.implicitly_wait(10) driver.get("https://www.baidu.com/") element = driver.find_element_by_id("su")
implicitly_wait()預設引數的單位為秒,本例中設定等待時長為10秒。首先這10秒並非一個固定的等待時間,它並不影響指令碼的執行速度。其次,它並不針對頁面上的某一元素進行等待。當指令碼執行到某個元素定位時,如果元素可
以定位,則繼續執行;如果元素定位不到,則它將以輪詢的方式不斷地判斷元素是否被定位到。假設在第6秒定位到了元素則繼續執行,若直到超出設定時長(10秒)還沒有定位到元素,則丟擲異