如何使用selenium-webdriver(ruby)使用相同的浏览器窗口进行自动测试?

时间:2013-07-12 20:41:39

标签: ruby selenium cucumber selenium-webdriver automated-tests

我使用selenium-webdriver和ruby中的黄瓜自动化网站的测试用例。我需要每个功能以特定顺序运行并使用相同的浏览器窗口。 Atm的每个功能都会创建一个新的窗口来运行测试。虽然在某些测试用例中需要这种行为 - 但在许多情况下并非如此。从我到目前为止的研究来看,似乎有关于在整个测试案例中是否可以用硒驱动相同浏览器窗口的混合答案。我遇到的大多数答案都是针对其他语言的,并且是针对浏览器特定的解决方法(我在测试IE时开发我的测试,但预计会在其他浏览器中运行这些测试)。我在Ruby工作,从我所看到的,似乎我必须为该页面创建一个类?我很困惑为什么要这样做或者这有什么帮助。

我的env.rb文件:

require 'selenium-webdriver'
require 'rubygems'
require 'nokogiri'
require 'rspec/expectations'

Before do

    @driver ||= Selenium::WebDriver.for :ie
    @accept_next_alert = true
    @driver.manage.timeouts.implicit_wait = 30
    @driver.manage.timeouts.script_timeout = 30
    @verification_errors = []
  end

  After do
    #@driver.quit
    #@verification_errors.should == []
  end

到目前为止,我收集了一些有类似问题的人的信息: https://code.google.com/p/selenium/issues/detail?id=18 Is there any way to attach an already running browser to selenium webdriver in java?

如果我的问题不明确,请问我问题。我有更多的测试要创建,但如果我的基础很草率并且缺少所请求的功能,我不想继续创建测试。 (如果您发现我的代码中存在任何其他问题,请在评论中指出它们)

3 个答案:

答案 0 :(得分:5)

在每个场景之前运行Before挂钩。这就是每次打开新浏览器的原因。

执行以下操作(在env.rb中):

require "selenium-webdriver"

driver = Selenium::WebDriver.for :ie
accept_next_alert = true
driver.manage.timeouts.implicit_wait = 30
driver.manage.timeouts.script_timeout = 30
verification_errors = []

Before do
  @driver = driver
end

at_exit do
  driver.close
end

在这种情况下,浏览器将在开始时(在任何测试之前)打开。然后每个测试都会抓取该浏览器并继续使用它。

注意:虽然通常可以在测试中重复使用浏览器。您应该注意需要按特定顺序运行的测试(即变得依赖)。相关测试很难调试和维护。

答案 1 :(得分:1)

我在创建spec_helper文件时遇到了类似的问题。我为我的目的做了以下(为本地运行的firefox简化),它非常非常可靠地工作。 RSpec将对_spec.rb文件中的所有it块使用相同的浏览器窗口。

Rspec.configure do |config|
  config.before(:all) do
    @driver = Selenium::WebDriver.for :firefox
  end

  config.after(:all) do
    @driver.quit
  end
end

如果切换到:each而不是:all,则可以为每个断言块使用单独的浏览器实例...再次使用:each RSpec将为新的浏览器实例提供每个it。两者都有用,具体取决于具体情况。

答案 2 :(得分:0)

答案可以解决问题,但不要回答“如何连接到现有会话”问题。

我设法用下面的代码来做到这一点,因为它不受官方支持。

# monkey-patch 2 methods
module Selenium
  module WebDriver
    class Driver
      # Be able to set the driver
      def set_bridge_to(b)
        @bridge = b
      end

      # bridge is a private method, simply create a public version
      def public_bridge
        @bridge
      end
    end
  end
end


caps = Selenium::WebDriver::Remote::Capabilities.send("chrome")

driver = Selenium::WebDriver.for(
  :remote,
  url: "http://chrome:4444/wd/hub",
  desired_capabilities: caps
)
used_bridge = driver.bridge
driver.get('https://www.google.com')

# opens a new unused chrome window
driver2 = Selenium::WebDriver.for(
  :remote,
  url: "http://chrome:4444/wd/hub",
  desired_capabilities: caps
)

driver2.close() # close unused chrome window
driver2.set_bridge_to(used_bridge)

driver2.title # => "Google"

不幸的是,这没有在2个救援工作之间进行测试,将来会在我将其用于自己的用例时对其进行更新。