在這個系列的教程中,筆者將根據本身在多年的Selenium自動化測試開發過程當中的實戰經驗,爲各位朋友進行梳理和總結,提供一個實戰性很強的教程。同時也歡迎各位朋友指出教程的不足之處,一塊兒學習,一塊兒進步。
話很少說,直接進入教程的第一個板塊:瀏覽器操做。css
瀏覽器的操做能夠說是使用Selenium進行自動化開發中最基礎的內容之一,任何用例的執行都離不開瀏覽器的操做,由於Selenium的原理就是經過代碼實現對瀏覽器的控制和操做,從而達到模擬人在瀏覽器上執行測試用例的目的。
本教程以Ruby做爲開發語言。web
任何的一個測試用例,都須要打開一個瀏覽器的實體,而後才能進行下面的操做。須要注意的是須要提早安裝好對應瀏覽器的Webdriver。chrome
require 'selenium-webdriver' # chrome dr = Selenium::WebDriver.for :chrome # firefox dr = Selenium::WebDriver.for :ff # ie dr = Selenium::WebDriver.for :ie
在一些場景下測試工程師須要在不打開瀏覽器的狀況下進行自動化測試,也就是以headless的方式運行自動化測試。
如今全球最受歡迎的瀏覽器Chrome在Chrome 59 (Chrome 60 for Windows)版本中已經支持了headless mode,只須要配置一些簡單的參數就能夠實現。windows
require 'selenium-webdriver' options = Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless') options.add_argument('--disable-gpu') options.add_argument('--remote-debugging-port=9222') driver = Selenium::WebDriver.for :chrome, options: options driver.get "https://www.acitve.com" driver.save_screenshot("#{File.dirname(__FILE__)}/#{Time.now.strftime("%F")}")
執行完操做後,必須保證瀏覽器被關閉。
關閉瀏覽器有兩種方法:數組
close()
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome sleep 5 puts '瀏覽器將被關閉' dr.close() puts '瀏覽器已經關閉'
quit()
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome sleep 5 puts '瀏覽器將被關閉' dr.quit() puts '瀏覽器已經關閉'
方法 | 區別 |
---|---|
close | 關閉當前的瀏覽器窗口 |
quit | 不只關閉窗口,還會完全的退出webdriver,釋放與driver server之間的鏈接 |
在執行用例的過程當中,可能會須要對窗口的大小進行調整,以知足測試的要求,由於頁面的佈局在不一樣的瀏覽器窗口大小下會有不一樣的展現。
經常使用的設置主要是:瀏覽器
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome dr.maximize_window()
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome dr.set_window_size(240, 320)
經過設置不一樣的窗口大小,能夠在瀏覽器上模擬不一樣場景的頁面展現,例如設置一個移動端的分辨率,就能夠看到在移動端的頁面展現是否符合指望。
Selenium中有兩種打開URL的方法:ruby
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome url = 'http://www.acitve.com' puts "now access #{url}" #方法1: dr.get url #方法2: dr.navigate.to url
這兩種方法的區別在於:cookie
方法 | 區別1 | 區別2 |
---|---|---|
get |
等待page load完成 | 沒法進行前進後退操做 |
navigate.to |
不會等待page load完成 | 能夠保留瀏覽的歷史,進行前進後退刷新操做 |
在驗證當前頁面的標題和URL時時,會須要用到這個功能app
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome url = 'http://www.acitve.com' dr.get url puts "The Title of current page is #{dr.title}" puts "url of current page is #{dr.current_url}" dr.quit
dr.navigate
返回的Selenium::WebDriver::Navigation
類的對象除了能夠進行前面提到的to
操做外,還能夠進行前進,後退和刷新。less
require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome url1 = 'http://www.acitve.com' dr.navigate.to url url2 = 'http://www.acitve.com/contactus' dr.navigate.to url puts "url of current page is #{dr.current_url}" #'http://www.acitve.com/contactus' #返回 dr.navigate.back() puts "url of current page is #{dr.current_url}" #'http://www.acitve.com' #前進 dr.navigate.forward() puts "url of current page is #{dr.current_url}" #'http://www.acitve.com/contactus' #刷新 dr.navigate.refresh() puts "url of current page is #{dr.current_url}" #'http://www.acitve.com/contactus'
Selenium中有兩種等待:隱式等待和顯式等待。
NoSuchElement
異常。# 若是3s內還定位不到則拋出異常 driver.manage.timeouts.implicit_wait = 3 # seconds
Selenium::WebDriver::Wait
對象,設置一個等待的條件,條件成立時繼續執行,超過timeout則拋出異常。wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds wait.until { dr.find_element(class: 'label').displayed? }
在測試過程當中有可能會有新窗口打開,這樣就會有多個窗口同時出現,Selenium提供了方法實現多個窗口間的切換。
window_handle
是Selenium::WebDriver::Driver
類的方法,返回當前window的handle。window_handles
是Selenium::WebDriver::Driver
類的方法,返回所有window的handle數組。switch_to.window(window_handle)
實現跳轉到指定window_handle的窗口require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome dr.get 'http://the-internet.herokuapp.com/windows' dr.find_element(css: '.example a').click windows_array = dr.window_handles puts "All windows are #{windows_array}" dr.switch_to.window(windows_array.first) puts "Current window is #{dr.window_handle}" dr.switch_to.window(@driver.window_handles.last) puts "Current window is #{dr.window_handle}"
在Selenium自動化測試的開發過程當中,不少複雜的控制功能是原生API沒法提供或解決的,這就須要用到執行JavaScript來幫助實現。Selenium也提供了接口讓開發者在腳本中執行JS腳本。
下面的例子,將演示如何利用JS來實現操做元素的高亮顯示。
# coding: utf-8 require 'selenium-webdriver' def highlight(element, duration = 3) # 保留元素原有的style,以待方法執行完成後恢復 original_style = element.attribute("style") # 給元素加一個紅色的虛線邊界 $driver.execute_script( "arguments[0].setAttribute(arguments[1], arguments[2])", element, "style", "border: 2px solid red; border-style: dashed;") # 讓元素的邊界保留一段時間再恢復 if duration > 0 sleep duration $driver.execute_script( "arguments[0].setAttribute(arguments[1], arguments[2])", element, "style", original_style) end end begin $driver = Selenium::WebDriver.for :firefox $driver.get 'https://www.jianshu.com' highlight $driver.find_element(xpath: "//a[@class='logo']") ensure $driver.quit end
利用JS還能夠實現不少複雜的功能,筆者將會在後續的教程中專門介紹。
對於Web UI的自動化測試,對於Cookie的處理是比較常見的場景。
Selenium提供了完善的接口讓開發者來對cookie進行處理。
all_cookies
和獲取指定cookie cookie(name)
add_cookie(name: 'token', value: 'xxxxxx')
delete_all_cookies
和 刪除指定cookiedelete_cookie(name)
#encoding: utf-8 require 'selenium-webdriver' dr = Selenium::WebDriver.for :chrome url = 'http://www.acitve.com' dr.get url dr.manage.all_cookies dr.manage.delete_all_cookies #經過添加鑑權所需的cookie,能夠完成登陸的效果 dr.manage.add_cookie(name: 'userid', value: 'xxxxxx') dr.manage.add_cookie(name: 'token', value: 'xxxxxx') dr.get url #刪除一個鑑權須要的cookie後,登陸將失效 dr.manage.delete_cookie('token') dr.get url dr.quit()
在進行UI自動化的過程當中,使用代理訪問頁面的場景也是比較常見的,在Selenium中,給瀏覽器設置代理主要是經過對profile的設置實現的。
require 'selenium-webdriver' PROXY = 'localhost:8087' profile = Selenium::WebDriver::Firefox::Profile.new profile.proxy = Selenium::WebDriver::Proxy.new( :http => PROXY, :ftp => PROXY, :ssl => PROXY) driver = Selenium::WebDriver.for :firefox, :profile => profile