Selenium Grid原理

轉載: http://blog.csdn.net/five3/article/details/9428655java

Selenium-Grid版本node

selenium-grid分爲版本1和版本2,其實它的2個版本並非和selenium的版本1和2相對應發佈的[即selenium-grid2的發佈比selenium2要晚一點]。不過幸運的是如今的selenium-grid2基本能支持selenium2的全部功能了。linux

selenium雖然分1和2,但其實原理和基本工做方式都是同樣的。只是版本2同時支持selenium1和selenium2兩種協議,而且在一些小的功能和易用性上進行了優化。好比:指定測試平臺的方式;如下未做特殊說明的Selenium-Grid均爲通用。web

Selenium1工做原理chrome

selenium1中除了使用selenium-core之外,進行自動化測試時都須要使用selenium-RC來做爲代理[不論是本機仍是遠程],目的是爲了解決同源問題;而形成同源問題的緣由是由於selenium1中是使用Javascript來驅動測試執行的【瀏覽器因爲安全問題不容許不一樣域之間的JS調用,即非同源不可調用;而selenium1中的工做方式就是在宿主頁面注入JS而且經過調用JS來執行測試操做的,因此就設計到同源問題】。因此爲了達成目的,其解決方案就有2種:瀏覽器

一、使用selenium-core:安全

selenium-core是一組js庫,用來驅動瀏覽器操做的全部庫文件都在這裏,整個selenium1能夠認爲核心組件就是這個selenium-core;而使用selenium-core的方式就是在被測試站點程序的源碼裏把selenium-core中的全部js庫直接添加到頁面裏,這樣頁面正常加載的同時也會把selenium-core加載下來,而且天生就是同源的。 二、使用selenium-RC:session

RC是一個http代理程序,用來注入到瀏覽器和被測web程序之間,這樣瀏覽器全部的請求和接收的內容都會經過RC;RC會把瀏覽器的請求發送給真實的web程序,而在接收到web程序的響應內容時,並無把內容原本來本的返回給瀏覽器客戶端,而是把包含selenium-core的內容注入到響應內容中去,而後才發送響應內容給瀏覽器,這樣就經過欺騙的方式讓瀏覽器認爲selenium1的驅動類庫一樣是同源的。分佈式

Selenium2工做原理工具

selenium2中由於使用的webdriver,這個技術不是靠js驅動的,而是直接調用瀏覽器的原生態接口驅動的。因此就沒有同源問題,也就不須要使用RC來執行本地腳本了【固然缺點就是並非全部的瀏覽器都有提供很好的驅動支持,但JS倒是全部瀏覽器都通用的】。因此selenium2中執行本地腳本的方式是:經過本地webdriver驅動直接調用本地瀏覽器接口就完事了。在本地調用本地的代碼是這樣的:

 
	import org.openqa.selenium.*;
	import org.openqa.selenium.firefox.*;
	
	WebDriver wd = new FirefoxDriver();
	wd.doSomething()

 

 

但有時候並老是隻執行本地測試的腳本,有時候可能須要在本地調用遠程的環境來執行測試,【好比:由於測試環境覆蓋緣由】此時就須要一個相似selenium1中的RC來承擔這個任務,也就是selenium2中的selenium-server。selenium-server支持接收遠程腳本的調用命令,而後操做其宿主機上的瀏覽器來到遠程執行測試的任務。固然selenium-server爲了兼容selenium1的腳本,它一樣也支持selniumRC所支持的功能【即能接收selenium1的調用命令】。在本地調用遠程機器執行測試的代碼是這樣的:

 
	import org.openqa.selenium.*;
	import org.openqa.selenium.remote.RemoteWebDriver;
	import org.openqa.selenium.remote.DesiredCapabilities;
	
	DesiredCapabilities ieDesiredcap = DesiredCapabilities.internetExplorer();
	WebDriver wd = new RemoteDriver("http://localhost:4444/wd/hub", ieDesiredcap);
	wd.doSomething()

 

可是在運行這段代碼以前,要先啓動Selenium-Server;啓動命令爲:

 
	java -jar selenium-server-standalone-x.xx.x.jar

 

調用selenium-server對應的結構圖:

Selenium-Grid工做原理

到此爲止,其實尚未提到selenium-grid,由於到目前爲止咱們尚未需求說同時覆蓋多個平臺和瀏覽器,而selenium-grid在這種狀況下就會體現出其做用來。selenium-grid是用於設計幫助咱們進行分佈式測試的工具,其整個結構是由一個hub節點和若干個代理節點組成。hub用來管理各個代理節點的註冊和狀態信息,而且接受遠程客戶端代碼的請求調用,而後把請求的命令再轉發給代理節點來執行。使用selenium-grid遠程執行測試的代碼與直接調用Selenium-Server是同樣的[只是環境啓動的方式不同,須要同時啓動一個hub和至少一個node]:

 
java -jar selenium-server-standalone-x.xx.x.jar -role hub
java -jar selenium-server-standalone-x.xx.x.jar -role node

