UI自動化測試,大多都是通過定位頁面元素來模擬實際的生產場景操作。但在編寫自動化測試腳本中,經常出現元素定位不到的情況,究其原因,無非兩種情況:1、有frame;2、沒有設置等待。
因為代碼運行速度和瀏覽器加載渲染速度,不是一個量級,所以導致了這種情況發生。webdriver提供了3種類型的等待:顯式等待、隱式等待、強制等待。
1、顯示等待
定義:等待某個條件成立時繼續執行,否則在達到最大時長時拋出異常(TimeoutException);
1 WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None) 2 driver:瀏覽器驅動 3 timeout:最長超時時間 4 poll_frequency:檢測間隔時間,默認0.5s 5 ignored_exceptions:超時后的異常信息,默認情況拋出NoSuchElementException異常 6 WebDriverWait()一般由until()或until_not方法配合使用,下面是這兩種方法的說明: 7 until(method,message=''):調用該方法提供的驅動程序作為一個參數,直到返回值為True; 8 until_not(method,message=''):調用該方法提供的驅動程序作為一個參數,直到返回值為Flase;
示例代碼如下:
1 # coding = utf-8 2 from selenium import webdriver 3 from selenium.webdriver.support.wait import WebDriverWait 4 from selenium.webdriver.support import expected_conditions as EC 5 from selenium.webdriver.common.by import By 6 7 driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe") 8 driver.implicitly_wait(10) 9 driver.get('http://www.cnblogs.com/imyalost/') 10 locator = (By.LINK_TEXT, '老_張') 11 12 try: 13 WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator)) 14 print(driver.find_element_by_link_text('老_張').get_attribute('href')) 15 finally: 16 driver.close()
代碼解析:
本例中,通過as關鍵字將expected_conditions重命名為EC,並調用presence_of_element_located()方法判斷元素是否存在;
上面的例子中,同時使用了隱性等待和顯性等待,但是需要注意的是:等待的最長時間取兩者之中的最大值;
1 title_is: 判斷當前頁面的title是否完全等於(==)預期字符串,返回布爾值 2 title_contains : 判斷當前頁面的title是否包含預期字符串,返回布爾值 3 presence_of_element_located : 判斷某個元素是否被加到了dom樹里,並不代表該元素一定可見 4 visibility_of_element_located : 判斷某個元素是否可見. 可見代表元素非隱藏,並且元素的寬和高都不等於0 5 visibility_of : 跟上面的方法做一樣的事情,只是上面的方法要傳入locator,這個方法直接傳定位到的element就好了 6 presence_of_all_elements_located : 判斷是否至少有1個元素存在於dom樹中。舉個例子,如果頁面上有n個元素的class都是‘column-md-3‘,那么只要有1個元素存在,這個方法就返回True 7 text_to_be_present_in_element : 判斷某個元素中的text是否 包含 了預期的字符串 8 text_to_be_present_in_element_value : 判斷某個元素中的value屬性是否 包含 了預期的字符串 9 frame_to_be_available_and_switch_to_it : 判斷該frame是否可以switch進去,如果可以的話,返回True並且switch進去,否則返回False 10 invisibility_of_element_located : 判斷某個元素中是否不存在於dom樹或不可見 11 element_to_be_clickable : 判斷某個元素中是否可見並且是enable的,這樣的話才叫clickable 12 staleness_of : 等某個元素從dom樹中移除,注意,這個方法也是返回True或False 13 element_to_be_selected : 判斷某個元素是否被選中了,一般用在下拉列表 14 element_selection_state_to_be : 判斷某個元素的選中狀態是否符合預期 15 element_located_selection_state_to_be : 跟上面的方法作用一樣,只是上面的方法傳入定位到的element,而這個方法傳入locator 16 alert_is_present : 判斷頁面上是否存在alert
2、隱式等待
定義:通過設定的時長等待頁面元素加載完成,再執行下面的代碼,如果超過設定時間還未加載完成,則繼續執行下面的代碼(注意:在設定時間內加載完成則立即執行下面的代碼);
隱式等待的方法為:implicitly_wait,示例代碼如下:
1 # coding = utf-8 2 from selenium import webdriver 3 4 driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe") 5 driver.implicitly_wait(10) # 隱性等待,最長等10秒 6 driver.get('http://www.cnblogs.com/imyalost/') 7 8 print(driver.current_url) 9 driver.quit()
代碼解析:
本例中,設置的等待時長為10秒,但這10秒並非一個固定時間,並不影響腳本執行速度;其次,隱式等待對整個driver的周期都起作用,因此只需要設置一次即可。
3、強制等待
即sleep()方法,由python中的time模塊提供,強制讓代碼等待xxx時間,無論前面的代碼是否執行完成或者還未完成,都必須等待設定的時間。
示例代碼如下:
1 # coding = utf-8 2 from selenium import webdriver 3 from time import sleep 4 5 driver = webdriver.Chrome("F:\安裝工具\python\chromedriver.exe") 6 driver.get('http://www.cnblogs.com/imyalost/') 7 8 sleep(5) 9 10 print(driver.current_url) 11 driver.quit()
代碼解析:
本例中,設置強制等待時間為5秒,5秒之后,打印獲取到的當前頁面的url,然后關閉窗口。
這種強制等待的方法,在debug時候很有用,不過建議慎用這種方法,因為太死板,嚴重影響程序執行速度!
以上三種等待方法,在具體的場景中需要根據情況選擇合適的方法,靈活運用。。。