Selenium Grid 是 Selenium 的三大組件之一,它可以在多臺機器上并行運行測試肯腕,集中管理不同的瀏覽器版本和瀏覽器配置蔬浙。通過將客戶端命令發(fā)送到遠程瀏覽器的實例, Selenium Grid 允許在遠程計算機 (虛擬或真實) 上執(zhí)行 WebDriver 腳本. 它旨在提供一種在多臺計算機上并行運行測試的簡便方法否纬。
官方文檔:https://www.selenium.dev/
場景一:?實現(xiàn)分布式執(zhí)行測試盖袭,提高執(zhí)行效率
比如:我們有 1000 條用例執(zhí)行,如果在本機執(zhí)行熄诡,一條用例耗時 100 秒,執(zhí)行完成則需要大約 27 小時?1000*100/60/60=27個小時可很。如果讓這些用例并發(fā)執(zhí)行,比如分配 6 臺計算機凰浮,每個計算機執(zhí)行 1000/6 大約 166 條用例我抠,那時間大約節(jié)省了 6 倍,原來需要大約 27 個小時袜茧,現(xiàn)在可能只需要 4.5 個小時左右就基本完成了屿良, 分布式并發(fā)執(zhí)行可以讓我們用例的執(zhí)行總時長指數(shù)級的縮小,從而效率得到很大的提升惫周。
場景二:?解決瀏覽器兼容性問題
比如還是 1000 條用例,需要分別在 Chrome康栈、Firefox递递、Edge喷橙、Safari 這些瀏覽器上都執(zhí)行一遍,保證每個瀏覽器上都能正常執(zhí)行登舞,測試瀏覽器的兼容性贰逾。這時也可以使用 Selenium Grid,通過 Selenium Grid 將這些請求分發(fā)到不同的系統(tǒng)菠秒、不同瀏覽器中執(zhí)行疙剑。這些瀏覽器可以分別布署在不同的計算機中比如可以布署在 Linux 、Windows践叠、Mac 上都可以言缤,作為它的 Node 結(jié)點,從而解決兼容性測試的問題
Selenium Grid 4 是一個全新的工具禁灼,它能夠支持完全分布式的測試管挟。Selenium Grid4 也兼容了之前 Selenium Grid3 的工作模式,在 Selenium Grid3 的基礎(chǔ)上又添加了一些新的通訊方式弄捕,使它通訊速度更快僻孝。另外現(xiàn)在很多公司都支持容器化部署,Selenium Grid 4 也提供了的 Docker 支持守谓。相比 Selenium Grid 3穿铆,Selenium Grid 4 更容易在虛擬機上使用。
Selenium Grid4 有三個新特性
特性一:Hub 和 Node 使用同一個 jar 服務(wù)斋荞。
特性二:架構(gòu)優(yōu)化荞雏,在 Selenium Grid 4 版本的全新架構(gòu)中劃分成了組件:Router、Distributor譬猫、Node讯檐、Session Map、Session Queue染服、Event Bus别洪。
特性三:支持不同的運行模式,Selenium 4 支持三種網(wǎng)格類型柳刮,包括 Standalone Mode 獨立模式挖垛、Classical Grid 經(jīng)典網(wǎng)格模式、Fully Distributed 完全分布式
下面這張圖是官方提供的 Selenium Grid4 的工作原理圖:
image1080×646 59.2 KB
從圖中可以看到 Selenium Grid 包括六大組件秉颗,分別是:
Router 路由器
Distributor 分發(fā)服務(wù)器
Session Map 會話映射
Node 測試節(jié)點
New Session Queue 新的會話隊列
Event Bus 事件總線
下面分別說一下這六個組件所負責的職責:
Router 路由器:Router 是所有組件的入口痢毒,所有向服務(wù)器發(fā)送的外部請求第一個會經(jīng)常 Router 組件。
Distributor 分發(fā)服務(wù)器:它有兩個主要的功能蚕甥,第一個功能哪替,注冊并跟蹤所有 Node 節(jié)點,第二個功能就是查詢新會話隊列并處理掛起的新會話請求菇怀。當一個新的請求到達 Router 時凭舶,它會被轉(zhuǎn)發(fā)到 New Session Queue晌块,在隊列中等待。分發(fā)服務(wù)器會輪詢新會話隊列查找掛起的新會話請求帅霜,為這個請求找到匹配的節(jié)點之后匆背,會創(chuàng)建一個新的會話,這個會話的 ID 以及 URI 會存儲在 Session Map 中身冀。
Session Map 會話映射:它是一個數(shù)據(jù)存儲區(qū)钝尸,它存儲了會話 ID 與對應(yīng)的會話結(jié)點的關(guān)系,在 Router 轉(zhuǎn)發(fā)請求到對應(yīng)的結(jié)點時搂根,要先在 Session Map 中查看對應(yīng)的關(guān)系珍促,再進行請求。
Node 測試節(jié)點:結(jié)點有多個兄墅,每個結(jié)點管理多個可用的瀏覽器的插槽踢星,結(jié)點只負責執(zhí)行命令,不需要做出其它的判斷隙咸。這個 Node 可以配置在 Windows沐悦、Mac、Linux 等任何系統(tǒng)上五督。
New Session Queue 新的會話隊列:從 Router 發(fā)過來的請求藏否,它會先放到這個隊列中, 等待被分發(fā)服務(wù)器分發(fā)出去充包,這個隊列有一些特殊的功能副签,它能夠定期的檢查會話是否超時,如果超時基矮,請求將被拒絕并立即刪除淆储。這里可以配置一些參數(shù)來處理超時時長等參數(shù)。
Event Bus 事件總線:充當了節(jié)點家浇、分發(fā)服務(wù)器本砰、新會話隊列和會話映射之間的通信路徑,使用了 socket 通信钢悲。在完全分布式模式下啟動 selenium grid 時点额,事件總線會是第一個被啟動起來的組件。
Java11 及以上版本莺琳。
下載被測試的瀏覽器(Chrome/Firefox/Edge/Safari 等)还棱。
配置環(huán)境變量,將對應(yīng)的 driver 提前下載下來配置到環(huán)境變量中惭等≌涫郑或者將下載的 driver 放在與 selenium server 的 jar 包同級目錄下也可以。
Selenium Server 下載,建議使用 4.4.0 版本琳要。
命令行 cd 到當前下載 jar 包的路徑下
cdDesktop
java -jar 啟動對應(yīng)的 jar 包:java -jar selenium-server-<version>.jar standalone
java-jar selenium-server-4.4.0.jar standalone
啟動成功后料扰,對應(yīng)命令行顯示:Started Selenium Standalone ...,如圖
image1080×209 75.2 KB
查看 UI 界面 > 瀏覽器輸入網(wǎng)址查看 UI 界面:UI 鏈接
image1080×563 40.9 KB
查看 Grid status 狀態(tài) > 瀏覽器輸入網(wǎng)址查看 status 狀態(tài):Status 狀態(tài)
image1080×1008 129 KB
直接運行代碼焙蹭,發(fā)現(xiàn)在本地運行單線程,只不過通過 Selenium Grid 來轉(zhuǎn)發(fā)請求嫂伞。
SeleniumGrid 會創(chuàng)建一個 Queue 隊列孔厉,里面包含了啟動的參數(shù)代碼:
image1080×261 7.31 KB
SeleniumGrid 創(chuàng)建一個本地的 session,然后再打開瀏覽器運行測試用例:
image1080×288 32.6 KB
示例代碼如下:
"""
@Author: 霍格沃茲測試開發(fā)學(xué)社-西西
@Desc: '更多測試開發(fā)技術(shù)探討帖努,請訪問:https://ceshiren.com/t/topic/15860'
"""fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByclassTestSingleNode:defsetup_method(self):# 創(chuàng)建Options ,新版本DesireCapability已棄用options = webdriver.EdgeOptions()# 通過URL和options 創(chuàng)建一個遠程的連接# client 發(fā)送請求撰豺,要發(fā)送給selenium grid hub 結(jié)點, hub 結(jié)點會將請求分發(fā)到對應(yīng)的nodeself.driver = webdriver.Remote(? ? ? ? ? ? command_executor='http://10.1.1.104:4444',? ? ? ? ? ? options=options? ? ? ? )deftest_singlenode1(self):# 打開 baidu 頁self.driver.get("http://www.baidu.com")# 向輸入框中輸入self.driver.find_element(By.ID,'kw').send_keys("firefox")# 點擊搜索框self.driver.find_element(By.ID,'su').click()# 等待一秒sleep(1)# 斷言輸入內(nèi)容在頁面中assert"firefox"inself.driver.page_sourcedefteardown_method(self):self.driver.quit()
創(chuàng)建測試文件?test_multi_node.py?示例代碼如下:
fromtimeimportsleepfromseleniumimportwebdriverfromselenium.webdriver.common.byimportByclassTestMultiNode:defsetup_method(self):options = webdriver.ChromeOptions()? ? ? ? self.driver = webdriver.Remote(? ? ? ? ? ? command_executor='http://10.1.1.104:4444',? ? ? ? ? ? options=options? ? ? ? )deftest_multinode1(self):# 打開 baidu 頁self.driver.get("http://www.baidu.com")# 向輸入框中輸入self.driver.find_element(By.ID,'kw').send_keys("selenium")# 點擊搜索框self.driver.find_element(By.ID,'su').click()# 等待一秒sleep(1)# 斷言輸入內(nèi)容在頁面中assert"selenium"inself.driver.page_sourcedeftest_multinode2(self):# 打開 baidu 頁self.driver.get("http://www.baidu.com")# 向輸入框中輸入self.driver.find_element(By.ID,'kw').send_keys("appium")# 點擊搜索框self.driver.find_element(By.ID,'su').click()# 等待一秒sleep(1)# 斷言輸入內(nèi)容在頁面中assert"appium"inself.driver.page_sourcedeftest_multinode3(self):# 打開 baidu 頁self.driver.get("http://www.baidu.com")# 向輸入框中輸入self.driver.find_element(By.ID,'kw').send_keys("pytest")# 點擊搜索框self.driver.find_element(By.ID,'su').click()# 等待一秒sleep(1)# 斷言輸入內(nèi)容在頁面中assert"pytest"inself.driver.page_sourcedeftest_multinode4(self):# 打開 baidu 頁self.driver.get("http://www.baidu.com")# 向輸入框中輸入self.driver.find_element(By.ID,'kw').send_keys("requests")# 點擊搜索框self.driver.find_element(By.ID,'su').click()# 等待一秒sleep(1)# 斷言輸入內(nèi)容在頁面中assert"requests"inself.driver.page_sourcedeftest_multinode5(self):# 打開 baidu 頁self.driver.get("http://www.baidu.com")# 向輸入框中輸入self.driver.find_element(By.ID,'kw').send_keys("java")# 點擊搜索框self.driver.find_element(By.ID,'su').click()# 等待一秒sleep(1)# 斷言輸入內(nèi)容在頁面中assert"java"inself.driver.page_sourcedefteardown_method(self):self.driver.quit()
為了模擬多瀏覽器并發(fā)運行拼余,使用 pytest 的插件?pytest-xdist?實現(xiàn)分布式并發(fā)執(zhí)行方式污桦,提前安裝?pytest-xdist?插件,然后使用命令執(zhí)行用例匙监。打開命令提示行或者終端凡橱,使用cd?命令進入到文件所在路徑,然后執(zhí)行?pytest test_multi_node.py -n 3 --alluredir ./results命令亭姥。執(zhí)行完用例之后稼钩,會把測試報告結(jié)果統(tǒng)一匯總到results?目錄中。
命令行 cd 到當前下載 jar 包的路徑下
cdDesktop
java -jar 以 Hub 啟動對應(yīng)的 jar 包:java -jar selenium-server-<version>.jar hub
java-jar selenium-server-4.4.0.jar hub
此時达罗,啟動了 Router,Distributor,Session Map,New Session Queue,Event Bus坝撑;雖然,已經(jīng)有了對應(yīng)集線器粮揉,但是還沒有 node 節(jié)點注冊進來巡李。
如果不把節(jié)點 Node 注冊進來,對應(yīng)的集線器無法知道哪個物理機器可以被分發(fā)請求扶认,對應(yīng)的 Router 就無法把測試用例進行分發(fā)侨拦。
查看狀態(tài)的 UI 界面:
同一機器上啟動 node:java -jar selenium-server-<version>.jar node --detect-drivers true
java-jar selenium-server-4.4.0.jar node --detect-drivers true
此時 node 節(jié)點創(chuàng)建成功,并且 hub 上注冊對應(yīng) node 節(jié)點:
健康檢測就是每隔 2 分鐘會 ping 一下對應(yīng) URL 看看是否可以 ping 成功蝠引,對應(yīng)是否處于活動狀態(tài)
再次查看狀態(tài)的 UI 界面:
直接運行代碼阳谍,發(fā)現(xiàn)在本地運行單線程,只不過通過 Selenium Grid 來轉(zhuǎn)發(fā)請求螃概。
在經(jīng)典網(wǎng)格模式等基礎(chǔ)上再在其他機器上啟動一個 node 角色矫夯。
不同機器上啟動 node:java -jar selenium-server-<version>.jar node --detect-drivers true --publish-events tcp://<ip> --subscribe-events tcp://<ip>
java-jar selenium-server-4.4.0.jar node --detect-drivers true --publish-events tcp://10.1.1.178:4442--subscribe-events tcp://10.1.1.178:4443
此時 node 節(jié)點創(chuàng)建成功,并且在遠端 hub 上注冊對應(yīng) node 節(jié)點
查看狀態(tài)的 UI 界面:
注意
:不同機器上啟動的時候需要安裝相同版本的 jar 及根據(jù)機器上的瀏覽器下載對應(yīng)的 driver
使用代碼運行時會發(fā)現(xiàn)對應(yīng)分發(fā)時會分給不同的系統(tǒng)運行代碼吊洼,如圖: