如何使用selenium-webdriver (ruby)进行自动化测试时使用同一个浏览器窗口?

问题描述 投票:2回答:3

我正在使用selenium-webdriver和cucumber在ruby中为一个网站进行自动化测试。我需要每个功能以特定的顺序运行,并使用相同的浏览器窗口。目前,每个功能都会创建一个新的窗口来运行测试。尽管在一些测试案例中,这种行为是需要的,但在很多情况下却不是。从我目前的研究来看,关于是否可以在整个测试用例中使用同一个浏览器窗口的问题,似乎答案不一。我所遇到的大多数答案都是针对其他语言的,而且是针对浏览器的变通方法(我是在测试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.compseleniumissuesdetail?id=18。有什么办法可以将已经运行的浏览器附加到java中的selenium webdriver上?

如果我的问题有不清楚的地方,请向我提问。我还有很多测试要创建,但如果我的基础是马虎的,缺少要求的功能,我不想继续创建测试。(如果你发现我的代码中有任何其他问题,请在评论中指出)

ruby selenium cucumber selenium-webdriver automated-tests
3个回答
9
投票

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

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

注意:虽然在各个测试中重复使用浏览器通常是可以的。你应该小心那些需要以特定顺序运行的测试(即成为依赖性测试)。依赖性测试可能很难调试和维护。


2
投票

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

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. 两者都是有用的,这取决于情况。


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个救援工作之间的工作,将在未来更新,当我使它为我自己的用例工作。

© www.soinside.com 2019 - 2024. All rights reserved.