【问题标题】:Do Watir-Webdriver and Capybara have performance issues when compared to Webdriver?与 Webdriver 相比,Watir-Webdriver 和 Capybara 是否存在性能问题?
【发布时间】:2013-08-24 17:46:14
【问题描述】:

我即将将我的测试自动化语言从 Java 更改为 Ruby(我有一份新工作,让 Ruby 更适合技术堆栈)。

我在 Java 和 Webdriver 方面拥有丰富的经验,但可以看到 Watir 和 Capybara 等包装器在 Ruby 中的使用似乎比直接访问 Webdriver API 更多。

我对使用这样一个库的担忧是性能。我通常会尝试将 Saucelabs 等第 3 方网格集成到我的测试框架中,但我了解到 Selenium Web 元素对象的缓存很重要,因为不断查找元素可能会对性能产生影响。

如果我使用 Capybara 等库,我会失去控制缓存策略的能力吗?我之前调查过 Geb,发现该框架不断地重新创建 web 元素而不是缓存,而且在改变这种行为方面似乎不够灵活。

我是否担心这些库可以帮助您避免编写样板代码但以牺牲性能为代价?

【问题讨论】:

  • 当你需要不断地寻找一个元素时,你能举个例子吗?我也有一个测试套件,但我认为那里没有这样的问题。
  • 根据我的经验,像el = find('#id'); el[:id].should == expected_id; el[:name].should == expected_name 这样简单的事情通常会有所帮助
  • 大多数时候我只想访问元素一次,所以我觉得默认情况下不需要缓存。
  • 你使用页面对象模式吗?
  • 不是这里写的形式 - code.google.com/p/selenium/wiki/PageObjects。我使用类似的东西。例如,我不遵循“一般不做断言”、“方法返回其他 PageObjects”、“同一操作的不同结果被建模为不同方法”等规则

标签: ruby selenium-webdriver capybara watir-webdriver selenium-grid


【解决方案1】:

TL;DR

约定优于配置;使用page-object 进行缓存。


以下是我对此事的看法。请考虑这不是一个答案,而更多的是对讨论的回应。我想要对此答案的反馈,请随时提供。

Ruby 中的主要模式之一(它实际上来自 Rails)是Convention over Configuration。基本思想是,当存在由语言或社区规定的约定时,您将尽可能地遵循它。就您而言,我建议尽可能使用社区框架。这将使其他开发人员更容易使用您的代码,并且在您需要时更容易寻求帮助。

就实际缓存而言,我不太熟悉。我知道page-object gem 存储元素而不是在每次使用时重新创建它们*。这似乎符合您对缓存元素的要求。无论如何,我强烈推荐这个 gem,因为它强制执行页面对象模型的测试。

注意:我不确定page-factory mixin 是否支持这种对象缓存,或者它是否在每次使用时重新创建类。

*您可以通过查看source codeElement 类来了解元素是如何存储在page-object 中的。

def initialize(element, platform)
  @element = element

【讨论】:

  • 您能否更准确地指定缓存在page-object gem 中的位置。我在链接文件中找不到它。
  • page-objects 在初始化程序中存储一个 @element 变量。这将在实例的整个生命周期中保留。因此,除非元素本身每次都删除对页面的引用并进行搜索,否则这意味着您应该只搜索该元素一次。
  • “约定优于配置”的论点是我没有考虑过的,而且非常引人注目。在罗马的时候......
  • 让我们用 Python 编写,因为很容易找到 Python 程序员?
【解决方案2】:

我不会对一般性能发表评论,因为我没有进行过广泛的比较(你不应该真的相信任何不能指出基准的人)。但是,这里有一个性能提示(有或没有包装器):

在内部,WebDriver 使用 HTTP 将命令发送到浏览器(或中间服务器)。由于该协议非常健谈,您通常可以通过将默认的基于 Net::HTTP 的客户端换成支持 Keep-Alive 的客户端(假设服务器支持它)来获得很多好处。这样,Ruby 客户端将为每个浏览器打开一个套接字并在会话期间重复使用它,而不是为每个命令打开一个。

下面是使用 net-http-persistent gem 的代码:

require "selenium/webdriver"
require "selenium/webdriver/remote/http/persistent"

client = Selenium::WebDriver::Remote::Http::Persistent.new
driver = Selenium::WebDriver.for :remote, url: 'http://...', http_client: client

【讨论】:

    【解决方案3】:

    不幸的是,我不能说关于 Capybara 的任何具体内容,但我可以说关于 watir-webdriver。默认情况下,它总是重新定位页面上的元素,因此您无法缓存它。可以使用

    关闭此行为
    Watir.always_locate = false
    

    虽然在这种情况下您可能会遇到过时的元素(然而,它实际上更多地取决于您,就像使用普通 WebDriver 一样)。如果您计划将 watir-webdriver 与 page-object gem 一起使用,默认情况下,它的缓存将不会像 @screenmutt 回答中所述那样工作。

    此外,Zejlko Fillipn 发表了两篇关于使用 SauceLabsTestingBot 时 watir-webdriver 性能的精彩博文。

    watir-webdriver 的另一个问题是跨浏览器性能。因为它在底层使用 XPath,所以在 IE 中进行测试时会遇到严重的性能问题。

    【讨论】:

    • 干得好。正如我所说,我对缓存不太熟悉。我的大部分答案是配置参数。
    • 那么你是说 water-WebDriver 将所有选择器转换为 XPath 吗?甚至 CSS 选择器?
    • CSS 选择器不会被转换。然而,它的支持远非完美(参见github.com/watir/watir-webdriver/issues/124)。您还可以通过设置 Watir.prefer_css = true 来强制 watir-webdriver 使用 CSS 选择器,在这种情况下,只有在无法创建 CSS 选择器时(例如,通过文本定位元素时)它才会回退到 XPath。
    猜你喜欢
    • 2023-04-05
    • 2018-04-01
    • 1970-01-01
    • 2013-01-12
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多