未分类[selenium]-元素定位不到的原因及解决办法

摘自-宋现锋《测试开发工程师丛书》,如有版权问题请及时联系本人,谢谢.

在我们编写自动化测试用例的过程中,经常会遇到元素定位不到的现象,有的时候我们用 Selenium IDE 检查的时候也能在 Firebug 中看到,可是运行代码的时候,总是提示元素找不到。经过我以往和经验和大家在网上的讨论,我总结了以下几种情况:

(1) 定位属性值是动态变化的情况

现象:在我们定位元素的时候,发现有 id, name 或其他的属性存在,于是就用相应的定位方法去定位。可是运行的时候提示定位不到,然后我们再去查看元素的时候,发现属性值和我们写代码的时候不一样了。

原因:通常产生这种情况的原因就是你使用的属性值是动态变化的,主要表现有属性值是一串数据,或是字符加一串数据等情况。页面加载一次变化一次,每次都不相同。

解决办法:我们应尽量避免用这样的属性值去定位,而采用这个元素下的其他固定不变的属性值。或是向上层查找,采用 Xpath 定位。

(2) Iframe 中的元素定位出错的情况

现象:我们在定位元素的时候,查看网页源码,发现有 iframe 存在。可是我们没有做特殊处理,而是直接用通用的定位方法, name ,id,xpath 或者 CSS 来定位。用 Selenium IDE 验证能查找到元素,可是运行测试用例的时候,总是元素找到。

原因:在我们运行测试脚本的时候,代码获取的是页面的句柄,而 iframe 在句柄中是当成一个元素来处理的。脚本是没有办法自己去iframe 中去定位元素的,所以当搜索完页面时,发现找不到要定位的元素,就当错误处理。

解决办法:当需要定位 iframe 中的元素的时候,先将句柄切换到iframe 中(driver.switchTo().frame("framename");),然后再去定位,就能定位到要测试的元素。

(3) 不同页面或 iframe 切换时元素定位情况现象:当我们在编写测试用例的时候,会遇到打开一个新页面,或是切换到一个新的 iframe 中,然后再去定位元素进行操作。但是我们的定位方法写的没有问题,而且在 Selenium IDE 中也验证通过,可是代码运行的时候还是会提示找不到元素。

原因:其实这个和定位 iframe 中元素的情况是一样的,在打开一个页面或是切换到一个 iframe 的时候, driver 获取的是当前页面或是iframe 的句柄。当你的操作切换到新的页面或是 iframe 的时候,如果代码不去做相应的切换,查找元素的时候还会在原来的句柄下查找,当然会出现查找不到的情况。

解决办法:当操作切换页面或是 iframe 的时候,我们的测试脚本也要做相应的切换,选择新打开的页面或是切换到新的 iframe 下。然后再去定位的时候,就会在新页面或是 iframe 下定位了。

(4) Xpath 编写出错的情况

现象:如果我们对一个元素编写了对应的 Xpath,然后在没有通过 Selenium IDE 进行验证的情况吧,就去编写代码执行测试用例。会出现查找不到元素的情况,或是页面发生了变化,导致 Xpath 路径有了变化,也会查找不到元素。

原因:主要的问题就是 Xpath 编写出错了,或是页面有改动。不管是增加了新的模块或是隐藏的 div,都会影响 Xpath 路径的。

解决办法:将代码中的 Xpath 拷出来,放到 Selenium IDE 中进行Web验证。如果出错了,就做相应的修改。这个也是代码维护中当遇到的问题,被测试对象变化,导致测试用例的修改。

(5) 操作速度过快,被定位的元素没有加载出来的情况

现象:在测试用例运行过程中,会出现被定位的元素有的时候能定位的到,有的时候却定位不到的现象。而我们去页面上验证我们的定位方法的时候,没有一点儿问题,显示不是定位方法写错了。

原因:这种情况多半是因为测试用例执行到代码的时候,被定位元素没有加载出来造成的。网速原因,执行代码的机器原因,都会造成加载比程序执行的慢的情况。

解决办法:在我们定位元素之前,评估一下页面的加载情况,如果有加载慢的地方,需要添加一定等待时间 self.sleep(5000),等上几秒后再去定位操作。

(6) 定位页面嵌入式元素的情况

现象:在页面中会有一些儿嵌入式元素,如 object,播放器等。这个时候,我们对其操作的时候,是无法定位到上面的元素的。

原因:嵌入式元素对 webdriver 来说是一个元素,不管里面包含多少元素,都无法操作。对于 object 对象,网上有说要对相应的 Flash重新编译,添加相应的代码或是控件才能定位。但这样一样又不安全了,所以嵌入式对象一直是自动化测试的盲区。

解决办法:嵌入式对象如果是简单的单击操作,可是用模拟鼠标单击相应的区域,就能完成操作。如果是输入操作,我们可以先模拟点击输入区,然后模拟键盘进行输入。除此之外,好像也没有什么好的办法。

(7) firefox 安全性报错的情况

现象:firefox 安全性强,不允许跨域调用出现报错,错误描述: uncaught exception: [Exception... "Component returned failure code: 0x80004005(NS_ERROR_FAILURE) [nsIDOMNSHTMLDocument.execCommand]"nsresult: "0x80004005 (NS_ERROR_FAILURE)" location:

原因: 这是因为 firefox 安全性强,不允许跨域调用。

解决办法: Firefox 要取消 XMLHttpRequest 的跨域限制的话,第一是从 about:config 里设置 signed.applets.codebase_principal_support= true; (地址栏输入 about:config 即可进行 firefox 设置)。

第二就是在 open 的代码函数前加入类似如下的代码:

try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");

}

catch (e)

{

alert("Permission UniversalBrowserRead denied.");

}

对错误进行处理。

 

原文地址:https://www.cnblogs.com/alpha-go/p/6952693.html