天天看點

使用WebDriver過程中遇到的那些問題

  但是我在使用selenium webdriver時,遇到了很多坑。這些問題,有的是因為selenium webdriver與浏覽器不同版本之間相容性的問題,有的是selenium webdriver本身的bug,當然也不乏自己對selenium webdriver某些功能了解不透徹。我花時間總結了一下,分享給大家,希望大家以後遇到問題可以避過這些坑,少走彎路。另外也總結了一些使用webdriver的比較好的實踐,也一并分享給大家。

  webdriver每次啟動一個firefox的執行個體時,會生成一個匿名的profile,并不會使用目前firefox的profile。這點一定要注意。比如如果通路被測試的web服務需要通過代理,你想直接設定firefox的代理是行不通的,因為webdriver啟動的firefox執行個體并不會使用你這個profile,正确的做法是通過firefoxprofile來設定。

public webdriver create() {

firefoxprofile firefoxprofile = new firefoxprofile();

firefoxprofile.setpreference("network.proxy.type",1);

firefoxprofile.setpreference("network.proxy.http",yourproxy);

firefoxprofile.setpreference("network.proxy.http_port",yourport);

firefoxprofile.setpreference("network.proxy.no_proxies_on","");

return new firefoxdriver(firefoxprofile);

}

  通過firefoprofile也可以設定firefox其它各種配置。如果要預設給firefox安裝插件的話,可以将插件放置到firefox安裝目錄下的預設的plugin檔案夾中,這樣即使是使用一個全新的profile也可以應用此plugin。

  使用webdriver點選界面上button元素時,如果目前button元素被界面上其他元素遮住了,或沒出現在界面中(比如button在頁面底部,但是螢幕隻能顯示頁面上半部分),使用預設的webelement.click()可能會觸發不了click事件。

  修正方案是找到該頁面元素後直接發送一條click的javascript指令。

  ((javascriptexecutor)webdriver).executescript("arguments[0].click();", webelement);

  當進行了一些操作發生頁面跳轉時,最好加一個wait方法等待page load完成再進行後續操作。方法是在某個時間段内判斷document.readystate是不是complete。

protected function<webdriver, boolean> ispageloaded() {

return new function<webdriver, boolean>() {

@override

public boolean apply(webdriver driver) {

return ((javascriptexecutor) driver).executescript("return document.readystate").equals("complete");

};

public void waitforpageload() {

webdriverwait wait = new webdriverwait(webdriver, 30);

wait.until(ispageloaded());

如果頁面有ajax操作,需要寫一個wait方法等待ajax操作完成。方式與上一條中的基本相同。比如一個ajax操作是用于向dropdownlist中填充資料,則寫一個方法判斷該dropdownlist中元素是否多餘0個。

private function<webdriver, boolean> havemorethanoneoption(final by element) {

webelement webelement = driver.findelement(element);

if (webelement == null) {

return false;

} else {

int size = webelement.findelements(by.tagname("option")).size();

return size >= 1;

public void waitfordropdownlistloaded() {

  以此類推,我們可以判斷某個元素是否呈現、某個class是否append成功等一系列方法來判斷ajax是否執行完成。

  如果網站使用了jquery的動畫效果,我們在運作測試的時候其實可以disable jquery的animation,一方面可以加快測試的速度,另一方面可以加強測試的穩定性(如果啟用了animation,使用webdriver驅動浏覽器時可能會出現一些無法預料的異常)。

  ((javascriptexecutor)driver).executescript("jquery.fx.off=true");

  由于webdriver要驅動浏覽器,是以測試運作的時間比較長,我們可以并行跑測試以節省時間。如果你使用的是maven建構工具,可以配置surefire plugin時,在configruation節點加入以下配置。

  <parallel>classes</parallel>

  <threadcount>3</threadcount>

  <percorethreadcount>false</percorethreadcount>

  當測試fail的時候,如果目前使用的webdriver實作了takesscreenshot接口,我們就可以調用相應的方法截下目前浏覽器呈現的web頁面,這樣有利于快速定位出錯的原因。

  public void getscreenshot() {

  if (webdriver instanceof takesscreenshot) {

  takesscreenshot screenshottaker = (takesscreenshot) webdriver;

  file file = screenshottaker.getscreenshotas(savepath);

  }

  如果頁面彈出了浏覽器自帶的警告框(使用javascript的alert方法),selenium webdriver在點選次警告框時會偶發性失敗。具體原因還未查明。解決方案是盡量不使用alert方法的警告框,而是自己實作模式視窗(比如jquery ui的模式視窗)來實作警告框效果。這樣即保證了測試的穩定性,另外我們自己可以控制警告框的樣式,給使用者帶來更好的體驗。

  經常更新selenium的版本。注意經常上selenium的官網看是否釋出了新的版本,新的版本都修複了那些bug,如果包含你遇到的bug,就可以更新到目前的版本。

最新内容請見作者的github頁:http://qaseven.github.io/