什么是selenium Grid
① Selenium Grid 是Selenium套件的一部分,它專門用於並行運行多個測試用例在不同的瀏覽器、操作系統和機器上。
② Selenium Grid 主要使用 master-slaves 或者 hub-nodes 理念 :一個 master/hub 和多個基於 master/hub 注冊的子節點 slaves/nodes 。
當我們在master上基於不同的瀏覽器/系統運行測試用例時,master將會將測試用例分發給適當的node運行。(當然也可以作為兼容性測試工具將測試用例運行在不同的web瀏覽器上)
③
④ selenium Grid 主要的作用:實現分布式執行測試,解決瀏覽器兼容性問題。【通過 Selenium Grid 的可以控制多台機器多個瀏覽器執行測試用例,分布式上執行的環境在 Selenium Grid 中稱為node節點。】
⑤舉例:
當自動化測試用例達到一定數量的時候,比如上萬,一台機器執行全部測試用例耗時5個小時(只是舉例,真正的耗時是需要根據測試用例場景的復雜度決定的),而如果需要覆蓋主流瀏覽器比如Chrome、Firefox,加起來就是10個小時;這時候領導跟你說有什么辦法可以解決這個執行速度?當然最笨的辦法就是另外拿台機器,然后部署環境,把測試用例分開去執行然后合並結果即可。而Selenium也想到了這點,所以有了Selenium Grid的出現,它就是解決分布式執行測試的痛點。
⑥總結:
- Slenium Grid 分布式測試由hub主節點和node節點組成
- Hub節點用來管理node節點注冊信息。
- 腳本——》Hub節點——》node節點——》瀏覽器
什么時候用Selenium Grid
①同時在不同的瀏覽器、操作系統和機器上運行測試。最大程度用於兼容性測試。
②減少測試用例的運行時間。
Selenium Grid工作原理
① Selenium Grid 實際它是基於Selenium RC的,而所謂的分布式結構就是由一個hub節點和若干個node代理節點組成。
②Hub節點用來管理各個代理節點的注冊信息和狀態信息,並且接受遠程客戶端代碼的請求調用,然后把請求的命令轉發給代理節點來執行。
如何啟動Selenium Grid
啟動 Selenium Grid 有三種方式:一種直接用命令行方式;另一種用JSON
配置文件;最后一種docker
啟動。
首先需要下載:selenium-server-standalone-3.9.1.jar【可以理解為搭建selenium Grid環境】
下載地址:http://selenium-release.storage.googleapis.com/index.html
1、命令行方式啟動 selenium Grid
①進入selenium-server-standalone-3.9.1.jar文件所在的目錄位置。
②進入cmd命令行終端中。
③啟動Hub,命令如下:
java -jar selenium-server-standalone-3.9.1.jar -role hub -maxSession 10 -port 4444
運行結果如下圖:
命令參數解析:
- - role :此參數后跟hub或者node;表示此機器啟動hub節點或者node子節點;
- - port :此參數后跟端口號;設置啟動hub或者node節點服務的端口號;hub的默認端口是4444;這里使用的是默認的端口,當然可以自己配置;
- - maxSession :此參數后跟最大會話請求數;最大會話請求,這個參數主要用於並發執行測試用例,默認是1,建議設置10及以上。
④瀏覽器打開地址:http://localhost:4444/grid/console,出現如下圖表示hub節點啟動成功。
⑤啟動node節點【啟動hub節點后最少需要一個node節點,不然啟動hub節點就沒有意義】
而node節點同樣可以與hub節點在同一台機器上運行,如下例就是hub節點與node節點同機的例子。
hub機 |
ip:10.200.145.226 |
node1機 |
ip:10.200.145.226 |
命令行:
java -jar selenium-server-standalone-3.9.1.jar -role node -port 6666 -hub http://10.200.145.226:4444/grid/register/ -maxSession 5 -browser browserName=chrome,seleniumProtocol=WebDriver,maxInstances=5,platform=WINDOWS,version=96.0
運行結果如下圖:
命令參數解析:
- -role node :表示啟動的是node節點
- -port 5555 :指定node節點端口
- - browser :啟動的node節點服務設置瀏覽器參數信息
- browsderName=chrome :瀏覽器的名稱
- seleniumProtocol=WebDriver :selenium工具的實現協議
- maxInstances=5 :最大實例(該node節點上最多可運行的瀏覽器數),該值不能大於前面開啟hub節點服務時 maxSession 參數的值
- platform=WINDOWS :表示操作系統。
- version=96.0 :表示瀏覽器版本。
- Dwebdriver.chrome.driver=chromedriver.exe :瀏覽器驅動,如果是其他瀏覽器就寫對應的瀏覽器驅動的名字;如火狐瀏覽器: Dwebdriver.firefox.driver=geckodriver.exe
- - hub :此參數后面跟開啟hub節點時生成的Nodes節點應該連接的地址,表示需要連接的hub機地址
⑥瀏覽器重新打開地址:http://localhost:4444/grid/console,如出現下圖則表示node節點服務啟動成功:
【注意】如果使用的chromedriver.exe與selenium-server-standalone-3.9.1.jar版本或者瀏覽器chrome版本不匹配都會報錯提示,具體原因需要具體解決。
2、Json配置文件啟動 selenium Grid
①創建hub的Json配置文件。
代碼如下:將下述代碼保存為 hub_config.json 文件,放在hub節點機器的與selenium server(即selenium-server-standalone-3.9.1.jar)相同的路徑下。
{ "port": 4444, "newSessionWaitTimeout": -1, "servlets" : [], "withoutServlets": [], "custom": {}, "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", "registry": "org.openqa.grid.internal.DefaultGridRegistry", "throwOnCapabilityNotPresent": true, "cleanUpCycle": 5000, "role": "hub", "debug": false, "browserTimeout": 0, "timeout": 1800 }
②創建nodes的Json配置文件。
代碼如下:保存為 node_config.json 文件(注意將hub對應的值改為node節點機器的IP地主),放在node節點上和selenium server相同的路徑下。(當多個node時需將該文件放在多個node機器上或者同一個機器上啟動多個node)
{ "capabilities": [ { "browserName": "firefox", "marionette": true, "maxInstances": 5, "seleniumProtocol": "WebDriver" }, { "browserName": "chrome", "maxInstances": 5, "seleniumProtocol": "WebDriver" }, { "browserName": "internet explorer", "platform": "WINDOWS", "maxInstances": 1, "seleniumProtocol": "WebDriver" }, { "browserName": "safari", "technologyPreview": false, "platform": "MAC", "maxInstances": 1, "seleniumProtocol": "WebDriver" } ], "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", "maxSession": 5, "port": -1, "register": true, "registerCycle": 5000, "hub": "http://192.168.1.100:4444", "nodeStatusCheckTimeout": 5000, "nodePolling": 5000, "role": "node", "unregisterIfStillDownAfter": 60000, "downPollingLimit": 2, "debug": false, "servlets" : [], "withoutServlets": [], "custom": {} }
③
hub機器上命令行運行: java -jar selenium-server-standalone-3.141.59.jar -role hub -hubConfig hub_config.json
node機器上命令行運行: java -jar selenium-server-standalone-3.141.59.jar -role node -nodeConfig node_config.json
【注意】命令行方式啟動 selenium Grid、Json配置文件啟動 selenium Grid 兩種方式的缺點:不易啟動和維護
- 每個node需要下載和配置依賴
- java 進程占內存
- 出現問題時需手動啟動
- 不易維護
- 擴展性差
3、docker啟動 selenium Grid
docker簡介
- https://docs.docker.com/docker-hub/
- https://yeasy.gitbooks.io/docker_practice/appendix/repo/mysql.html
- https://docker-curriculum.com/
- https://towardsdatascience.com/learn-enough-docker-to-be-useful-1c40ea269fa8
docker啟動 Selenium Grid
docker上已經有selenium官方的Selenium Grid鏡像,只有你已經安裝了docker,即可使用。
- 啟動hub:docker run -d -p 4444:4444 --name selenium-hub selenium/hub
- 啟動node(Chrome&&Firefox):
- docker run -d --link selenium-hub:hub selenium/node-chrome
- docker run -d --link selenium-hub:hub selenium/node-firefox
運行命令將會下載內置鏡像文件(包括java、Chrome、Firefox、selenium-server-standalone-XXX.jar 等運行selenium所需的環境);此時你可以訪問:http://localhost:4444/grid/console
如果需要多個Chrome node則繼續運行這個命令: docker run -d --link selenium-hub:hub selenium/node-chrome ,刷新則看到多了一個Chrome實例。
通過運行命令: docker ps ,顯示正在運行的容器:
docker 組件啟動 Selenium Grid
①selenium Grid
通常需要啟動一個hub,多個nodes像Chrome、Firefox等。我們可以把他們定義到一個文件中叫做 docker-compose.yml ,通過一個命令來整體啟動,docker提供了一個這樣的工具 –Docker-Compose
。
②安裝docker-compose
,一旦安裝成功,則創建一個新的文件夾,創建文件 docker-compose.yml , docker-compose.yml 內容:
version: "3" services: selenium-hub: image: selenium/hub container_name: selenium-hub ports: - "4444:4444" chrome: image: selenium/node-chrome depends_on: - selenium-hub environment: - HUB_PORT_4444_TCP_ADDR=selenium-hub - HUB_PORT_4444_TCP_PORT=4444 firefox: image: selenium/node-firefox depends_on: - selenium-hub environment: - HUB_PORT_4444_TCP_ADDR=selenium-hub - HUB_PORT_4444_TCP_PORT=4444
docker-compose命令:
- 運行命令啟動(到
docker-compose.yml
路徑下):docker-compose up -d
- 查看啟動是否成功:
docker-compose ps
- 創建更多實例:
docker-compose scale chrome=5
- 關閉命令:
docker-compose down
瀏覽器打開http://localhost:4444/grid/console將會看到:
運行腳本的話直接運行就好(IP:http://localhost:4444/wd/hub) ,和上邊兩種的方法不太一樣;不會有瀏覽器打開(容器內部運行),但是已經運行成功:
import unittest from selenium import webdriver class MyTestCase(unittest.TestCase): def setUp(self): ds = {'platform': 'ANY', 'browserName': "chrome", 'version': '', 'javascriptEnabled': True } self.dr = webdriver.Remote('http://localhost:4444/wd/hub', desired_capabilities=ds) def test_something(self): self.dr.get("https://www.baidu.com") self.assertEqual(self.dr.name, "chrome") def test_search_button(self): self.dr.get("https://www.baidu.com") self.assertTrue(self.dr.find_element_by_id("su").is_displayed()) def tearDown(self): self.dr.quit() if __name__ == '__main__': unittest.main()
Selenium Grid 腳本執行(在node節點機器上執行)
單node節點單瀏覽器執行代碼腳本:
import time from selenium import webdriver from selenium.webdriver.common.by import By cap = dict(browserName="chrome", version="96.0", platform="WINDOWS") # 初始化連接 driver = webdriver.Remote('http://10.200.145.226:4444/wd/hub', desired_capabilities=cap) driver.get("https://www.baidu.com/") driver.find_element(By.ID, "kw").send_keys("selenium grid") print(driver.title) time.sleep(2) driver.quit()
單node節點多瀏覽器並行執行代碼腳本:
import threading import time from selenium import webdriver from selenium.webdriver.common.by import By def task(driver): driver.get("https://www.baidu.com/") driver.find_element(By.ID, "kw").send_keys("selenium grid") time.sleep(2) driver.quit() def getDrivder(browser): # 瀏覽器描述 cap = None # 判斷瀏覽器種類 if browser == "chrome": cap = webdriver.DesiredCapabilities.CHROME.copy() # 該類封裝了各個瀏覽器的運行參數 elif browser == "firefox": cap = webdriver.DesiredCapabilities.FIREFOX.copy() # 重構瀏覽器描述 cap["platform"] = "WINDOWS" # 返回驅動對象 return webdriver.Remote('http://10.200.145.226:6666/wd/hub', desired_capabilities=cap) if __name__ == '__main__': browsers = ("chrome", "firefox") for b in browsers: # 獲取驅動 driver = getDrivder(b) # 創建線程執行任務 threading.Thread(target=task, args=(driver,)).start()