使用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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章