在这个系列的教程中,笔者将根据本身在多年的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