上面是啓動一個hub和一個node,如果同一臺機器要啓動多個node則要注意端口分配問題,能夠這樣來啓動多個node:

 
	java -jar selenium-server-standalone-x.xx.x.jar -role node -port 5555
	java -jar selenium-server-standalone-x.xx.x.jar -role node -port 5556
	java -jar selenium-server-standalone-x.xx.x.jar -role node -port 5557

 

調用Selenium-Grid的基本結構圖以下: 上面是使用selenium-grid的一種普通方式,僅僅使用了其支持的分佈式執行的功能,即當你同時須要測試用例比較多時,能夠平行的執行這些用例進而縮短測試總耗時;除此以外,selenium-grid還支持一種更友好的功能,便可以根據你用例中啓動測試的類型來相應的把用例轉發給符合匹配要求的測試代理。例如你的用例中指定了要在Liunux上FF的3.6版本進行測試,那麼selenium-grid會自動匹配註冊信息爲Linux、且安裝了FF3.6的代理節點,若是匹配成功則轉發測試請求,若是失敗則拒絕請求。使用selenium-grid的遠程兼容性測試的代碼同上。其調用的基本結構圖以下:
瞭解了selenium-grid的基本結構,再來看看selenium-grid通訊的原理。假設如今咱們有這樣一個場景:[一個測試請求客戶端、一個hub節點、一個Windows+ie代理、一個linux+FF代理、一個Mac+Safari代理、一個任意平臺下的Chrome代理]。其分佈圖以下:

測試的代碼以下:

 
	import org.openqa.selenium.*;
	import org.openqa.selenium.remote.RemoteWebDriver;
	import org.openqa.selenium.remote.DesiredCapabilities;
	
	//test01: 只匹配Windows下的ie來執行此用例,版本不限;多個版本匹配成功時優先級暫未知
	DesiredCapabilities aDesiredcap = DesiredCapabilities();
	aDesiredcap.setBrowserName("internet explorer")
	aDesiredcap.setVersion("")
	aDesiredcap.setPlatform(Platform.WINDOWS)
	WebDriver wd = new RemoteDriver("http://localhost:4444/wd/hub", aDesiredcap);
	wd.doSomething()
	
	//test02: 只匹配linix下的firefox的版本爲22的瀏覽器執行用例;	
	DesiredCapabilities aDesiredcap = DesiredCapabilities("firefox", "22", Platform.LINUX);
	WebDriver wd = new RemoteDriver("http://localhost:4444/wd/hub", aDesiredcap);
	wd.doSomething()	
	
	//test03: 只匹配MAC下的safari瀏覽器執行,版本不限	
	DesiredCapabilities aDesiredcap = DesiredCapabilities.safari();
	aDesiredcap.setPlatform(Platform.MAC)
	WebDriver wd = new RemoteDriver("http://localhost:4444/wd/hub", aDesiredcap);
	wd.doSomething()	
	
	//test04: 只匹配chrome瀏覽器,任意平臺,任意版本
	DesiredCapabilities aDesiredcap = DesiredCapabilities.chrome();
	aDesiredcap.setPlatform(Platform.ANY)
	WebDriver wd = new RemoteDriver("http://localhost:4444/wd/hub", aDesiredcap);
	wd.doSomething()	

 

那麼整個測試執行的過程大概是這樣的。首先咱們在測試請求機上執行測試代碼,代碼中測試啓動方式爲遠程調用;

 
WebDriver wd = new RemoteDriver("http://localhost:4444/wd/hub", aDesiredcap);

此時測試腳本就會根據啓動參數鏈接hub節點,這裏的鏈接信息爲

 
http://localhost:4444/wd/hub

鏈接到hub成功後,會在hub上註冊一個session信息;[後面再與hub通訊時就會帶上這個session信息,告訴hub我以前來過,而且以前是被分配到哪一個代理節點上執行過測試]

hub在接受初始化請求時會根據請求的類型來匹配全部代理,並肯定是否有符合規則的代理;

若是匹配失敗了就會拒絕該初始請求;若是匹配成功則通知對應代理節點進行對應的初始化操做,這裏是啓動XX,並記錄瀏覽器的註冊session,最後發回給hub端;

hub端接收到代理端起的完成後的session信息後,在hub中一樣要記錄session並返回給測試請求端,[session中會保存匹配到的代理信息]

在初始化請求成功以後,測試請求端會繼續發送下一條測試命令,這裏的命令是:

 
wd.doSomething()

 

此命令會一樣被髮送給hub,固然是帶上session信息的;

hub接收到帶有session的請求命令時,會查詢session的信息,得知session中對應的代理後就把請求的命令給轉發給該代理;

代理在接收到hub發送過來的測試命令後,一樣查詢其session信息,並根據session信息操做與之對應的瀏覽器以執行測試;

測試完成後會通知hub執行結果,hub再轉發給測試請求端,測試請求端根據的返回信息來決定接下來的執行流程;

最後測試結束後,通知hub關閉瀏覽器進程,同時清除對應的session信息。

由selenium-grid的原理能夠得知

經過selenium-grid執行遠程操做時,並不須要遠程機器上有測試腳本;可是遠程機器上必須安裝了對應的webdriver程序[能夠直接放在環境變量的目錄裏便可],固然了,還得須要正確的啓動了代理程序

相關文章
相關標籤/搜索