使用Python學習selenium測試工具-6:同步

webdriver支持顯式和隱式的同步。本節主要內容如下:

  • 顯式和隱式等待

  • 何時使用顯式和隱式的等待

  • 使用預期條件

  • 創建自定義的等待狀態

使用隱式等待

隱式等待提供了通用的方法同步測試和步驟。適用於網絡響應時間不一致或者使用Ajax調用渲染元素的時候。

隱式等待的默認超時時間是0,對整個webdriver生效。這個功能我們在第2章就有使用,現在我們把當時實例的隱式等待時間從30秒改成10秒。

import unittest
from selenium import webdriver


class SearchProductTest(unittest.TestCase):
    def setUp(self):
        # create a new Firefox session
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

        # navigate to the application home page
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_search_by_category(self):

        # get the search textbox
        self.search_field = self.driver.find_element_by_name('q')
        self.search_field.clear()

        # enter search keyword and submit
        self.search_field.send_keys('phones')
        self.search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver\
            .find_elements_by_xpath("//h2[@class='product-name']/a")

        # check count of products shown in results
        self.assertEqual(3, len(products))

    def tearDown(self):
        # close the browser window
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

針對具體案例,顯式案例通常隱式案例要好。

explicit_wait_tests.py

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


class ExplicitWaitTests(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_account_link(self):
        WebDriverWait(self.driver, 10)\
            .until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')

        account = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
        account.click()

    def test_create_new_customer(self):
        # click on Log In link to open Login page
        self.driver.find_element_by_link_text('ACCOUNT').click()

        # wait for My Account link in Menu
        my_account = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()

        # get the Create Account button
        create_account_button = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))

        # click on Create Account button. This will displayed new account
        create_account_button.click()
        WebDriverWait(self.driver, 10)\
            .until(expected_conditions.title_contains('Create New Customer Account'))

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)


expected_conditions類

完整的屬性和方法參見:selenium.webdriver.support.expected_conditions

該類的常見方法如下:

Method Description Argument Example
element_to_be_clickable(locator) This will wait for an element to be located and be visible and enabled so that it can be clicked. This method returns the element that is located back to the test. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver, 10).until(expected_conditions.element_to_be_clickable((By.NAME,“is_subscribed”)))
element_to_be_selected(element) This will wait until a specified element is selected. element: This is the WebElement?. subscription = self.driver.find_element_by_name(“is_subscribed”) WebDriverWait?(self.driver, 10).until(expected_conditions.element_to_be_selected(subscription))
invisibility_of_element_located(locator) This will wait for an element that is either invisible or is not present on the DOM. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver, 10).until(expected_conditions.invisibility_of_element_located((By.ID,“loading_banner”)))
presence_of_all_elements_located(locator) This will wait until at least one element for the matching locator is present on the web page. This method returns the list ofWebElements? once they are located. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver,10).until(expected_conditions.presence_of_all_elements_located((By.CLASS_NAME,“input-text”)))
presence_of_element_located(locator) This will wait until an element for the matching locator is present on a web page or available on the DOM. This method returns an element once it is located. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver, 10).until(expected_conditions.presence_of_element_located((By.ID,“search”)))
text_to_be_present_in_element(locator, text_) This will wait until an element is located and has the given text. locator: This is a tuple of (by, locator). text: This is the text to be checked. WebDriverWait?(self.driver,10).until(expected_conditions.text_to_be_present_in_element((By.ID,“sele language”),“English”))
title_contains(title) This will wait for the page tile to contain a casesensitive substring.This method returns true if the tile matches, false otherwise。 title: This is the substring of the        title        to check. WebDriverWait?(self.driver, 10).until(expected_conditions.title_contains(“Create New Customer Account”))
title_is(title) This will wait for the page tile to be equal to the expected title. This method returns true if the tile matches, false otherwise. title: This is the title of the page. WebDriverWait?(self.driver, 10).until(expected_conditions.title_is(“Create New Customer Account -Magento Commerce Demo Store”))
visibility_of(element) This will wait until an element is present in DOM, is visible, and its width and height are greater than zero. This method returns the (same)WebElement? once it becomes visible. element: This is the WebElement?. first_name = self.driver.find_element_by_id(“firstname”) WebDriverWait?(self.driver,10).until(expected_conditions.visibility_of(first_name))
visibility_of_element_located(locator) This will wait until an element to be located is present in DOM, is visible, and its width and height are greater than zero. This method returns theWebElement? once it becomes visible. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver,10).until(expected_conditions.visibility_of_element_located((By.ID,“firstname”)))

前一章的彈出窗口處理得不夠好,現在我們修改下:comparetests.py

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


class CompareProducts(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_compare_products_removal_alert(self):
        # get the search textbox
        search_field = self.driver.find_element_by_name('q')
        search_field.clear()

        # enter search keyword and submit
        search_field.send_keys('phones')
        search_field.submit()

        # click the Add to compare link
        self.driver.\
            find_element_by_link_text('Add to Compare').click()

        # wait for Clear All link to be visible
        clear_all_link = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.visibility_of_element_located((By.LINK_TEXT, 'Clear All')))

        # click on Clear All link,
        # this will display an alert to the user
        clear_all_link.click()

        # wait for the alert to present
        alert = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.alert_is_present())

        # get the text from alert
        alert_text = alert.text

        # check alert text
        self.assertEqual('Are you sure you would like to remove all products from your comparison?',
                          alert_text)
        # click on Ok button
        alert.accept()

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

參考資料

  • 作者:Unmesh        Gundecha

  • 評審:Adil        Imroz:alam.adil12#gmail.com   Twitter        at        @adilimroz

  • 評審:Dr .        Philip        Polstra         介紹 博客

  • 評審: Walt        Stoneburner: wls#wwco.com Walt.Stoneburner#gmail.com 博客

  • 維基百科Selenium英文介紹

發佈了28 篇原創文章 · 獲贊 21 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章