Django:关于浏览

时间:2015-08-16 00:50:03

标签: python django selenium django-testing

我正在使用Chrome网络驱动程序,因为Firefox webdriver似乎在我的Windows PC上出现问题。

我的Django功能测试在我去度假之前工作得很好,但现在他们正在抛出各种错误。

有时候,当我试图在页面上找到一个元素时,我得到了:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

其他时候,尝试验证网址失败,因为Selenium似乎正在读取上一页的网址。失败点似乎在不同运行之间发生变化,换句话说,测试的某些部分可以在执行之间交替成功和不成功。但是,使用.click()后,似乎总会出现此问题。

在观看浏览器时,Selenium似乎成功导航到该页面,因此我认为它只是在浏览器中存在之前过快地查找项目。

implicitly.wait()添加到我的setUpClass似乎没有帮助,但我可能使用它错了。

我尝试了来自Harry Percival's site的有希望的想法(下面),但Selenium只是在坐在被告知要等待的页面上时超时。

from contextlib import contextmanager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import \
    staleness_of
class MySeleniumTest(SomeFunctionalTestClass):
    # assumes self.browser is a selenium webdriver

    @contextmanager
    def wait_for_page_load(self, timeout=30):
        old_page = self.browser.find_element_by_tag_name('html')
        yield
        WebDriverWait(self.browser, timeout).until(
            staleness_of(old_page)
        )

    def test_stuff(self):
        # example use
        with self.wait_for_page_load(timeout=10):
            self.browser.find_element_by_link_text('a link')
            # nice!

还有其他人处理过此事吗?我应该遵循这个问题的正确方法是什么?

编辑: 发布的解决方案非常出色,并且真正清理了我的代码,因为我能够简单地将.click()添加到被调用的函数中,就像所描述的那样。

以下是帮助我自定义此文档的文档:

Documentation for the syntax for By for modification purposes.

Documentation for Selenium's Expected Conditions

注意:我使用的是术语"浏览器"代替司机,我认为这是最初让我失望的原因。

1 个答案:

答案 0 :(得分:2)

wait_for_page_load必须是生成器吗?我想它会在没有等待的情况下回归!这就是为什么你的测试很不稳定的原因。有时,当你调用find_element_by_link_text时,元素会被加载。

我成功地使用了这种方法:

from selenium.webdriver.support import expected_conditions as EC

def wait_for_element(self, elm, by = 'id', timeout=10) :
    wait = WebDriverWait(self.driver, timeout)
    if by == 'id' :
        element = wait.until(EC.element_to_be_clickable((By.ID,elm)))
        return self.driver.find_element_by_id(elm)
    elif by == 'link':
        wait.until(EC.element_to_be_clickable( (By.LINK_TEXT,elm)))
        return self.driver.find_element_by_link_text(elm)
    # by tag, by css etc etc goes here.

我将此方法称为dom元素的显着ID,该元素应在页面可以与之交互之前显示。返回的元素可以直接交互。