快速入門
Selenium是一個簡便的Web應用軟體測試框架。Selenium的元件Selenium IDE支援錄製/回放。它還支援Python,Java,C#,javascript等語言。支援Windows,Linux和Macintosh。它是 開源軟體,根據Apache2.0許可證釋出的,並可以下載並無償使用。
歷史
Selenium來源於由傑森·哈金斯 (Jason Huggins)在2004年在ThoughtWorks的開發內部工具,後面有ThoughtWorks的其他程式設計師和測試人員在 ThoughtWorks加入。後來Paul Hammant加入開發了’Selenium Remote Control’ (RC)並開源。
2005年Dan Fabulich和Nelson Sproul在Pat Lightbody的幫助下給Selenium-RC做了一些補丁。同時ThoughtWorks在Huggins和Hammant代表的情況下組建了Selenium委員會。
2007 年哈金斯和Jennifer Bevan等加盟谷歌。他繼續Selenium RC的開發和穩定。與此同時,西蒙·斯圖爾特(Simon Stewart)在ThoughtWorks開發出了卓越的瀏覽器自動化工具webdriver。2009年在谷歌測試自動化大會上決定合併兩個專案,新 專案叫Selenium WebDriver,即Selenium 2.0。
2008年,ThoughtWorks的Philippe Hanrigou開發了’Selenium Grid’,支援同時在任意數量的本地或遠端系統執行多個Selenium測試,從而減少測試執行時間。Selenium Grid提供類似谷歌內部Selenium RC雲專案的功能,但是它是開源的。Pat Lightbody也開發了一個類似的私有云:’HostedQA’,並賣給了Gomez公司。
當時有個類似的軟體叫Mercury,及汞,哈金斯就取名為硒,可以通過服用硒補充劑治癒汞中毒。
元件
支援瀏覽器: Firefox、Internet Explorer、Google Chrome、Safari和Opera。
支援作業系統:Linux, Windows和Mac OS X。
- Selenium IDE
Selenium IDE是Selenium測試完整的整合開發環境(IDE)。它是Firefox外掛,並允許錄製,編輯和除錯。這是以前被稱為Selenium Recorder,最初是由Shinya Kasatani開發並於2006年捐贈給Selenium。
指令碼會自動錄製,可以事後編輯,編輯時可以自動完成並快速移動命令。指令碼記錄在Selenese的(Selenium特殊的測試指令碼語言)。Selenese可以在瀏覽器中執行操作命令(如點選連結,選擇選項),並從網頁中檢索資料。
- Selenium client API
目前支援Python, Java,C#,Ruby。
- Selenium Remote Control(webdriver已經棄用)
Selenium Remote Control (RC)是Java編寫的服務,通過HTTP接收瀏覽器的命令(類似代理伺服器)。RC支援多種程式語言對Web應用進行測試,方便整合進語言的單元測試 框架。支援PHP,Python和Ruby,.NET,Perl和Java客戶端驅動程式。java驅動通過Rhino engine支援JavaScript。一個埠只支援一個例項,但是Java/PHP中一個埠可以支援多個例項。RC來源於Paul Hammant和Jason。
Selenium Remote Control來源於Paul Hammant的Driven Selenium或Selenium B。最初的版本直接在程式語言中啟動程式和瀏覽器互動,Selenese在各種語言中實現。Dan Fabulich和Nelson Sproul在Pat Lightbody的幫助下改進後,測試指令碼和和瀏覽器之間增加了守護程式,這樣就可以驅動遠端瀏覽器,並只需要維護一套Selenese語言。2006 年RC完全替代Driven Selenium。RC和Driven Selenium瀏覽器模式是響應/請求,即Comet。
Selenium 2釋出時,已經建議用webdriver替代RC。
- Selenium WebDriver:
Selenium WebDriver是RC的替代。它接受命令(Selenese或者API),併傳送給瀏覽器。呼叫特定瀏覽器的驅動,傳送命令到瀏覽器,並獲取結果。多 數瀏覽器驅動啟動和訪問瀏覽器應用程式(如Firefox或Internet Explorer);另外還有瀏覽器的HtmlUnit驅動程式,它用模擬使用瀏覽器。
Selenium WebDrive不需要特殊的伺服器來執行測試。webdriver直接啟動瀏覽器例項並控制它。Selenium Grid可以用於的webdriver執行遠端測試。
2012 年初,Simon Stewart(webdriver的發明者,當時在google工作,現在在Facebook)和Mozilla的David Burns與W3C協商將WebDriver作為網際網路標準。2013年初草案發布,Selenium-Webdriver為參考實現。目前 Selenium-WebDriver在Python和Ruby,Java和C#有完整的支援。
- Selenium Grid(Selenium standalone server)
Selenium Grid是允許在遠端機器上執行的Web瀏覽器例項的服務。Selenium Grid允許執行測試在多臺計算機上並行,以及管理的不同版本的瀏覽器和瀏覽器配置。甚至支援移動作業系統:Android和Apple iOS。
快速入門
Selenium WebDriver python client可以訪問Selenium WebDriver和Selenium standalone server,開發人員:David Burns, Adam Goucher, Maik Röder,Jason Huggins, Luke Semerau, Miki Tebeka和Eric Allenin。支援python版本2.6, 2.7, 3.2和3.3。
安裝:
1 |
pip install -U selenium |
需要選擇一個合適IDE,要求如下:
- 程式碼完成和智慧提示的圖形化程式碼編輯器
- 函式和類的程式碼瀏覽器
- 語法高亮
- 專案管理
- 程式碼模板
- 單元測試和除錯
- 原始碼控制支援
推薦:WingIDE,PyCharm,PyDev Eclipse plugin,PyScripter。相關下載地址如下:
例項1:在網站python自動化測試上面尋找webdriver相關的頁面,並輸出相關的網址:
注意:本例項因為http://automationtesting.vipsinaapp.com及http://automationtesting.sinaapp.com已經因為新浪收費原因關閉匿名使用者查詢,已經不能執行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#!/usr/bin/env python # encoding: utf-8 import time from selenium import webdriver # create a new Firefox session driver = webdriver.Firefox() driver.implicitly_wait(30) driver.maximize_window() # navigate to the application home page driver.get("http://automationtesting.sinaapp.com/") # get the search textbox search_field = driver.find_element_by_name("q") search_field.clear() # enter search keyword and submit search_field.send_keys("webdriver") search_field.submit() time.sleep(6) products = driver.find_elements_by_xpath("//a[@class='searchable']") # get the number of anchor elements found print "Found " + str(len(products)) + " pages:" # iterate through each anchor element and # print the text that is name of the product for product in products: print product.get_attribute('href') # close the browser window driver.quit() |
selenium.webdriver實現了瀏覽器驅動類,涉及 Firefox, Chrome, Internet Explorer, Safari等瀏覽器及用於測試遠端機器的類RemoteWebDriver。
driver.implicitly_wait(30)表示最多等待頁面開啟的時間為30秒。
執行結果:
1 2 3 |
Found 2 pages: http://automationtesting.sinaapp.com/blog/python_selenium1 http://automationtesting.sinaapp.com/blog/appium |
例項2開啟網址,搜尋產品,並列出產品名。例項的網站為:magentocommerce,程式碼下載地址:learnsewithpython。
注意:上面演示的網址可能需要梯子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
from selenium import webdriver # create a new Firefox session driver = webdriver.Firefox() driver.implicitly_wait(30) driver.maximize_window() # navigate to the application home page driver.get("http://demo.magentocommerce.com/") # get the search textbox search_field = driver.find_element_by_name("q") search_field.clear() # enter search keyword and submit search_field.send_keys("phones") search_field.submit() # get all the anchor elements which have product names displayed # currently on result page using find_elements_by_xpath method products = driver.find_elements_by_xpath("//h2[@class='product-name']/a") # get the number of anchor elements found print "Found " + str(len(products)) + " products:" # iterate through each anchor element and # print the text that is name of the product for product in products: print product.text # close the browser window driver.quit() |
執行結果:
1 2 3 |
Found 2 products: MADISON EARBUDS MADISON OVEREAR HEADPHONES |
跨瀏覽器支援
IE
selenium下載頁面地址。為了在Internet Explorer上面執行,需要下載配置InternetExplorerDriver服務,它是測試指令碼和Internet Explorer之間的膠水。
在上述下載頁面搜尋InternetExplorerDriver,下載32位或者64位版本,並解壓到合適的目錄。在IE7以上的版本,選擇Tools 選單下面的Internet Options,在彈出視窗選擇Security標籤,把每個zone的Protected Mode設定為關或者開啟的情況都設定為中。另外要特別注意IE的縮放要選擇為100%才正確地進行座標對應。
例項1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#!/usr/bin/env python # encoding: utf-8 import time from selenium import webdriver ie_driver_path = "e:IEDriverServer.exe" # create a new Firefox session driver = webdriver.Ie(ie_driver_path) driver.implicitly_wait(30) driver.maximize_window() # navigate to the application home page driver.get("http://automationtesting.sinaapp.com/") # get the search textbox search_field = driver.find_element_by_name("q") search_field.clear() # enter search keyword and submit search_field.send_keys("webdriver") search_field.submit() time.sleep(6) products = driver.find_elements_by_xpath("//a[@class='searchable']") # get the number of anchor elements found print "Found " + str(len(products)) + " pages:" # iterate through each anchor element and # print the text that is name of the product for product in products: print product.get_attribute('href') # close the browser window driver.quit() |
例項2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import os from selenium import webdriver # get the path of IEDriverServer # dir = os.getcwd() ie_driver_path = "e:IEDriverServer.exe" # create a new Internet Explorer session driver = webdriver.Ie(ie_driver_path) driver.implicitly_wait(30) driver.maximize_window() # navigate to the application home page driver.get("http://demo.magentocommerce.com/") # get the search textbox search_field = driver.find_element_by_name("q") search_field.clear() # enter search keyword and submit search_field.send_keys("phones") search_field.submit() # get all the anchor elements which have product names displayed # currently on result page using find_elements_by_xpath method products = driver.find_elements_by_xpath("//h2[@class='product-name']/a") # get the number of anchor elements found print "Found " + str(len(products)) + " products:" # iterate through each anchor element and # print the text that is name of the product for product in products: print product.text # close the browser window driver.quit() |
執行結果和火狐的類似。
參考資料:
Chrome
ChromeDriver由Chromium開發,安裝方法和IE的類似,但是不需要設定Protected Mode。 例項1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#!/usr/bin/env python # encoding: utf-8 import time from selenium import webdriver # get the path of chromedriver chrome_driver_path = r"e:chromedriver.exe" #remove the .exe extension on linux or mac platform # create a new Chrome session driver = webdriver.Chrome(chrome_driver_path) driver.implicitly_wait(30) driver.maximize_window() # navigate to the application home page driver.get("http://automationtesting.sinaapp.com/") # get the search textbox search_field = driver.find_element_by_name("q") search_field.clear() # enter search keyword and submit search_field.send_keys("webdriver") search_field.submit() time.sleep(6) products = driver.find_elements_by_xpath("//a[@class='searchable']") # get the number of anchor elements found print "Found " + str(len(products)) + " pages:" # iterate through each anchor element and # print the text that is name of the product for product in products: print product.get_attribute('href') # close the browser window driver.quit() |
例項2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import os from selenium import webdriver # get the path of chromedriver chrome_driver_path = r"e:chromedriver.exe" #remove the .exe extension on linux or mac platform # create a new Chrome session driver = webdriver.Chrome(chrome_driver_path) driver.implicitly_wait(30) driver.maximize_window() # navigate to the application home page driver.get("http://demo.magentocommerce.com/") # get the search textbox search_field = driver.find_element_by_name("q") search_field.clear() # enter search keyword and submit search_field.send_keys("phones") search_field.submit() # get all the anchor elements which have product names displayed # currently on result page using find_elements_by_xpath method products = driver.find_elements_by_xpath("//h2[@class='product-name']/a") # get the number of anchor elements found print "Found " + str(len(products)) + " products:" # iterate through each anchor element and # print the text that is name of the product for product in products: print product.text # close the browser window driver.quit() |
參考資料:
在unittest中使用
unittest可以為webdriver增加setup、teardown、檢查應用狀態、報告測試結果、資料驅動等功能。主要內容如下:
- 什麼是unittest?
- 使用unittest來編寫webDriver測試
- 基於TestCase類實現測試
- 理解各種型別的assert方法
- 建立一組測試為TestSuite
- 使用unittest擴充套件生成HTML格式的測試報告
unittest庫
主要組成如下:
- Test Fixture:準備及清理工作。
- Test Case: 通常是使用assert方法檢查動作和輸入的響應,一般是基於TestCase類擴充。
- Test Suite:多個測試的集合。
- Test Runner:測試執行。
- Test Report:測試報告。
測試通常由3A組成:
- Arrange:預置條件、相關配置和依賴等。
- Act:實際功能。
- Assert:斷言。
其他框架有Pytest和Nose等。
TestCase類
測試方法以test_開頭
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import unittest from selenium import webdriver class SearchTests(unittest.TestCase): def setUp(self): # create a new Firefox session self.driver = webdriver.Firefox() self.driver.implicitly_wait(30) self.driver.maximize_window() # navigate to the application home page self.driver.get("http://demo.magentocommerce.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") self.assertEqual(2, len(products)) def test_search_by_name(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("salt shaker") 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") self.assertEqual(1, len(products)) def tearDown(self): # close the browser window self.driver.quit() if __name__ == '__main__': unittest.main(verbosity=2) |
執行結果:
1 2 3 4 5 6 7 |
# python searchtests.py test_search_by_category (__main__.SearchTests) ... ok test_search_by_name (__main__.SearchTests) ... ok ---------------------------------------------------------------------- Ran 2 tests in 138.375s OK |
基於類的setUp()和tearDown()方法
上面每個用例都會初始化和清理一次,有時這不一定是必要的。@classmethod支援在一個類中只進行一次初始化和清理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import unittest from selenium import webdriverclass SearchTests(unittest.TestCase): @classmethod def setUpClass(cls): # create a new Firefox session cls.driver = webdriver.Firefox() cls.driver.implicitly_wait(30) cls.driver.maximize_window() # navigate to the application home page cls.driver.get("http://demo.magentocommerce.com/") cls.driver.title 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") self.assertEqual(2, len(products)) def test_search_by_name(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("salt shaker") 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") self.assertEqual(1, len(products)) @classmethod def tearDownClass(cls): # close the browser window cls.driver.quit() if __name__ == '__main__': unittest.main(verbosity=2) |
斷言
斷言有3種型別:相等、邏輯比較、異常。如果斷言不通過,當前測試用例會停止,並報錯。詳細的斷言參見unittest。
另外fail()可以無條件讓用例失敗。
測試用例集(Test suites)
通過TestSuite, TestLoader和TestRunner可以有效地組織測試用例集。
先新增檔案homepagetests.py,演示上面部分斷言。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
import unittest from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By from __builtin__ import classmethod class HomePageTest(unittest.TestCase): @classmethod def setUp(cls): # create a new Firefox session """ cls.driver = webdriver.Firefox() cls.driver.implicitly_wait(30) cls.driver.maximize_window() # navigate to the application home page """ cls.driver.get('http://demo-store.seleniumacademy.com/') def test_search_field(self): # check search field exists on Home page self.assertTrue(self.is_element_present(By.NAME, 'q')) def test_language_option(self): # check language options dropdown on Home page self.assertTrue(self.is_element_present(By.ID, 'select-language')) def test_shopping_cart_empty_message(self): # check content of My Shopping Cart block on Home page shopping_cart_icon = self.driver. find_element_by_css_selector('div.header-minicart span.icon') shopping_cart_icon.click() shopping_cart_status = self.driver. find_element_by_css_selector('p.empty').text self.assertEqual('You have no items in your shopping cart.', shopping_cart_status) close_button = self.driver. find_element_by_css_selector('div.minicart-wrapper a.close') close_button.click() @classmethod def tearDown(cls): # close the browser window cls.driver.quit() def is_element_present(self, how, what): """ Utility method to check presence of an element on page :params how: By locator type :params what: locator value """ try: self.driver.find_element(by=how, value=what) except NoSuchElementException, e: return False return True if __name__ == '__main__': unittest.main(verbosity=2) |
再組合起來,見smoketests.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import unittest from searchtests import SearchTests from homepagetests import HomePageTest # get all tests from SearchProductTest and HomePageTest class search_tests = unittest.TestLoader().loadTestsFromTestCase(SearchTests) home_page_tests = unittest.TestLoader().loadTestsFromTestCase(HomePageTest) # create a test suite combining search_test and home_page_test smoke_tests = unittest.TestSuite([home_page_tests, search_tests]) # run the suite unittest.TextTestRunner(verbosity=2).run(smoke_tests) |
執行結果:
1 2 3 4 5 6 7 8 9 10 |
# python smoketests.py test_language_option (homepagetests.HomePageTest) ... ok test_search_field (homepagetests.HomePageTest) ... ok test_shopping_cart_empty_message (homepagetests.HomePageTest) ... ok test_search_by_category (searchtests.SearchTests) ... ok test_search_by_name (searchtests.SearchTests) ... ok ---------------------------------------------------------------------- Ran 5 tests in 223.231s OK |
生成HTML測試報告
外掛 HTMLTestRunner可以幫助生成HTML報告。見 smoketests_with_html_report.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import unittest import HTMLTestRunner import os from searchtests import SearchTests from homepagetests import HomePageTest # get the directory path to output report file result_dir = os.getcwd() # get all tests from SearchProductTest and HomePageTest class search_tests = unittest.TestLoader().loadTestsFromTestCase(SearchTests) home_page_tests = unittest.TestLoader().loadTestsFromTestCase(HomePageTest) # create a test suite combining search_test and home_page_test smoke_tests = unittest.TestSuite([home_page_tests, search_tests]) # open the report file outfile = open(result_dir + 'SmokeTestReport.html', 'w') # configure HTMLTestRunner options runner = HTMLTestRunner.HTMLTestRunner(stream=outfile, title='Test Report', description='Smoke Tests') # run the suite using HTMLTestRunner runner.run(smoke_tests) |
web通常包含了Hyper Text Markup Language (HTML)、Cascading Style Sheets (CSS)和JavaScript。本節主要內容如下:
- 瞭解更多Selenium webDriver查詢元素的知識
- 使用各種瀏覽器提供的開發工具找到和定位元素
- 多種發現元素的方法:ID、Name、類屬性值、XPath、CSS選擇器
- Selenium webDriver中的各種find_element_by方法。
一般的瀏覽器都有檢視原始碼的功能。
元素查詢
使用開發工具發現定位器
Firefox的外掛Firebug是個好幫手,可以F12或者右鍵點選元素選擇“Inspect Element with Firebug”開啟。Firefox的搜素框還可以對XPath或CSS進行查詢。
Chrome中可以F12或者右鍵點選元素選擇“Inspect Element”的方式檢視程式碼。查詢功能也和Firefox類似。Internet Explorer也有類似功能,不再贅述。
元素查詢
find_element_by*系列方法在找到元素的時候返回WebElement例項,否則產生NoSuchElementException異常。另外find_elements_by*系列方法可以一次返回多個元素。
driver.find_element_by_css_selector(‘#search’)
Method | Description | Argument | Example |
find_element_by_id(id) | This method finds an element by the ID attribute value | id: The ID of the element to be found | driver.find_element_by_id(‘search’) |
find_element_by_name(name) | This method finds an element by the name attribute value | name: The name of the element to be found | driver.find_element_by_name(‘q’) |
find_element_by_class_name(name) | This method finds an element by the class attribute value | name: The class name of the element to be found | driver.find_element_by_class_name(‘input-text’) |
find_element_by_tag_name(name) | This method finds an element by its tag name | name: The tag name of the element to be found | driver.find_element_by_tag_name(‘input’) |
find_element_by_xpath(xpath) | This method finds an element using XPath | xpath: The xpath of the element to be found | driver.find_element_by_xpath(‘form[0]/div[0]/input[0]’) |
find_element_by_css_selector(css_selector) | This method finds an element by the CSS selector | css_selector: The CSS selector of the element to be found | |
find_element_by_link_text(link_text) | This method finds an element by the link text | link_text: The text of the element to be found | driver.find_element_by_link_text(‘Log In’) |
find_element_by_partial_link_text(link_text) | This method finds an element by a partial match of its link text | link_text: The text to match part of the text of the element | driver.find_element_by_partial_link_text(‘Log’) |
通過id、name、類屬性是最建議,也是最快速的查詢方法,尤其是id和name。其次使用tag和連結文字,萬不得已才使用xpath和css。
XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文件中某部分位置的語言。參考:XPath維基百科介紹 以及 w3schools的Xpath介紹,zvon的XPath 1.0介紹。參考書籍:Selenium Testing Tools Cookbook。注意XPath的速度會比CSS還慢,不過支援向前向後定義和相對路徑。
層疊樣式表(英語:Cascading Style Sheets,簡寫CSS),又稱串樣式列表、層次結構式樣式表檔案,一種用來為結構化文件(如HTML文件或XML應用)新增樣式(字型、間距和顏色等)的計算機語言。參考CSS維基百科介紹,w3schools之CSS介紹 和
例項
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import unittest from selenium import webdriver class HomePageTest(unittest.TestCase): @classmethod def setUpClass(cls): # create a new Firefox session cls.driver = webdriver.Firefox() cls.driver.implicitly_wait(30) cls.driver.maximize_window() # navigate to the application home page cls.driver.get('http://demo-store.seleniumacademy.com/') def test_search_text_field_max_length(self): # get the search textbox search_field = self.driver.find_element_by_id('search') # check maxlength attribute is set to 128 self.assertEqual('128', search_field.get_attribute('maxlength')) def test_search_button_enabled(self): # get Search button search_button = self.driver.find_element_by_class_name('button') # check Search button is enabled self.assertTrue(search_button.is_enabled()) def test_my_account_link_is_displayed(self): # get the Account link account_link = self.driver.find_element_by_link_text('ACCOUNT') # check My Account link is displayed/visible in the Home page footer self.assertTrue(account_link.is_displayed()) def test_account_links(self): # get the all the links with Account text in it account_links = self.driver. find_elements_by_partial_link_text('ACCOUNT') # check Account and My Account link is displayed/visible in the Home page footer self.assertTrue(len(account_links), 2) def test_count_of_promo_banners_images(self): # get promo banner list banner_list = self.driver.find_element_by_class_name('promos') # get images from the banner_list banners = banner_list.find_elements_by_tag_name('img') # check there are 3 banners displayed on the page self.assertEqual(3, len(banners)) def test_vip_promo(self): # get vip promo image vip_promo = self.driver. find_element_by_xpath("//img[@alt='Shop Private Sales - Members Only']") # check vip promo logo is displayed on home page self.assertTrue(vip_promo.is_displayed()) # click on vip promo images to open the page vip_promo.click() # check page title self.assertEqual("VIP", self.driver.title) def test_shopping_cart_status(self): # check content of My Shopping Cart block on Home page # get the Shopping cart icon and click to open the Shopping Cart section shopping_cart_icon = self.driver. find_element_by_css_selector('div.header-minicart span.icon') shopping_cart_icon.click() # get the shopping cart status shopping_cart_status = self.driver. find_element_by_css_selector('p.empty').text self.assertEqual('You have no items in your shopping cart.', shopping_cart_status) # close the shopping cart section close_button = self.driver. find_element_by_css_selector('div.minicart-wrapper a.close') close_button.click() @classmethod def tearDownClass(cls): # close the browser window cls.driver.quit() if __name__ == '__main__': unittest.main(verbosity=2) |
執行結果:
1 2 3 4 5 6 7 8 9 10 11 12 |
# python homepagetest.py test_account_links (__main__.HomePageTest) ... ok test_count_of_promo_banners_images (__main__.HomePageTest) ... ok test_my_account_link_is_displayed (__main__.HomePageTest) ... ok test_search_button_enabled (__main__.HomePageTest) ... ok test_search_text_field_max_length (__main__.HomePageTest) ... ok test_shopping_cart_status (__main__.HomePageTest) ... ok test_vip_promo (__main__.HomePageTest) ... ok ---------------------------------------------------------------------- Ran 7 tests in 77.086s OK |
元素互動
本節主要內容如下:
- 瞭解更多關於WebDriver和WebElement類的知識
- 使用webdriver和WebElement類方法和屬性實現測試與應用互動
- 使用Select類自動化下拉選單和列表的操作
- 自動化的JavaScript彈窗和瀏覽器操作。
HTML表單的元素
1 2 3 4 5 6 7 8 9 10 11 12 |
HTML --HEAD TITLE --BODY ----FORM ----INPUT: Text,Password, Submit, Checkbox, Radio, FileEA ----TEXTAREA ----SELECT OPTION ----TABLE: THEAD,TBODY,TR(Rows),TD(columns/cells) ----DIV ----P(Paragraph) ----Headings(H1,H2...) ----A(Anchor) |
webDriver類
webDriver類主要用於和瀏覽器互動,完整的屬性和方法參見:selenium.webdriver.remote.webelement
屬性列表:
Property/attribute | Description | Example |
current_url | This gets the URL of the current page displayed in the browser | driver.current_url |
current_window_handle | This gets the handle of the current window | driver.current_window_handle |
name | This gets the name of the underlying browser for this instance | driver.name |
orientation | This gets the current orientation of the device | driver.orientation |
page_source | This gets the source of the current page | driver.page_source |
title | This gets the title of the current page | driver.title |
window_handles | This gets the handles of all windows within the current session | driver.window_handles |
方法列表:
Method | Description | Argument | Example |
back() | This goes one step backward in the browser history in the current session. | driver.back() | |
close() | This closes the current browser window. | driver.close() | |
forward() | This goes one step forward in the browser history in the current session. | driver.forward() | |
get(url) | This navigates and loads a web page in the current browser session. | url is the address of the website or web page to navigate | driver.get(“http://www.google.com”) |
maximize_window() | This maximizes the current browser window. | driver.maximize_window() | |
quit() | This quits the driver and closes all the associated windows. | driver.quit() | |
refresh() | This refreshes the current page displayed in the browser. | driver.refresh() | |
switch_to.active_element() | This returns the element with focus or the body if nothing else has focus. | driver.switch_to_active_element() | |
Switch.to_alert() | This switches the focus to an alert on the page. | driver.switch_to_alert() | |
switch_to.default_content() | This switches the focus to the default frame. | driver.switch_to_default_content() | |
switch_to.frame(frame_reference) | This switches the focus to the specified frame, by index, name, or web element. This method also works on IFRAMES. | frame_reference: This is the name of the window to switch to, an integer representing the index, or a web element that is a frame to switch to | driver.switch_to_frame(‘frame_name’) |
switch_to.window(window_name) | This switches focus to the specified window. | window_name is the name or window handle of the window to switch to. | driver.switch_to_window(‘main’) |
implicitly_wait(time_to_wait) | This sets a sticky timeout to implicitly wait for an element to be found, or a command to complete. This method only needs to be called one time per session. To set the timeout for calls to execute_async_script, see set_script_timeout. | time_to_wait is the amount of time to wait(in seconds). | |
set_page_load_timeout(time_to_wait) | This sets the amount of time to wait for a page load to complete. | time_to_wait is the amount of time to wait(in seconds) | driver.set_page_load_timeout(30) |
set_script_timeout(time_to_wait) | This sets the amount of time that the script should wait during an execute_async_script call before throwing an error. | time_to_wait is the amount of time to wait(in seconds) | driver.set_script_timeout(30) |
WebElement類
WebElement類主要用於和元素互動,完整的屬性和方法參見:elenium.webdriver.remote.webelement
屬性列表:
Property/attribute | Description | Example |
size | This gets the size of the element | element.size |
tag_name | This gets this element’ s HTML tag name | element.tag_name |
text | This gets the text of the element | element.text |
方法列表:
Method | Description | Argument | Example |
clear() | This clears the content of the textbox or text area element. | element.clear() | |
click() | This clicks the element. | element.click() | |
get_attribute(name) | This gets the attribute value from the element. | name is the name of the attribute. | element.get_attribute(“value”) Or element.get_attribute(“maxlength”) |
is_displayed() | This checks whether the element is visible to the user. | element.is_displayed() | |
is_enabled() | This checks whether the element is enabled. | element.is_enabled() | |
is_selected() | This checks whether the element is selected. This method is used to check the selection of a radio button or checkbox. | element.is_selected() | |
send_keys(*value) | This simulates typing into the element. | Value is a string for typing or setting form fields. | element.send_keys(“foo”) |
submit() | This submits a form. If you call this method on an element, it will submit the parent form. | element.submit() | |
value_of_css_property(property_name) | This gets the value of a CSS property. | property_name is the name of the CSS property. | element.value_of_css_property(“backgroundcolor”) |
處理form、textbox、checkbox和radio
下面的homepagetests建立一個使用者,演示了form、textbox、checkbox和radio等操作。
register_new_user.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
from selenium import webdriver from time import gmtime, strftime import unittest class RegisterNewUser(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(30) self.driver.maximize_window() # navigate to the application home page self.driver.get('http://demo-store.seleniumacademy.com/') def test_register_new_user(self): driver = self.driver # click on Log In link to open Login page driver.find_element_by_link_text('ACCOUNT').click() driver.find_element_by_link_text('My Account').click() # get the Create Account button create_account_button = driver.find_element_by_link_text('CREATE AN ACCOUNT') # check Create Account button is displayed and enabled self.assertTrue(create_account_button.is_displayed() and create_account_button.is_enabled()) # click on Create Account button. This will displayed new account create_account_button.click() # check title self.assertEquals('Create New Customer Account', driver.title) # get all the fields from Create an Account form first_name = driver.find_element_by_id('firstname') last_name = driver.find_element_by_id('lastname') email_address = driver.find_element_by_id('email_address') password = driver.find_element_by_id('password') confirm_password = driver.find_element_by_id('confirmation') news_letter_subscription = driver.find_element_by_id('is_subscribed') submit_button = driver. find_element_by_xpath("//button[@title='Register']") # check maxlength of first name and last name textbox self.assertEqual('255', first_name.get_attribute('maxlength')) self.assertEqual('255', last_name.get_attribute('maxlength')) # check all fields are enabled self.assertTrue(first_name.is_enabled() and last_name.is_enabled() and email_address.is_enabled() and news_letter_subscription.is_enabled() and password.is_enabled() and confirm_password.is_enabled() and submit_button.is_enabled()) # check Sign Up for Newsletter is unchecked self.assertFalse(news_letter_subscription.is_selected()) user_name = 'user_' + strftime('%Y%m%d%H%M%S', gmtime()) # fill out all the fields first_name.send_keys('Test') last_name.send_keys(user_name) news_letter_subscription.click() email_address.send_keys(user_name + '@example.com') password.send_keys('tester') confirm_password.send_keys('tester') # click Submit button to submit the form submit_button.click() # check new user is registered self.assertEqual('Hello, Test ' + user_name + '!', driver.find_element_by_css_selector('p.hello > strong').text) driver.find_element_by_link_text('ACCOUNT').click() self.assertTrue(driver.find_element_by_link_text('Log Out').is_displayed()) def tearDown(self): self.driver.quit() if __name__ == '__main__': unittest.main(verbosity=2) |
執行結果:
1 2 3 4 5 |
test_register_new_user (__main__.RegisterNewUser) ... ok ---------------------------------------------------------------------- Ran 1 test in 133.117s OK |
處理dropdown和list
屬性列表:
Property/attribute | Description | Example |
all_selected_options | This gets a list of all the selected options belonging to the dropdown or list | select_element.all_selected_options |
first_selected_option | This gets the first selected/currently selected option from the dropdown or list | select_element.first_selected_option |
options | This gets a list of all options from the dropdown or list | select_element.options |
方法列表:
Method | Description | Argument | Example |
deselect_() | This clears all the selected entries from a multiselect dropdown or list | select_element.deselect_() | |
deselect_by_index(index) | This deselects the option at the given index from the dropdown or list | index is the index of the option to be deselected | deselect_element.deselect_by_index(1) |
deselect_by_value(value) | This deselects all options that have a value matching the argument from the dropdown or list | value is the value attribute of the option to be deselected | select_element.deselect_by_value(“foo”) |
deselect_by_visible_text(text) | This deselects all the options that display text matching the argument from the dropdown or list | text is the text value of the option to be deselected | select_element.deselect_by_visible_text(“bar”) |
select_by_index(index) | This selects an option at the given index from the dropdown or list | index is the index of the option to be selected | select_element.select_by_index(1) |
select_by_value(value) | This selects all the options that have a value matching the argument from the dropdown or list | value is the value attribute of the option to be selected | select_element.select_by_value(“foo”) |
select_by_visible_text(text) | This selects all the options that display the text matching the argument from the dropdown or list | text is the text value of the option to be selected | select_element.select_by_visible_text(“bar”) |
程式碼檔案:homepagetests.py。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
from Tkinter import image_names import unittest from selenium import webdriver from selenium.webdriver.support.ui import Select class HomePageTest(unittest.TestCase): @classmethod def setUpClass(cls): # create a new Firefox session cls.driver = webdriver.Firefox() cls.driver.implicitly_wait(30) cls.driver.maximize_window() # navigate to the application home page cls.driver.get('http://demo-store.seleniumacademy.com/') def test_search_text_field_max_length(self): # get the search textbox search_field = self.driver.find_element_by_id('search') # check maxlength attribute is set to 128 self.assertEqual('128', search_field.get_attribute('maxlength')) def test_search_button_enabled(self): # get Search button search_button = self.driver.find_element_by_class_name('button') # check Search button is enabled self.assertTrue(search_button.is_enabled()) def test_my_account_link_is_displayed(self): # get the Account link account_link = self.driver.find_element_by_link_text('ACCOUNT') # check My Account link is displayed/visible in the Home page footer self.assertTrue(account_link.is_displayed()) def test_account_links(self): # get the all the links with Account text in it account_links = self.driver. find_elements_by_partial_link_text('ACCOUNT') # check Account and My Account link is # displayed/visible in the Home page footer self.assertEqual(2, len(account_links)) def test_count_of_promo_banners_images(self): # get promo banner list banner_list = self.driver.find_element_by_class_name('promos') # get images from the banner_list banners = banner_list.find_elements_by_tag_name('img') # check there are 3 banners displayed on the page self.assertEqual(3, len(banners), 3) def test_vip_promo(self): # get vip promo image vip_promo = self.driver. find_element_by_xpath("//img[@alt='Shop Private Sales - Members Only']") # check vip promo logo is displayed on home page self.assertTrue(vip_promo.is_displayed()) # click on vip promo images to open the page vip_promo.click() # check page title self.assertEqual('VIP', self.driver.title) self.driver.back() def test_shopping_cart_status(self): # check content of My Shopping Cart block on Home page # get the Shopping cart icon and click to open the # Shopping Cart section shopping_cart_icon = self.driver. find_element_by_css_selector('div.header-minicart span.icon') shopping_cart_icon.click() # get the shopping cart status shopping_cart_status = self.driver. find_element_by_css_selector('p.empty').text self.assertEqual('You have no items in your shopping cart.', shopping_cart_status) # close the shopping cart section close_button = self.driver. find_element_by_css_selector('div.minicart-wrapper a.close') close_button.click() def test_language_options(self): # list of expected values in Language dropdown exp_options = ["ENGLISH", "FRENCH", "GERMAN"] # empty list for capturing actual options displayed in the dropdown act_options = [] # get the Your language dropdown as instance of Select class select_language = Select(self.driver.find_element_by_id("select-language")) # check number of options in dropdown self.assertEqual(3, len(select_language.options)) # get options in a list for option in select_language.options: act_options.append(option.text) # check expected options list with actual options list self.assertListEqual(exp_options, act_options) # check default selected option is English self.assertEqual("ENGLISH", select_language.first_selected_option.text) # select an option using select_by_visible text select_language.select_by_visible_text("German") # check store is now German self.assertTrue("store=german" in self.driver.current_url) # changing language will refresh the page, # we need to get find language dropdown once again select_language = Select(self.driver.find_element_by_id("select-language")) select_language.select_by_index(0) def test_store_cookie(self): select_language = Select(self.driver.find_element_by_id("select-language")) select_language.select_by_visible_text("French") self.assertEqual("french", self.driver.get_cookie("store")["value"]) # changing language will refresh the page, # we need to get find language dropdown once again select_language = Select(self.driver.find_element_by_id("select-language")) select_language.select_by_index(0) def test_css_for_home_page(self): self.assertTrue("demo-logo.png" in self.driver.find_element_by_css_selector("div.notice-inner") .value_of_css_property("background-image")) @classmethod def tearDownClass(cls): # close the browser window cls.driver.quit() if __name__ == '__main__': unittest.main(verbosity=2) |
處理告警和彈出視窗
完整的參考地址:selenium.webdriver.common.alert
屬性列表:
Property/attribute | Description | Example |
text | This gets text from the alert window | alert.text |
方法列表:
Method | Description | Argument | Example |
accept() | This will accept the JavaScript? alert.box that is click on the OK button | alert.accept() | |
dismiss() | This will dismiss the JavaScript? | alert.box that is click on the Cancel button | alert.dismiss() |
send_keys(*value) | This simulates typing into the element value is a string for typing or setting form fields | alert.send_keys(“foo”) |
例項中先加入商品,然後清空商品,此時會有彈出告警。注意此處的程式碼在網速較慢時,彈出視窗可能無法識別,解決方法參見下一章。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
from selenium import webdriver import unittest class CompareProducts(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.implicitly_wait(30) 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() # click on Remove this item link, # this will display an alert to the user self.driver.find_element_by_link_text('Clear All').click() # switch to the alert alert = self.driver.switch_to.alert # 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) |
自動化瀏覽器瀏覽
Method | Description | Argument | Example |
back() | This goes one step backward in the browser history in the current session. | None | driver.back() |
forward() | This goes one step forward in the browser history in the current session. | None | driver.forward() |
refresh() | This refreshes the current page displayed in the browser. | None | driver.refresh() |
例項: navigation_test.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import unittest from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions class NavigationTest(unittest.TestCase): def setUp(self): # create a new Firefox session self.driver = webdriver.Chrome() self.driver.implicitly_wait(30) self.driver.maximize_window() # navigate to the application home page self.driver.get('http://www.google.com') def test_browser_navigation(self): driver = self.driver # get the search textbox search_field = driver.find_element_by_name('q') search_field.clear() # enter search keyword and submit search_field.send_keys('selenium webdriver') search_field.submit() se_wd_link = driver. find_element_by_link_text('Selenium WebDriver') se_wd_link.click() self.assertEqual('Selenium WebDriver', driver.title) driver.back() self.assertTrue(WebDriverWait(self.driver, 10) .until(expected_conditions.title_is('selenium webdriver - Google Search'))) driver.forward() self.assertTrue(WebDriverWait(self.driver, 10) .until(expected_conditions.title_is('Selenium WebDriver'))) driver.refresh() self.assertTrue(WebDriverWait(self.driver, 10) .until(expected_conditions.title_is('Selenium WebDriver'))) def tearDown(self): # close the browser window self.driver.quit() if __name__ == '__main__': unittest.main(verbosity=2) |
上面用例,因為google被和諧,通常無法執行,僅供參考。
同步
webdriver支援顯式和隱式的同步。本節主要內容如下:
- 顯式和隱式等待
- 何時使用顯式和隱式的等待
- 使用預期條件
- 建立自定義的等待狀態
使用隱式等待
隱式等待提供了通用的方法同步測試和步驟。適用於網路響應時間不一致或者使用Ajax呼叫渲染元素的時候。
隱式等待的預設超時時間是0,對整個webdriver生效。這個功能我們在第2章就有使用,現在我們把當時例項的隱式等待時間從30秒改成10秒。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
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 of WebElements? 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 the WebElement? 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
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) |
參考資料
- Dr . Philip Polstra 介紹 部落格
- Walt Stoneburner: wls#wwco.com Walt.Stoneburner#gmail.com 部落格
- 維基百科Selenium英文介紹