我的测试目标是断言某些操作后不会出现弹出窗口。
以前,我已经使用异常处理来测试弹出窗口是否存在。

try:

    self.driver.find_element_by_id("fancybox-close").click()

except Exception ('ElementNotVisibleException'):

    print "No popup"


对于测试而言,它工作正常:断言是否存在弹出窗口。

但是一旦我将目标更改为:断言是否不存在弹出窗口

异常处理解决方案变得非常昂贵(异常处理在python中需要花费大量时间),而现在要在3秒钟内执行的测试最多需要一分钟。

是否可以解决这个问题?使用webdriver python绑定更快地检查元素是否不存在?

评论

您估计在一分钟的测试过程中该代码片段会执行多少次?

它只执行一次,但是在1分钟的90%内停在“除外”部分。

听起来可疑。在现代硬件上,我希望“慢速”异常处理意味着更多的微秒,甚至可能更多的毫秒,但肯定不是54秒。

我可能应该使用探查器来获取在try / catch块中花费的确切时间。但是从过去的测试结果来看,没有引发异常的测试在4到8秒内进行了,而引发异常的测试进行了大约一分钟或刚刚结束。代码中没有其他更改。

#1 楼

我还没有使用过Python绑定,但据我所知它们应该等效于Java绑定。

如果我是我,我会尝试找到findElements()isDisplayed()的Python等效项例如,我会做类似的事情:

// ...
myElementList = driver.findElements(By.Id("fancybox-close"))
if (myElementList.isEmpty()) {
    // The element doesn't exist. findElements, in plural, returns a list of the matching elements, or an empty list if no one is found
else {
    // We know it exists, now we need to know if it's displayed (visible) or not
    if (myElementList[0].isDisplayed()) {
        // This means the element is visible
    else {
        // ...
    }

}


希望对您有所帮助

评论


伊格纳西奥,这是一个好主意。 python绑定具有find_elements()和is_displayed()。但是,我在检查列表是否为空时遇到了麻烦。我收到一条错误消息,提示“内置函数ID不可序列化JSON。必须查看它。否则,这是个好主意。谢谢!

–user1411110
2012年7月17日19:39



isEmpty()是列表的Java方法。在Python中,我认为您应该检查列表的长度(len(driver.find_elements(...))== 0)?我现在无法自己检查。

– Ignacio Contreras Pinilla
2012年7月17日在19:43



在python中检查列表是否为空,如果不是:,则只需执行操作:其中= []是列表。那就是我在做什么。如果不是self.driver.find_elements(By.id(“ fancybox-close”)):

–user1411110
2012年7月17日在19:53



而且行不通吗?

– Ignacio Contreras Pinilla
2012年7月17日在19:56

凉。现在,您应该为我的Python寻找等效的isDisplayed()(如果未显示元素,则单击时会抛出您正在使用的异常):

– Ignacio Contreras Pinilla
2012年7月17日在20:18

#2 楼

测试缓慢不是由于异常处理缓慢,而是因为驱动程序等待找不到元素。在这种情况下,驱动程序等待弹出窗口-可能会出现。

尝试使用self.driver.implicitly_wait(0)

这将告诉驱动程序如果找不到某些元素,请不要等待。

#3 楼

这是另一个类似Ignacio的示例,但使用C#:

    //Displayed
    public static bool IsElementDisplayed(this IWebDriver driver, By element)
    {
        if (driver.FindElements(element).Count > 0)
        {
            if (driver.FindElement(element).Displayed)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }
    }

    //Enabled
    public static bool IsElementEnabled(this IWebDriver driver, By element)
    {
        if (driver.FindElements(element).Count > 0)
        {
            if (driver.FindElement(element).Enabled)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }
    }


#4 楼

您可以使用多种方式来加快速度:


隐式等待
tstempko提到了这一点。但是,隐式等待有一个缺点。这将使驱动程序在设置为“ 0”时不必等待所有UI元素。在您的情况下,这是不理想的。您可能确实需要等待一段时间才能显示UI元素,然后您的测试会因无正当理由而中断。
显式等待
您可以为此调用设置显式等待。这允许以更健壮的方式等待UI元素显示。

对于我来说,Javascript执行程序
,有些Web元素太“不可靠”,无法一直检测到。我将使用的是这样的javascript执行程序:

String cmd = "$('#header-username').click()";
((JavascriptExecutor)driver).executeScript(cmd);


关于JavaScriptExcutor的好处是,只要加载了javascript,就可以执行它。浏览器不需要等待元素被渲染。这样做的缺点是它不是模仿用户的行为。我只使用它来进入我感兴趣的下一个测试区域。


附带说明,您可能想尝试一下,而不是您拥有的try-except方法用这种方式编写代码:不幸的是,我的代码是用Java编写的。我认为在Python中也有类似的方法。

#5 楼

在python中,要断言可见的内容,请使用:

element.is_displayed()


is_displayed()将等待元素可见或超时

如果要断言某个元素不可见,请使用:

element.is_not_displayed()


如果未显示该元素,它将立即返回True

#6 楼

在过去的几个月中,我使用的一种安全方法是提取最近的元素节点,并将其验证为XML。

(以下是您将获得的输出示例。)

WebElement element = driver.findElement(By.css("some path to a div"));
String documentNode = ((JavascriptExecutor) driver).executeScript("return arguments[0].outerHTML;", element);


修剪它,然后将其转换为文档并安全地xpath或手动解析节点。而已。这已经快了很多,而且没有陈旧状态的机会。不再无限期地等待。

希望有帮助。

#7 楼

我知道这是一篇旧文章,但是您可以使用Python进行更好的操作以测试元素不存在。

from selenium.common.exceptions import NoSuchElementException

with self.assertRaises(NoSuchElementException):
    driver.find_element_by_id(element_id)


如果您想检查一下是否无法请参阅元素,使用(如上所述)

self.assertFalse(element.is_displayed())