相关文章推荐
俊秀的海龟  ·  Selenium 函式庫 - Python ...·  4 月前    · 
酒量小的领带  ·  JavaScript ...·  2 年前    · 
纯真的围巾  ·  Mockito不能mock ...·  2 年前    · 
深情的大蒜  ·  Go 简单而强大的Reverse ...·  3 年前    · 
无邪的夕阳  ·  jquery sweet alert ...·  3 年前    · 
·  阅读

在这个系列的教程中,笔者将根据自己在多年的Selenium自动化测试开发过程中的实战经验,为各位朋友进行梳理和总结,提供一个实战性很强的教程。同时也欢迎各位朋友指出教程的不足之处,一起学习,一起进步。 话不多说,直接进入教程的第一个板块:浏览器操作。

浏览器的操作可以说是使用Selenium进行自动化开发中最基础的内容之一,任何用例的执行都离不开浏览器的操作,因为Selenium的原理就是通过代码实现对浏览器的控制和操作,从而达到模拟人在浏览器上执行测试用例的目的。

1.打开和关闭浏览器

打开浏览器

任何的一个测试用例,都需要打开一个浏览器的实体,然后才能进行下面的操作。需要注意的是需要提前安装好对应浏览器的Webdriver。

require 'selenium-webdriver'
# chrome
dr = Selenium::WebDriver.for :chrome
# firefox
dr = Selenium::WebDriver.for :ff
dr = Selenium::WebDriver.for :ie
复制代码

Headless mode

在一些场景下测试工程师需要在不打开浏览器的情况下进行自动化测试,也就是以headless的方式运行自动化测试。 现在全球最受欢迎的浏览器Chrome在Chrome 59 (Chrome 60 for Windows)版本中已经支持了headless mode,只需要配置一些简单的参数就可以实现。

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 '浏览器已经关闭'
复制代码

两种方式的区别:

dr.set_window_size( 240 , 320 )

通过设置不同的窗口大小,可以在浏览器上模拟不同场景的页面展示,例如设置一个移动端的分辨率,就可以看到在移动端的页面展示是否符合期望。

3.打开URL

Selenium中有两种打开URL的方法:

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
复制代码

这两种方法的区别在于:

dr.get url puts "The Title of current page is #{dr.title} " puts "url of current page is #{dr.current_url} " dr.quit 复制代码

5.前进,后退和刷新

dr.navigate 返回的 Selenium::WebDriver::Navigation 类的对象除了可以进行前面提到的 to 操作外,还可以进行前进,后退和刷新。

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'
复制代码

6.设置等待

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? }
    复制代码

    7.切换窗口

    在测试过程中有可能会有新窗口打开,这样就会有多个窗口同时出现,Selenium提供了方法实现多个窗口间的切换。

    window_handleSelenium::WebDriver::Driver类的方法,返回当前window的handle。

    window_handlesSelenium::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}"
    复制代码

    8.执行JavaScript

    在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)
    begin
        $driver = Selenium::WebDriver.for :firefox
        $driver.get 'https://www.jianshu.com'
        highlight $driver.find_element(xpath: "//a[@class='logo']")
    ensure
        $driver.quit
    复制代码

    利用JS还可以实现很多复杂的功能,笔者将会在后续的教程中专门介绍。

    9.处理Cookie

    对于Web UI的自动化测试,对于Cookie的处理是比较常见的场景。 Selenium提供了完善的接口让开发者来对cookie进行处理。

  • 获取Cookie:获取全部cookieall_cookies和获取指定cookie cookie(name)
  • 添加Cookie:add_cookie(name: 'token', value: 'xxxxxx')
  • 删除Cookie:删除全部cookie 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()
    复制代码

    10.设置代理

    在进行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
          安装掘金浏览器插件