1. 程式人生 > 其它 >讓selenium自動化指令碼執行的更快的技巧

讓selenium自動化指令碼執行的更快的技巧

讓自動化測試指令碼正常工作只是自動化測試的第一步,由於自動化指令碼會經常執行並更新,因此測試指令碼需要

  • 可以快速執行
  • 容易維護
  • 容易閱讀

本文會提供一些讓selenium自動化指令碼執行的更快的技巧。

在page_source中斷言text比直接使用text屬性斷言要快

我們經常會需要斷言頁面中的某個部分包含一些具體的文字,下面的語句的輸出結果是相同的

driver.page_source
driver.find_element(:tag_name=>‘body').

不過對於第二條語句來說,selenium需要去分析頁面的結構,最後再找到對應的元素並輸入結果,這顯然是需要花費時間的。如果頁面比較小的化,那麼二者的差距可能不大,不過對於大的頁面來說,第一條語句速度明顯會更快一些。

使用page text的情況

expect(driver.find_element(:tag_name=>"body").text).toinclude("platform-andlanguage-neutralwireprotocol")

使用 page source的情況

expect(driver.page_source).toinclude("platform-andlanguage-neutralwireprotocol")

來看一下差距

Method1:Searchwholedocumenttexttook0.823076seconds
Method2:SearchwholedocumentHTMLtook0.039573seconds

當然兩者的使用場景是不太相同的,不過我們這裡只關注效能,顯然page source要更快速一些。

元素越具體,獲取text的速度越快

根據經驗,我們可以通過縮小更具體的 Web 控制元件的範圍來節省執行時間。下面的兩個斷言語句在很大程度上實現了相同的功能,但在執行時間上有很大的不同。

expect(driver.find_element(:tag_name,“body”).text).toinclude(“language-neutralwire”)

這條語句的執行時間是0.93s

expect(driver.find_element(:id,“abstract”).text).toinclude(“language-neutralwire”)

這個斷言只執行了0.02s

很明顯,第2個斷言除了在執行速度上更快之外,斷言也更加精確,更容易理解。

使用變數去快取沒有變化的元素

我經常看到有人編寫如下測試來檢查頁面上的多個文字。

driver.navigate.to(site_url+"/WebDriverStandard.html")expect(driver.find_element(:tag_name,"body").text).toinclude("Firefox")
expect(driver.find_element(:tag_name,"body")").text).toinclude("chrome")
expect(driver.find_element(:tag_name,"body").text).toinclude("W3C")

執行時間2.35s

上述三個測試語句非常低效,因為每個測試語句都呼叫driver.find_element(:tag_name, 'body').text,當網頁很大時,這可能是費時費力的工作。

解決方案:使用一個變數來儲存網頁的文字,這是程式設計中很常見的做法。

the_page_text=driver.find_element(:tag_name,“body”).textexpect(the_page_text).toinclude("Firefox")
expect(the_page_text).toinclude("chrome")
expect(the_page_text).toinclude("W3C")

執行速度0.86s

無論我們在該頁面上執行了多少斷言(針對頁面文字),只要我們檢查的頁面文字沒有改變,我們都會獲得恆定的執行時間。

快速在文字框中輸入大文字

我們通常用來send_keys在文字框中輸入文字。當您發現要輸入的文字字串很大,例如數千個字元時,儘量避免使用,send_keys因為它不高效。下面是一個例子:

long_str=“START”+‘0’*1024*5+“END”#justover5K
text_area_elem=driver.find_element(:id,“comments”)
text_area_elem.send_keys(long_str)

執行時間3.8s

其實解決方案很簡單,用js來做

driver.execute_script(“document.getElementById('comments').value=arguments[0];”,long_str)

執行時間0.2s

使用動態等待進行動態/AJAX 操作而不是固定睡眠

對於一些前後端分離的頁面,由於操作之間頁面不會重新整理,我們就不能依賴selenium自帶的頁面重新整理等待機制,所以我們經常需要去等待一個元素出現或者消失,下面的程式碼演示了這個過程。

driver.find_element(:xpath,"//input[@value='Paynow']").click
sleep10#seconds
expect(driver.find_element(:id,"bn").text).toinclude("RN#")

這樣無論這個頁面的流暢程度如何,上面的程式碼都至少需要執行10s,一個用例的話10s可以接受,但如果大部分用例裡都有固定等待時間,那整個測試執行的過程將是非常緩慢的。

解決方案是使用動態等待。

wait=Selenium::WebDriver::Wait.new(:timeout=>10)#seconds
wait.until{driver.find_element(:id,"bn").text.include?("RN#")}

最後

如果用例是一個接一個序列執行的話,那麼執行速度可以優化的空間也是有上限的,更好的方案是多組用例一起執行,多一些執行機,把序列該成並行,這樣的優化效果將更加明顯。總之時間太長,就想辦法堆機器吧。

原文連結

如何優化selenium webdriver的執行速度 (qq.com)