【问题标题】:Explicit wait in Python Selenium with page object model带有页面对象模型的 Python Selenium 中的显式等待
【发布时间】:2018-02-08 14:58:59
【问题描述】:

我的显式等待不是等到元素出现。它实际上会等待我声明的秒数,然后测试仍然失败。如果我在测试通过的完全相同的地方放置一个隐式等待。从我正在阅读的内容来看,最好的做法是尽可能避免隐式等待。难道我做错了什么?

我在 base_page 中创建了一个方法,如下所示:

def _wait_for_is_displayed(self, locator, timeout):
        try:
            wait = WebDriverWait(self.driver, timeout)
            wait.until(expected_conditions.visibility_of_element_located((locator["by"], locator["value"])))
        except TimeoutException:
            return False
        return True

然后我像这样在页面对象中调用 _wait_for_is_displayed 方法,但失败了:

 def relatie_page_present(self):
     self._wait_for_is_displayed(self._open_actieve_polissen_tab, 10)

 def relatie_page_(self):
     self._click(self._open_relatie_details)
     self.relatie_page_present()

我得到的错误是:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"td.first > a"}

通过:

 def relatie_page_present(self):
        self.driver.implicitly_wait(10)

def relatie_page_(self):
    self._click(self._open_relatie_details)
    self.relatie_page_present()

最后在我的测试套件中,我调用了 relatie_page_present 和 relatie_page_ 方法。

【问题讨论】:

  • 等待 10 秒后失败会出现什么错误?请发布您使用的隐式等待代码,以便我们进行比较。
  • self.driver.implicitly_wait(10) 在 relatie_page_present(self) 方法中。
  • 你没有回答我的第一个问题。另外,请编辑问题并在其中发布详细信息以获取答案和代码。
  • 对不起。我刚刚编辑了我的问题。带有错误消息和通过测试的等待。

标签: python selenium object wait explicit


【解决方案1】:

为了阐明隐式等待的工作原理,它在驱动程序上设置一次,然后在驱动程序实例的生命周期内应用。所以调用self.driver.implicitly_wait(10) 实际上并没有等待在那一刻...它只是将驱动程序设置为在找到元素时从该点开始等待。我认为这让很多人感到困惑,因为我看到了很多。

无论如何,如果我是你,我会使用像下面这样的函数来等待元素可点击,然后点击它。您可以在需要等待某个元素被点击时随时调用它。

def _wait_and_click(self, locator, timeout):
    try:
        wait = WebDriverWait(self.driver, timeout)
        wait.until(expected_conditions.element_to_be_clickable((locator["by"], locator["value"]))).click()
    except TimeoutException:
        return False
    return True

【讨论】:

  • 我尝试使用给定的等待但出现错误:TypeError: string indices must be integers
【解决方案2】:

在您尝试调用click() 时向前推进,因此您应该使用element_to_be_clickable() 而不是使用expected_conditions 作为visibility_of_element_located(),如下所示:

try:
    wait = WebDriverWait(self.driver, timeout)
    wait.until(expected_conditions.element_to_be_clickable((locator["by"], locator["value"])))
  • 元素可点击 - WebElement 已显示已启用

避免混淆隐式等待显式等待documentation 明确提到:

警告:不要混合隐式和显式等待。这样做会导致不可预测的等待时间。例如,设置 10 秒的隐式等待和 15 秒的显式等待,可能会导致 20 秒后发生超时。

【讨论】:

    【解决方案3】:

    隐式等待是为查找元素API设置超时,如find_element_by_xxxfind_elements_by_xxx。其默认值为 10 秒。

    这是一个全局设置。一旦更改了隐式等待,调用 find element API 的所有代码位置都将采用相同的超时值。

    如果您觉得您网站的大多数页面/响应速度很慢,您可以通过增加超时值来更改它,直到遇到下一个隐式等待。

    但不等于说the implicit wait time out value is more large more better.

    假设您的网站 UI 有很大的变化或许多页面无法打开/加载,如果隐式等待超时值较大,则会增加整个运行的持续时间。因为每次查找元素都必须等待那么长的秒数然后抛出超时异常。

    显式等待只影响使用它的代码,它是全局影响。

    我看到你设置显式等待超时为10秒,它不超过隐式等待的默认值。

    一般情况下,显式等待应该比隐式等待长,否则不需要使用它,使用查找元素API可以归档相同的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-05
      • 2019-10-27
      • 1970-01-01
      • 2019-02-23
      • 2017-10-12
      • 2020-06-06
      • 2017-03-27
      • 1970-01-01
      相关资源
      最近更新 更多