Python+Selenium前端页面测试自动化
2014-11-25 11:17
701 查看
(selenium学习日志一)
【找元素】
学习selenium,个人的感觉是主要任务在【找元素】。而对于查找页面元素,有以下几个方法:
find_element(self, by=By.ID, value=None) #需要 importfrom selenium.webdriver.common.by import By
find_element_by_css_selector(self, css_selector) #通过CSS样式,如“#kw”
find_element_by_class_name(self, name) #通过node的classname,如<div class='sample'>
find_element_by_tag_name(self, name) #相当于node name ,如<dvi></div>
find_element_by_name(self, name) #通过node的name属性
find_element_by_partial_link_text(self, link_text) #部分链接文字,如<a>登录 sign</a>
find_element_by_link_text(self, link_text) #全部链接文字,如<a>sign</a>
find_element_by_xpath(self, xpath) #xpath路径
find_element_by_id(self, id_)
(以上方法的具体解析,网上很多,建议查看 虫师 作品 http://www.cnblogs.com/fnng/p/3183777.html)
如果有id,自然用find_element_by_id,如果没有,建议使用find_element_by_xpath,这个可以应付页面上的所有元素。而很多时候,常常会出现 No Such Element的报错。
针对这个问题,我归纳有以下几点:
1、元素处在不同的frame、iframe;
2、元素处在不同的window窗口;
3、页面未加载成功,元素不存在;
4、(也算第三点的一部分)由于网络线路等等原因,导致与服务器中断(又或者,你的这个请求得到的结果不正确,只是服务器只以为正确了),部分元素没来得及加载。
请注意,这里我强调的是浏览器“放弃”请求。
我的解决方案如下:
1、可以使用switch_to_frame一层层迭代,再查找元素;
2、可以使用switch_to_window;
3、网上的建议有两点:第一,使用WebDriverWait智能等待,如WebDriverWait(self.driver,7000).until(EC.alert_is_present(),"Time out,alert not appear");
第二,设置页面加载等待时间,如self.driver.implicitly_wait(10);
以上两点,我建议第一点,但在我实际操作中,依然没有很智能,还是会报No Such Element的错误。因此,我建议自己写一个函数等待,用起来顺心,如下:
同时,页面加载时间是不固定的,会因为你的网络而有所变化,所以强烈建议以上方法,智能等待。
另外,有网上有不少人问:WebDriver如何判断一个页面是否加载成功?
对这个问题,我想没有现成的函数实现。有人回答,len(driver.page_source) > 200,或者查找某个元素是否存在用来判断页面是否加载成功.....
个人感觉,问这个问题的思路错了。因为,WebDriver页面测试应着眼于元素上,而不应该死死盯在页面上。所以,我们应该想的是元素是否加载成功。
4、 当你使用第三点中的方法,智能等待元素出现的时候,如果没有发现【返回结果不正确】或者【已和服务器断开】,好吧,你就傻傻地等待。我曾遇到
这种情况,此时只需要重新请求即可,即driver.refresh()。如果你有想法,可以改写第三点的方法,请不要死循环或者多次请求,服务器会骂娘的。
1、window.open(新页面.html) 弹出一个新的页面,不常用;
2、window.showModalDialog 弹出子窗口,有父子关系;
3、alert 、 confirm、prompt,弹出子窗口,有父子关系;
4、通过javascript控制div弹出,属于原来的页面,不存在父子关系,现在最流行的弹窗方式
第一到第三点,组合使用switch_to_window、switch_to_frame、driver.switch_to_alert().accept()都能解决问题,也没什么好说的。我想强调的是这几点的区分,
很多时候,我们一看到弹出,就立刻使用driver.switch_to_alert().accept()处理。最烦的是,程序报错了也没醒悟,一直忙着去问度娘。亲,度娘也没想到你会这样子啊。
请看,左边的是confirm弹窗,右边是div弹出,很明显嘛。如果再无法区分,可以查看html,因为第四点不存在父子关系,所以【确定】按钮可以从html中找到。
1、display:none 相当于元素从页面中被移走,它下面所在的元素跟上填充,即消失
2、visibility=false 元素被隐藏,但位置还在
(以下方法有针对第一种实践过,第二种在理论上方法适用)
先模拟第一点:(A为隐藏元素Element)当鼠标移动元素B上时,元素A出现;等鼠标离开,元素A隐藏
解决方法:
方案一:使用ActionChains(driver).move_to_element(B) 。也许,此时你会讶异,A元素没出现。其实,A元素出现,只是在你看到她之前,她又匆匆离去。
原因在于move_to_element在执行时,鼠标在B上,执行后,鼠标已离开B。为了达到鼠标悬停的效率,可以使用如下方法:
ActionChains(driver).move_to_element(B).click_and_hold()
可没想到的是,元素B竟然是个链接,当点击后,driver发生了页面跳转,鼠标去到一个新的页面,你只有悲伤地看着她离你越来越远了。
如果你不放弃,可以考虑【循环】,即是,你尝试千万次的接触,纵使千万次都擦肩而过,只为A的一次回眸。
但这种方法成功的概率很低,且耗时多,不管你有多痴情。代码如下:
方法二:(极力推荐)使用javascript直接操作隐藏元素A,selenium使用execute_script()执行脚本。这是个完美的解决方案,且普遍适用,因为js可以操作所有的DOM
节点。js脚本中,你可以使用
var elementA= document.getElementByClassName(A) (或者使用getElementsByTagName等等)
do something at A
以上为个人经验所谈,如有错误,望各位指出
【找元素】
学习selenium,个人的感觉是主要任务在【找元素】。而对于查找页面元素,有以下几个方法:find_element(self, by=By.ID, value=None) #需要 importfrom selenium.webdriver.common.by import By
find_element_by_css_selector(self, css_selector) #通过CSS样式,如“#kw”
find_element_by_class_name(self, name) #通过node的classname,如<div class='sample'>
find_element_by_tag_name(self, name) #相当于node name ,如<dvi></div>
find_element_by_name(self, name) #通过node的name属性
find_element_by_partial_link_text(self, link_text) #部分链接文字,如<a>登录 sign</a>
find_element_by_link_text(self, link_text) #全部链接文字,如<a>sign</a>
find_element_by_xpath(self, xpath) #xpath路径
find_element_by_id(self, id_)
(以上方法的具体解析,网上很多,建议查看 虫师 作品 http://www.cnblogs.com/fnng/p/3183777.html)
如果有id,自然用find_element_by_id,如果没有,建议使用find_element_by_xpath,这个可以应付页面上的所有元素。而很多时候,常常会出现 No Such Element的报错。
针对这个问题,我归纳有以下几点:
1、元素处在不同的frame、iframe;
2、元素处在不同的window窗口;
3、页面未加载成功,元素不存在;
4、(也算第三点的一部分)由于网络线路等等原因,导致与服务器中断(又或者,你的这个请求得到的结果不正确,只是服务器只以为正确了),部分元素没来得及加载。
请注意,这里我强调的是浏览器“放弃”请求。
我的解决方案如下:
1、可以使用switch_to_frame一层层迭代,再查找元素;
2、可以使用switch_to_window;
3、网上的建议有两点:第一,使用WebDriverWait智能等待,如WebDriverWait(self.driver,7000).until(EC.alert_is_present(),"Time out,alert not appear");
第二,设置页面加载等待时间,如self.driver.implicitly_wait(10);
以上两点,我建议第一点,但在我实际操作中,依然没有很智能,还是会报No Such Element的错误。因此,我建议自己写一个函数等待,用起来顺心,如下:
def WaitAndFindElement(self,by,value=0,timedeta=5,timeout=300): element = None endtime = timeout while endtime > 0: try: element = self._driver.find_element(by, value) except: pass if element: break else: time.sleep(timedeta) endtime = endtime - timedeta return element
同时,页面加载时间是不固定的,会因为你的网络而有所变化,所以强烈建议以上方法,智能等待。
另外,有网上有不少人问:WebDriver如何判断一个页面是否加载成功?
对这个问题,我想没有现成的函数实现。有人回答,len(driver.page_source) > 200,或者查找某个元素是否存在用来判断页面是否加载成功.....
个人感觉,问这个问题的思路错了。因为,WebDriver页面测试应着眼于元素上,而不应该死死盯在页面上。所以,我们应该想的是元素是否加载成功。
4、 当你使用第三点中的方法,智能等待元素出现的时候,如果没有发现【返回结果不正确】或者【已和服务器断开】,好吧,你就傻傻地等待。我曾遇到
这种情况,此时只需要重新请求即可,即driver.refresh()。如果你有想法,可以改写第三点的方法,请不要死循环或者多次请求,服务器会骂娘的。
【弹窗处理】
html dom 弹出有以下几种:1、window.open(新页面.html) 弹出一个新的页面,不常用;
2、window.showModalDialog 弹出子窗口,有父子关系;
3、alert 、 confirm、prompt,弹出子窗口,有父子关系;
4、通过javascript控制div弹出,属于原来的页面,不存在父子关系,现在最流行的弹窗方式
第一到第三点,组合使用switch_to_window、switch_to_frame、driver.switch_to_alert().accept()都能解决问题,也没什么好说的。我想强调的是这几点的区分,
很多时候,我们一看到弹出,就立刻使用driver.switch_to_alert().accept()处理。最烦的是,程序报错了也没醒悟,一直忙着去问度娘。亲,度娘也没想到你会这样子啊。
请看,左边的是confirm弹窗,右边是div弹出,很明显嘛。如果再无法区分,可以查看html,因为第四点不存在父子关系,所以【确定】按钮可以从html中找到。
【隐藏元素处理】
在这里插个题外话,html隐藏元素有两种:1、display:none 相当于元素从页面中被移走,它下面所在的元素跟上填充,即消失
2、visibility=false 元素被隐藏,但位置还在
(以下方法有针对第一种实践过,第二种在理论上方法适用)
先模拟第一点:(A为隐藏元素Element)当鼠标移动元素B上时,元素A出现;等鼠标离开,元素A隐藏
解决方法:
方案一:使用ActionChains(driver).move_to_element(B) 。也许,此时你会讶异,A元素没出现。其实,A元素出现,只是在你看到她之前,她又匆匆离去。
原因在于move_to_element在执行时,鼠标在B上,执行后,鼠标已离开B。为了达到鼠标悬停的效率,可以使用如下方法:
ActionChains(driver).move_to_element(B).click_and_hold()
可没想到的是,元素B竟然是个链接,当点击后,driver发生了页面跳转,鼠标去到一个新的页面,你只有悲伤地看着她离你越来越远了。
如果你不放弃,可以考虑【循环】,即是,你尝试千万次的接触,纵使千万次都擦肩而过,只为A的一次回眸。
但这种方法成功的概率很低,且耗时多,不管你有多痴情。代码如下:
def ClickA(): try: favs_close = fs.find_element_by_xpath('../preceding-sibling::a[@class="S_close"]') #元素B的xpath except: return False return True def MoveToAndClickA(): while True: driver.move_to_element(B) result = ClickA() if result: break
方法二:(极力推荐)使用javascript直接操作隐藏元素A,selenium使用execute_script()执行脚本。这是个完美的解决方案,且普遍适用,因为js可以操作所有的DOM
节点。js脚本中,你可以使用
var elementA= document.getElementByClassName(A) (或者使用getElementsByTagName等等)
do something at A
以上为个人经验所谈,如有错误,望各位指出
相关文章推荐
- Selenium 使用 Selenium+PhantomJS 以静默方式完成前端页面 UI 自动化测试
- Python+Selenium使用Page Object实现页面自动化测试
- 构建Python+Selenium2自动化测试环境<二>:IE、Chrome和Firefox运行
- Python selenium+webdriver 自动化测试例子
- Selenium + Python 搭建自动化测试环境(三)
- Selenium2 Python 自动化测试实战学习笔记(九)
- Selenium2 Python 自动化测试实战学习笔记(四)
- python selenium 自动化测试环境安装
- Python-Selenium2做Web自动化测试(2)-自动化测试常用工具
- Selenium2 Python 自动化测试实战学习笔记
- Jenkins-测试自动化环境搭建(Python+RobotFramework+selenium)
- Selenium2 Python 自动化测试实战学习笔记(八)
- WIN7- selenium-python 自动化测试工具配置环境
- Selenium2 Python 自动化测试实战学习笔记(二)
- 如何利用selenium来进行自动化页面测试
- selenium + python 部署自动化测试环境
- 部署Python+Selenium2自动化测试环境
- selenium2+python如何启动Ie和Chrome进行自动化测试
- Selenium2 Python 自动化测试实战学习笔记(六)
- Selenium2 Python 自动化测试实战学习笔记(三)