您的位置:首页 > 编程语言 > Python开发

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的错误。因此,我建议自己写一个函数等待,用起来顺心,如下:

    

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

以上为个人经验所谈,如有错误,望各位指出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息