Python Selenium自動化測試框架 元素等待機制

白碼會說發表於2020-12-02

Time will tell.

由於可能會突然地資源受限或網路延遲,導致找不到目標元素。這時測試報告會顯示測試失敗,這裡就需要一種延時機制,來使指令碼的執行速度與程式的響應速度相匹配, WebDriver 為這種情況提供了隱式等待顯式等待兩種機制。

1、隱式等待

一旦設定隱式等待時間,就會作用於這個 WebDriver 例項的整個生命週期(對所有的元素查詢都生效),設定隱式等待時間後, Webdriver 會在一定時間內持續檢測和搜尋 DOM ,以便於查詢一個或多個不是立即載入成功並可用的元素。隱式等待的預設時間是 0。 WebDriver 使用implicitly_wait()來設定等待時間,單位秒。超過等待時間還沒找到,就報NoSuchElementException異常。

# 設定超時時間為10秒
driver.implicitly_wait(10)

2、顯式等待

WebDriver 提供了WebDriverWait類和expected_conditions模組來實現顯式等待。相比隱式等待,顯示等待更加智慧。顯示等待就是設定一個前置條件,在等待時間內,每隔一段時間檢查一次前置條件是否滿足,滿足則執行下一步,超時則報TimeoutException異常。

3、WebDriverWait類

WebDriverWait(driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None)

driver:瀏覽器驅動例項

timeout:等待時間,單位秒

poll_frequency:每隔多長時間檢查一次,預設0.5秒

ignored_exceptions:忽略的異常,預設只有NoSuchElementException

until方法 和 until_not方法:
- until(method, message=''):method指要執行的方法(等待時間內每隔一段時間,執行一次),直到返回值為true,超時則報TimeoutException異常,message將傳入異常(message引數可不填)
- until_not(method, message=''):直到返回值為false,其他和until相同

4、expected_conditions模組

expected_conditions模組提供了多種定義好的前置條件,需要配合 WebDriverWait 使用。

預期等待條件簡單說明
element_to_be_clickable(locator) 引數:locator,指一組(By,locator)等待查詢的元素可見並且可用,以便可以點選,返回定位到的元素
element_to_be_selected(locator)等待直到元素被選中
invisibility_of_element_located(locator)等待一個元素在DOM中不可見 或不存在
presence_of_all_elements_located(locator)等待至少有一個定位器查詢的元素出現在網頁中,返回一組元素
presence_of_element_located(locator)等待定位器查詢的元素出現在網頁中,或者可以在DOM中找到,返回一個被定位到的元素
text_to_be_present_in_element(locator,text) 引數:text,指定的文字等待元素能被定位,並且帶有指定的文字資訊
title_contains(title) 引數:title,指要校驗標題包含的字串等待網頁標題包含指定的字串,成功時返回True,否則返回false
title_is(title) 引數:title,指要校驗的標題等待網頁標題與預期一致,成功時返回True,否則返回false
visibility_of(element) 引數:element,指一個元素等待元素出現在DOM中,是可見的,並且寬和高都大於0,變為可見的,將返回一個元素(同一個)
visibility_of_element_located(locator)等待元素出現在DOM中,是可見的,並且寬和高都大於0,變為可見的,將返回一個元素
alert_is_present()判斷是否存在警告視窗

5、 expected_conditions示例

下面程式碼的 try 部分,每一部分都獨立可用(這裡註釋掉的只是驗證不同前置條件的用法)。另外這裡只對方法的使用方式進行說明,不對使用場景說明。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()
driver.maximize_window()
driver.get('https://www.cnblogs.com/')

# try:
#     #等待部落格園首頁的【找找看】按鈕可見並可用
#     search_btn = WebDriverWait(driver,10).until(expected_conditions.element_to_be_clickable((By.CLASS_NAME,'search_btn')))
#     print(search_btn.get_attribute('value'))

# try:
#     login_area = driver.find_element_by_css_selector('#login_area')
#     login = login_area.find_element_by_link_text('登入')
#     login.click()
#     remember_me = driver.find_element_by_id('remember_me')
#     remember_me.click()
#     #等待直到登入頁面的核取方塊被選中
#     WebDriverWait(driver, 10).until(expected_conditions.element_located_to_be_selected((By.ID, 'remember_me')))

# try:
#     search_file = driver.find_element_by_id('zzk_q')
#     search_btn = driver.find_element_by_class_name('search_btn')
#     search_file.send_keys('python')
#     search_btn.click()
#     #網頁標題是否包含 python
#     WebDriverWait(driver, 10).until(expected_conditions.title_contains('python'))

try:
    search_file = driver.find_element_by_id('zzk_q')
    #檢查元素是否出現在DOM中,是可見的,並且寬和高都大於0
    search_file = WebDriverWait(driver,10).until(expected_conditions.visibility_of(search_file))
    print(search_file)
finally:
    driver.quit()

6、示例

expected_conditions類提供了多種定義好的前置條件(預期等待條件),沒有前置條件符合時,也可以通過 WebDriverWait 自定義前置條件。下面這個是 WebDriverWait 類自帶的部分註釋。

class WebDriverWait(object):
    def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
        """
           Example:
            from selenium.webdriver.support.ui import WebDriverWait \n
            element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("someId")) \n
            is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).\ \n
                        until_not(lambda x: x.find_element_by_id("someId").is_displayed())
        """

lambda 表示式其實就是一個匿名函式,冒號左邊的可以理解為函式名及引數,右邊的可以理解為函式的返回值。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select

profile = webdriver.FirefoxProfile\
    (r'C:\Users\quanhua\AppData\Roaming\Mozilla\Firefox\Profiles\tnwjkr4m.selenium')
driver = webdriver.Firefox(profile)
driver.maximize_window()
driver.get('https://home.cnblogs.com/')
try:
    #等待 部落格園個人主頁中的下拉選單有5個可選項
    WebDriverWait(driver,10).until(lambda l:len(Select(l.find_element_by_id('sel_application')).options) == 5)
finally:
    driver.quit()


應用元素等待機制,對於構建高度穩定可靠的測試是必不可少的。在使用過程中,應該儘量避免隱式等待顯示等待混合使用。至於隱式等待顯示等待的優缺點,書上、網上一般是推薦顯示等待。我自己也試了下,暫時沒看出來在執行速度方面有多大區別。

好嘍,分享就到這裡啦,哈哈。如果你對Python自動化軟體測試、面試題等更多內容感興趣,在這裡推薦一個學習資料分享扣裙:175317069。有各項已整理好的測試學習資源,也有行業深潛多年的技術人分析講解。

測試工程師職業發展路線:
功能測試 — 介面測試 — 自動化測試 — 測試開發 — 測試架構師

作為測試工程師,不斷提升自己工作能力是提高薪資待遇最重要的基礎。另外也要注重學習, IT 行業是個不斷髮展、更新迭代相對較快的行業,技術具有明顯的時代特徵,所以緊跟時代技術的發展才能讓自己不掉隊,在職場當中具有足夠的競爭力。

覺得還不錯就【點贊】、【評論】、【關注】吧~

Time will tell.(時間會說明一切)

相關文章