等待
在测试动态网站时,正确同步代码与浏览器状态一直是测试人员面临的最大问题。
休眠
人们经常讨论硬编码 #sleep
是一种不好的做法。除了表明您的测试套件不够成熟之外,硬编码休眠还会带来一些特定的技术问题。最大的问题是,您必须权衡休眠时间足够长与在整个代码中散布额外的、通常不必要的 30 秒休眠之间的平衡。
Selenium 等待 - 隐式和显式
Selenium 有两种同步方法。第一种是“隐式等待”。据推测,此功能的灵感来自早期版本的 Watir,这些版本在自动等待元素方面做得更好。使用隐式等待意味着告诉驱动程序在尝试定位元素时,如果找不到元素,则应用一个全局值来等待多长时间。隐式等待的理念很好,但这种实现形式有两个主要问题,因此 Watir 不建议也不提供直接设置它们的访问权限。
- 等待发生在定位期间,而不是在尝试对元素进行操作时。这使得在元素出现之前无法立即查询元素的状态。
- 隐式等待本身不足以处理代码中的所有同步问题。将等待职责委托给驱动程序并利用代码中的轮询(显式等待)的组合会导致难以调试的奇怪现象。
Selenium 中的第二种也是推荐的等待方法是使用显式等待。这将同步的责任保留在您的代码中。在这种方法中,您的代码将不断检查提供的条件是否满足,并在满足时继续执行代码的下一部分。Watir 的等待方法都利用了这种从提供的条件中轮询所需输出的理念。
存在时和启用时
在 Watir 6.0 之前,确保代码等待浏览器准备就绪的最佳方法是在操作之前插入 #when_present
或 #when_enabled
方法。
browser.text_field(title: 'Search').when_present.set 'Hello World!'
这里的问题是,如果您不确定元素是否存在或已启用,则永远不应该使用 #set
,因此这些 #when_present
调用在哲学上是多余的。
因此,Watir 6.0 已弃用 #when_present
和 #when_enabled
,并且默认情况下,对元素的每个操作调用都会有效地执行此逻辑。
请注意,Watir 在执行操作时会自动等待,而不是在尝试定位时等待。这为查询元素状态提供了额外的灵活性,而无需进行不必要的等待。
Watir 等待和可等待模块
Waitable
是由 Browser
、Alert
、Window
和 Element
包含的模块。此模块提供对两种主要方法的访问:#wait_until
和 #wait_while
。从 Watir 6 开始,这两种方法都接受 :timeout
、:message
关键字参数。请注意,:interval
关键字是在 Watir 6.1 中添加的,以允许减少轮询条件的频率,并且从 Watir 6.12 开始,您可以对 :message
使用 Proc
实例值,如果更喜欢使用 String
)。然后,一如既往,传递一个块来建立需要满足的条件。 #wait_until
将执行块,直到返回一个真值结果,而 #wait_while
将执行块,直到返回一个假值结果。
browser.wait_until { |b| b.title == "Foo" }
browser.window(title: "Foo")wait_while(&:exists?)
browser.alert.wait_until { |a| a.text == "foo" }
browser.button(name: 'submit').wait_until(&:enabled?)
请注意,鼓励尽可能使用 #to_proc
语法
# Good
browser.text_field(title: 'Search').wait_until(message: "Can't find it" &:present?)
# Less Good
browser.text_field(title: 'Search').wait_until(message: "Can't find it") { |el| el.present? }
Watir 等待的默认超时时间为 30 秒。您可以将 :timeout
关键字参数传递给任何等待方法,或者可以使用以下方法更改全局默认值:
Watir.default_timeout = 60
等待出现和等待消失
从 6.15 开始,#wait_while_present
和 #wait_until_present
已被弃用。对于 6.2 到 6.14 版本,这些方法的行为与 .wait_until(&:present?)
和 .wait_while(&:present?)
有细微的差别。这种情况不再存在,这些方法不再应该使用。