在進行UI自動化測試的時候,咱們爲了保持用例的穩定性,每每要設置顯示等待,顯示等待就是說明確的要等到某個元素的出現或者元素的某些條件出現,好比可點擊、可見等條件,若是在規定的時間以內都沒有找到,那麼就會拋出Exception
.python
上面是我用selenium
寫的一個測試用例,展現了selenium
中顯示等待的使用方式,其中會使用到expected_conditions
模塊和WebDriverWait
類,注意這裏expected_conditions
是一個py文件的文件名,也就是一個模塊名,這個模塊下面有不少的條件類,而咱們用例中使用的title_is
就是一個條件類。web
WebDriverWait
是一個類,這個類的做用就是根據必定的條件,不斷的檢查這個條件是否被知足了。WebDriverWait
類只有兩個方法,一個是until
直到知足某個條件,另外一個是until_not
直到不知足某個條件。chrome
class WebDriverWait(object): def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
WebDriverWait
有四個參數分別是, driver
驅動, timeout
超時時間, poll_frequency=POLL_FREQUENCY
輪訓時間,也就是去判斷條件是否知足的時間間隔,默認是0.5秒, ignored_exceptions=None
在等待的過程當中須要忽略的異常,是一個可迭代的異常類集合,好比咱們能夠設置一個list,裏面是[NoSuchElementException,NoSuchAttributeException,InvalidElementStateException....]
,默認狀況下,是一個元組,只包含一個NoSuchElementException
,由於只有元素出現,才能去判斷條件是否知足,在不斷輪訓的過程當中,確定會發生NoSuchElementException
,這個時候必須忽略掉這個異常,否則程序就會中斷。windows
其中driver
和timeout
是畢傳的位置參數,另外兩個是選擇傳遞的關鍵字參數,若是不傳都有指定的默認值。dom
下面就進入咱們今天的主題,selenium中的等待條件的討論函數
在selenium.webdriver.support.expected_conditions
這個模塊裏,存放着全部的等待條件,每一個條件類的結構都是同樣的一個__init__
構造方法和一個__call__
方法。測試
在python中,若是想把類型的對象當作函數來使用,那麼就能夠給這個類實現__call__
方法,以下:url
class TestCase: def __init__(self): self.driver = webdriver.Chrome(executable_path="./driver/chromedriver") self.driver.get('http://www.baidu.com') # sleep(2) def __call__(self): print(self.driver.title) if __name__ == '__main__': case = TestCase() case()
case()
對象的調用,就會執行__call__
方法裏面的邏輯打印當前頁面的標題,咱們取一個selenium的實現類:code
class presence_of_element_located(object): def __init__(self, locator): self.locator = locator def __call__(self, driver): return _find_element(driver, self.locator)
這個條件類的意思是判斷一個元素是否已經渲染到頁面當中,在使用這個條件的時候須要先實例化,傳入元素的定位,而後要進行判斷的時候須要對實例對象進行調用並傳入driver
,對實例對象進行調用的時候就會執行__call__
方法裏的條件判斷邏輯。對象
WebDriverWait
是如何進行條件判斷的再回到文章開頭看一下咱們使用顯示等待的代碼:
wait = WebDriverWait(self.driver, 2) wait.until(EC.title_is('百度一下,你就知道'))
先是實例化一個WebDriverWait
對象,而後再調用until
方法而且傳遞一個條件的實例對象,until
方法裏就會不斷的去輪訓條件是否知足。
def until(self, method, message=''): screen = None stacktrace = None end_time = time.time() + self._timeout while True: try: value = method(self._driver) if value: return value except self._ignored_exceptions as exc: screen = getattr(exc, 'screen', None) stacktrace = getattr(exc, 'stacktrace', None) time.sleep(self._poll) if time.time() > end_time: break raise TimeoutException(message, screen, stacktrace)
method
這個參數就是咱們傳遞進來的條件的實例對象,value = method(self._driver)
這裏就是進行對象的調用,也就是執行了__call__
方法裏的邏輯。
以上就是selenium支持的全部條件。
說了那麼多條件,其實咱們也能夠本身實現一個條件類,
class page_is_load: def __init__(self, expected_title, expected_url): self.expected_title = expected_title self.expected_url = expected_url def __call__(self, driver): is_title_correct = driver.title == self.expected_title is_url_correct = driver.current_url == self.expected_url return is_title_correct and is_url_correct
上面是本身實現的一個條件類,根據頁面的url和標題來判斷頁面是否被正確加載,
class TestCase: def __init__(self): self.driver = webdriver.Chrome(executable_path="./driver/chromedriver") self.driver.get('http://www.baidu.com/') # sleep(2) def __call__(self): print(self.driver.title) def test_wait(self): wait = WebDriverWait(self.driver, 2) wait.until(page_is_load("百度一下,你就知道", "http://www.baidu.com/"))
歡迎你們去 個人博客 瞅瞅,裏面有更多關於測試實戰的內容哦!!