通過研究selenium-webdriver的源碼,筆者發現其實webdriver的實現原理並不高深莫測無法揣度。在這里以webdriver ruby binding的firefox-webdriver實現為例,簡單介紹一下webdriver的工作原理。
-
當測試腳本啟動firefox的時候,selenium-webdriver 會首先在新線程中啟動firefox瀏覽器。如果測試腳本指定了firefox的profile,那么就以該profile啟動,否則的話就新啟1個profile,並啟動firefox;
-
firefox一般是以-no-remote的方法啟動,啟動后selenium-webdriver會將firefox綁定到特定的端口,綁定完成后該firefox實例便作為webdriver的remote server存在;
-
客戶端(也就是測試腳本)創建1個session,在該session中通過http請求向remote server發送restful的請求,remote server解析請求,完成相應操作並返回response;
-
客戶端接受response,並分析其返回值以決定是轉到第3步還是結束腳本;
這就是webdriver的工作流程,看起來很復雜實際上當了解了webdriver的實現原理后,理解上述問題應該比較簡單。
webdriver是按照server – client的經典設計模式設計的。
server端就是remote server,可以是任意的瀏覽器。當我們的腳本啟動瀏覽器后,該瀏覽器就是remote server,它的職責就是等待client發送請求並做出相應;
client端簡單說來就是我們的測試代碼,我們測試代碼中的一些行為,比如打開瀏覽器,轉跳到特定的url等操作是以http請求的方式發送給被 測試瀏覽器,也就是remote server;remote server接受請求,並執行相應操作,並在response中返回執行狀態、返回值等信息;
舉個實際的例子,下面代碼的作用是”命令”firefox轉跳到google主頁:
driver = Selenium::WebDriver.for :firefox
driver.navigate.to "http://google.com"
在執行driver.navigate.to “http://google.com” 這句代碼時,client,也就是我們的測試代碼向remote server發送了如下的請求:
POST session/285b12e4-2b8a-4fe6-90e1-c35cba245956/url
post_data {"url":"http://google.com"}
通過post的方式請求localhost:port/hub/session/session_id/url地址,請求瀏覽器完成跳轉url的操作。
如果上述請求是可接受的,或者說remote server是實現了這個接口,那么remote server會跳轉到該post data包含的url,並返回如下的response
{"name":"get","sessionId":"285b12e4-2b8a-4fe6-90e1-c35cba245956","status":0,"value":""}
該response中包含如下信息
-
name:remote server端的實現的方法的名稱,這里是get,表示跳轉到指定url;
-
sessionId:當前session的id;
-
status:請求執行的狀態碼,非0表示未正確執行,這里是0,表示一切ok不許擔心;
-
value:請求的返回值,這里返回值為空,如果client調用title接口,則該值應該是當前頁面的title;
如果client發送的請求是定位某個特定的頁面元素,則response的返回值可能是這樣的:
{"name":"findElement","sessionId":"285b12e4-2b8a-4fe6-90e1-c35cba245956","status":0,"value":{"ELEMENT":"{2192893e-f260-44c4-bdf6-7aad3c919739}"}}
name,sessionId,status跟上面的例子是差不多的,區別是該請求的返回值是ELEMENT:{2192893e- f260-44c4-bdf6-7aad3c919739},表示定位到元素的id,通過該id,client可以發送如click之類的請求與 server端進行交互。
那么remote server端的這些功能是如何實現的呢?答案是瀏覽器實現了webdriver的統一接口,這樣client就可以通過統一的restful的接口去進 行瀏覽器的自動化操作。目前webdriver支持ie, chrome, firefox, opera等主流瀏覽器,其主要原因是這些瀏覽器實現了webdriver約定的各種接口。