【问题标题】:Selenium RC: Run tests in multiple browsers automaticallySelenium RC:自动在多个浏览器中运行测试
【发布时间】:2010-09-17 19:48:21
【问题描述】:

所以,我开始创建一些 Ruby 单元测试,使用 Selenium RC 直接在浏览器中测试我的网络应用程序。我将Selenum-Client 用于红宝石。我为所有其他 selenium 测试创建了一个基类来继承。

这会创建许多 SeleniumDriver 实例,并且在每个实例上调用所有缺少的方法。这实质上是并行运行测试。

其他人是如何实现自动化的?

这是我的实现:

class SeleniumTest < Test::Unit::TestCase
  def setup
    @seleniums = %w(*firefox *iexplore).map do |browser|
      puts 'creating browser ' + browser
      Selenium::SeleniumDriver.new("localhost", 4444, browser, "http://localhost:3003", 10000)
    end

    start
    open start_address
  end

  def teardown
      stop
  end

  #sub-classes should override this if they want to change it
  def start_address
    "http://localhost:3003/"
  end

  # Overrides standard "open" method
  def open(addr)
    method_missing 'open', addr
  end

  # Overrides standard "type" method
  def type(inputLocator, value)
    method_missing 'type', inputLocator, value
  end

  # Overrides standard "select" method
  def select(inputLocator, optionLocator)
    method_missing 'select', inputLocator, optionLocator
  end

  def method_missing(method_name, *args)
    @seleniums.each do |selenium_driver|
      if args.empty?
        selenium_driver.send method_name
      else
        selenium_driver.send method_name, *args
      end

    end
  end
end

这可行,但如果一个浏览器失败,则整个测试都会失败,并且无法知道它在哪个浏览器上失败。

【问题讨论】:

标签: ruby-on-rails ruby unit-testing selenium automated-tests


【解决方案1】:

免责声明:不是硒专家。

您只是想知道哪个浏览器出现故障,还是希望在所有浏览器上运行测试,然后在完成时报告全部故障?

如果您在设置中通过哈希存储驱动程序,则前者非常简单。 (我敢肯定 Hash.inject 有一种花哨的方法可以做到这一点,但我很懒。)

@seleniums = {}
%w(*firefox *iexplore).each do |browser|
  puts 'creating browser ' + browser
  @seleniums[browser] = Selenium::SeleniumDriver.new("localhost", 4444, browser, "http://localhost:3003", 10000)
end

然后更改您的核心函数以修改异常以包含正在使用的驱动程序的名称,例如:

@seleniums.each do |name, driver|
  begin
    driver.send method_name, *args
  rescue Exception => ex
    raise ex.exception(ex.message + " (in #{name})")
  end
end

应该让你靠近。

【讨论】:

  • 好主意,虽然我认为失败的测试不一定会引发异常。
  • 实际上,他们应该总是抛出某种 AssertionFailedException;但是下面的那个网格看起来非常光滑。
【解决方案2】:

你试过Selenium Grid吗?我认为它创建了很好的摘要报告,显示了您需要的详细信息。我可能是错的,因为我有一段时间没有使用它。

【讨论】:

    【解决方案3】:

    我最终修改了 Selenium 的 protocol.rb 以引发 AssertionFailedError,同时带有 @browser_string 和从 Selenium RC 返回的消息,如果响应没有以“OK”开头。我还修改了 http_post 方法以返回整个响应正文,并修改 method_missing 以返回一个返回值数组,用于向 Selenium RC 发出 get_X 命令。

    将此代码添加到问题中的代码,您应该能够看到哪些断言在哪些浏览器上失败。

    # Overrides a few Driver methods to make assertions return the
    # browser string if they fail
    module Selenium
      module Client
        class Driver
          def remote_control_command(verb, args=[])
            timeout(default_timeout_in_seconds) do
              status, response = http_post(http_request_for(verb, args))
              raise Test::Unit::AssertionFailedError.new("Browser:#{@browser_string} result:#{response}") if status != 'OK'
              return response[3..-1]
            end
          end
    
          def http_post(data)
            http = Net::HTTP.new(@server_host, @server_port)
            response = http.post('/selenium-server/driver/', data, HTTP_HEADERS)
            #return the first 2 characters and the entire response body
            [ response.body[0..1], response.body ]
          end
        end
      end
    end
    
    #Modify your method_missing to use seleniums.map to return the
    #results of all the function calls as an array
    class SeleniumTest < Test::Unit::TestCase
      def method_missing(method_name, *args)
        self.class.seleniums.map do |selenium_driver|
          selenium_driver.send(method_name, *args)
        end
      end
    end   
    

    【讨论】:

      【解决方案4】:

      您需要独立对待每个测试。因此,如果一项测试失败,它将继续测试其他测试。查看phpunit and selenium rc

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-24
        • 1970-01-01
        • 1970-01-01
        • 2012-04-03
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多