Selenium Grid2
利用Grid可以在不同的主機上建立主節點(hub)和分支節點(node)。使主節點上的測試用例在不同的分支節點上運作,可以搭建不同的環境,進而使一份測試用例完成在不同環境下的驗證。Selenium Grid2已經內建到selenium server中了(selenium-server-stanalon-xxx.jar包中)。
9.1 Selenium2工作原理
Selenium2 中因為使用的WebDriver,這個技術不是靠js 驅動的,而是直接調用浏覽器的原生态接口驅動的。是以就沒有同源問題,也就不需要使用RC 來執行本地腳本了(當然缺點就是并不是所有的浏覽器都有提供很好的驅動支援,但JavaScript卻是所有浏覽器都通用的)。是以Selenium2 中執行本地腳本的方式是:通過本地WebDriver 驅動直接調用本地浏覽器接口就可以了。
9.2Selenium Server環境配置
第一步,配置java環境:java 下載下傳位址:http://www.java.com/zh_CN/download/manual.jsp輕按兩下下載下傳的JDK ,設定安裝路徑。這裡我們選擇預設安裝在C:\Java\jdk1.7.0_45\
目錄下。下面設定環境變量:“我的電腦”右鍵菜單--->屬性--->進階--->環境變量--->系統變量-建立..
變量名:JAVA_HOME
變量值:C:\Java\jdk1.7.0_45\
變量名:CALSS_PATH
變量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
找到path 變量名—>“編輯”添加:
變量名:PATH
變量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
在Windows 指令提示符下驗證java 是否成功:java –version
第二步,下載下傳運作selenium server:下載下傳位址:http://www.seleniumhq.org/download/在頁面的左側清單中找到selenium-server-standalone-XXX.jar 進行下載下傳。下載下傳完成可以放到任意位置,直接在指令提示符下啟動Selenium Server:
C:\selenium> java -jarselenium-server-standalone-XXX.jar
執行se_rc.py 腳本,Selenium Server 将會做為代理,執行用戶端與伺服器端的請求與傳回資訊。
Se_rc.py
<pre name="code" class="html">#coding=utf-8
from selenium import selenium
import unittest, time, re
classserc(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost", 4444,"*chrome","http://www.baidu.com/")
self.selenium.start()
def test_serc(self):
sel = self.selenium
sel.open("/")
sel.type("id=kw","selenium grid")
sel.click("id=su")
sel.wait_for_page_to_load("30000")
def tearDown(self):
self.selenium.stop()
self.assertEqual([],self.verificationErrors)
if __name__ == "__main__":
unittest.main()
9.3 SeleniumGrid工作原理
Selenium Grid是進行分布式測試的工具,其整體結構是一個hub節點和若幹個node代理節點組成。Hub用來管理各個代理節點的注冊和撞他資訊,并且接受遠端客服端代碼的請求調用,然後把請求的指令再轉發給各個代理節點來執行。使用selenium grid遠端執行測試的代碼與直接調用Selenium-Server是一樣的(隻是環境啟動的方式不一樣,需要啟動一個hub和至少一個node):
> java -jarselenium-server-standalone-x.xx.x.jar -role hub
> java -jarselenium-server-standalone-x.xx.x.jar -role node
上面是啟動一個hub 和一個node,hub 預設端口号為4444,node 預設端口号為5555;若是同一台機器要啟動多個node 則要注意端口配置設定問題,可以這樣來啟動多個node:
> java -jar selenium-server-standalone-x.xx.x.jar-role node -port 5555
> java -jarselenium-server-standalone-x.xx.x.jar -role node -port 5556
> java -jarselenium-server-standalone-x.xx.x.jar -role node -port 5557
調用Selenium Grid 的基本結構圖如下:

上面是使用Selenium Grid 的一種普通方式,僅僅使用了其支援的分布式執行的功能,即當你同時需要測試用例比較多時,可以平行的執行這些用例進而縮短測試總耗時;關于并發的技術需要借助程式設計語言的多線程技術,我們會後面的章節深入學習Python 的多線程技術。除此之外,Selenium Grid 還支援一種更友好的功能,即可以根據你用例中啟動測試的類型來相應的把用例轉發給符合比對要求的測試代理。例如你的用例中指定了要在Liunux 上FireFox 的17 版本進行測試,那麼Selenium Grid 會自動比對注冊資訊為Linux、且安裝了FireFox17 的代理節點,如果比對成功則轉發測試請求,如果失敗則拒絕請求。使用SeleniumGrid 的遠端相容性測試的代碼同上。其調用的基本結構圖如下:
下面我們就來示範啟動一個hub 主節點和兩個node 分支節點。
通過浏覽器通路gird 的控制台:http://127.0.0.1:4444/grid/console
通過控制台檢視啟動的節資訊:
Node(5555)配置資訊:
port:5555
servlets:[]
host:192.168.5.57
cleanUpCycle:5000
browserTimeout:0
hubHost:192.168.5.57
registerCycle:5000
capabilityMatcher:org.openqa.grid.internal.utils.DefaultCapabilityMatcher
newSessionWaitTimeout:-1
url:http://192.168.5.57:5555
remoteHost:http://192.168.5.57:5555
prioritizer:null
register:true
throwOnCapabilityNotPresent:true
nodePolling:5000
proxy:org.openqa.grid.selenium.proxy.DefaultRemoteProxy
maxSession:5
role:node
jettyMaxThreads:-1
hubPort:4444
timeout:300000
9.4selenium Grid應用
之前編寫的腳本隻能在固定的某一款浏覽器上執行,因為在編寫測試用例之前需要先指定好浏覽器的驅動(webdriver.Firefox、webdriver.Chrome),一旦确定了浏覽器驅動是不能進行更改的。我們希望寫好的測試用例可以自由的切換成不同的浏覽器來執行。
9.4.1 認識Remote
WebDriver 提供了Remote 可以發送指令到遠端伺服器控制浏覽器。首先我們先來認識Remote 的格式。Remote_ts.py:
</pre><pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html">from selenium.webdriver import Remote
fromselenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = Remote(command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME
)
driver.get('http://www.baidu.com')
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
driver.quit()
command_executor 為指令執行器,它用于指定腳本執行的主機及端口。
>>> from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
>>> a=DesiredCapabilities.CHROME
>>> print a
{'platform': 'ANY', 'browserName': 'chrome', 'version': '','javascriptEnabled':
True}
Desired Capabilities 本質上是keyvalue 的對象,它告訴Selenium Server 腳本執行的基本運作環境:
'platform': 'ANY' 平台預設可以是任何(Windows,MAC,android)。
'browserName': 'chrome' 浏覽器名字是chrome。
'version': '' 浏覽器的版本預設為空。
'javascriptEnabled': True javascript 啟動狀态為True
Remote_ts.py:
from selenium.webdriver import Remote
fromselenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = Remote(command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities={'platform': 'ANY',
'browserName':'chrome',
'version': '',
'javascriptEnabled':True
}
)
driver.get('http://www.baidu.com')
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
driver.quit()
WebDriver API 提供了不同平台及浏覽器的參數:
ANDROID ={'platform': 'ANDROID', 'browserName': 'android', 'version': '','javascriptEnabled': True}
CHROME ={'platform': 'ANY', 'browserName': 'chrome', 'version': '','javascriptEnabled': True}
FIREFOX = {'platform': 'ANY', 'browserName': 'firefox', 'version': '','javascriptEnabled': True}
HTMLUNIT ={'platform': 'ANY', 'browserName': 'htmlunit', 'version': ''}
HTMLUNITWITHJS = {'platform': 'ANY','browserName': 'htmlunit', 'version':'firefox','javascriptEnabled': True}
INTERNETEXPLORER = {'platform': 'WINDOWS','browserName': 'internet explorer', 'version': '','javascriptEnabled': True}
IPAD = {'platform': 'MAC', 'browserName': 'iPad', 'version': '','javascriptEnabled': True}
IPHONE = {'platform': 'MAC', 'browserName': 'iPhone', 'version': '','javascriptEnabled':True}
SAFARI = {'platform': 'ANY', 'browserName': 'safari', 'version': '','javascriptEnabled':True}
PHANTOMJS = {'platform': 'ANY', 'browserName': 'phantomjs', 'version': '','javascriptEnabled': True}
OPERA = {'platform': 'ANY','browserName': 'opera', 'version': '','javascriptEnabled': True}
9.4.2參數化浏覽器執行用例
通過對Desired Capabilities 的分解,浏覽器的配置是由browserName 所對應的值所指定的,那麼實作浏覽器的參數化将變得非常簡單。
在運作腳本之前我們需要先啟動Selenium Server,因為隻對浏覽器進行參數化,是以啟動一個節點即可: > java -jarselenium-server-standalone-2.39.0.jar
Browsers.py
</pre><pre name="code" class="python">#coding=utf-8
fromselenium.webdriver import Remote
fromselenium.webdriver.common.desired_capabilities import DesiredCapabilities
lists=['chrome','firefox','internetexplorer']
for browser inlists:
print browser
driver = Remote(
command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities={'platform': 'ANY',
'browserName':browser,
'version': '',
'javascriptEnabled': True
})
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys(browser)
driver.find_element_by_id("su").click()
driver.close()
建立lists 數組,羅列不同的浏覽器,通過for 循環讀取數組中的浏覽器,傳參給當browserName 做為目前要執行的浏覽器來運作測試用例。
9.4.3 多節點執行用例
在Selenium Grid 原理的小節中,我們示範了如何啟動多個節點,下面來啟動多個節點,使同一個腳本在不同的節點上執行。
在本機打開兩個指令提示符視窗分别啟動一個hub:
C:\selenium>java -jarselenium-server-standalone-2.39.0.jar -role hub
啟動兩個node(節點):
C:\selenium>java-jar selenium-server-standalone-2.39.0.jar -role node -port 5555
C:\selenium>java-jar selenium-server-standalone-2.39.0.jar -role node -port 5556
下面修改腳本使其在不同的節點與浏覽器上運作:host.py:
#coding=utf-8
fromselenium.webdriver import Remote
fromselenium.webdriver.common.desired_capabilities import DesiredCapabilities
lists={ 'http://127.0.0.1:4444/wd/hub':'chrome',
'http://127.0.0.1:5555/wd/hub':'firefox',
'http://127.0.0.1:5556/wd/hub':'internetexplorer'
}
for host,browserin lists.items():
print host,browser
driver = Remote(
command_executor=host,
desired_capabilities={'platform':'ANY',
'browserName':browser,
'version': '',
'javascriptEnabled':True
}
)
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys(browser)
driver.find_element_by_id("su").click()
driver.close()
建立lists 字典,定義不同的主機端口号與浏覽器,通過for 循環讀取字典中的主機與浏覽器給Remote,使腳本執行時調用不同的主機和浏覽器。
啟動遠端node
我們目前啟動的hub 與node 都是在一台主機上。那麼要在其它主機啟動node 必須滿足以下幾個要求:
l 本地hub 主機與遠端node 主機之間可以互相ping 通。
l 遠端主機必須安裝運作腳本的運作環境(Python 、Selenium、浏覽器及浏覽器驅動)。
l 遠端主機必須安裝java 環境,因為需要運作SeleniumServer。
操作步驟如下:
啟動本地hub 主機(本地主機IP 為:172.16.10.66):
C:\selenium>java-jar selenium-server-standalone-2.39.0.jar -role hub
啟動遠端主機(作業系統:Ubuntu ,IP 位址:172.16.10.34):
遠端主機啟動node 方式如下:
$ java -jar selenium-server-standalone-2.39.0ar-role node -port 5555 -hubhttp://172.16.10.66:4444/grid/register
(設定的端口号為:5555 ,指向的hub ip 為172.16.10.66)
修改遠端主機的IP 位址及端口号,在其上面的firefox 浏覽下運作腳本。host.py:
#coding=utf-8
fromselenium.webdriver import Remote
fromselenium.webdriver.common.desired_capabilities import DesiredCapabilities
lists={'http://127.0.0.1:4444/wd/hub':'chrome',
'http://172.16.10.34:5555/wd/hub':'firefox',
'http://127.0.0.1:5556/wd/hub':'internetexplorer'
}
for host,browserin lists.items():
print host,browser
driver = Remote(
command_executor=host,
desired_capabilities={'platform':'ANY',
'browserName':browser,
<span > </span>'version': '',
<span > </span>'javascriptEnabled':True
}
)
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys(browser)
driver.find_element_by_id("su").click()
driver.close()
現在再來運作腳本,你将會在172.16.10.34 主機上看到腳本被執行。
小技巧:
自從使用Selenium Server 執行自動化腳本後,常常會因為忘記啟動Selenium Server 導緻腳本運作報錯。其實我們以在腳本中執行cmd 指令。如在我們建立的all_test.py 檔案中添加:
import os
os.chdir('E:\\selenium')
os.system('java-jar selenium-server-standalone-2.39.0.jar')
這樣就再也不會因為忘記啟動Selenium Server 導緻測試腳本運作失敗了。