當我們編寫(xiě)完 Selenium 測試用例在本地調試時(shí),WebDriver 通過(guò)瀏覽器驅動(dòng)直接與瀏覽器進(jìn)行交互。這時(shí),WebDriver、瀏覽器驅動(dòng)和瀏覽器位于同一主機。這種最基本的交互方式如下圖所示。
本地調試完成,使用自動(dòng)化流水線(xiàn)觸發(fā)執行測試用例時(shí),一般不會(huì )使用上述這種 WebDriver 與瀏覽器(驅動(dòng))直接交互的方式,而會(huì )選擇遠程交互的方式。
遠程交互方式是指 WebDriver 通過(guò) Grid(Selenium Server)來(lái)與瀏覽器(驅動(dòng))遠程交互。這時(shí),Grid 可以不與瀏覽器及其驅動(dòng)位于同一主機,測試代碼及 WebDriver 也可以不與 Grid 或瀏覽器位于同一主機。這種遠程交互的方式如下圖所示。
可以看到,使用 Grid 以后,測試用例只需知道 Grid 的地址即可,無(wú)需安裝瀏覽器及驅動(dòng),使得測試用例的執行變得非常簡(jiǎn)單。
本文主要關(guān)注 Grid 的搭建及使用。接下來(lái),主要有如下幾個(gè)部分。
·引入一段測試代碼,使用本地直接交互的方式來(lái)執行。
· 使用原始jar文件的方式搭建 Grid 環(huán)境,并執行測試代碼。
· 使用 Docker 鏡像的方式搭建 Grid 環(huán)境。
· 使用 Kubernetes 描述文件的方式搭建 Grid 環(huán)境。
1 測試代碼
如下是一段使用 Python 編寫(xiě)的 Selenium 測試代碼。是針對 Github 搜索功能的一個(gè)簡(jiǎn)單測試場(chǎng)景。
有下面幾個(gè)步驟:
· 打開(kāi) GitHub 首頁(yè);
· 在搜索框鍵入關(guān)鍵字Selenium,并回車(chē);
· 點(diǎn)擊第一個(gè)搜索結果,并等待倉庫首頁(yè)打開(kāi);
· 斷言倉庫首頁(yè)標題包含關(guān)鍵字Selenium。
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class GithubTestCase(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Chrome()
self.addCleanup(self.browser.quit)
def test_search(self):
# 打開(kāi) GitHub 首頁(yè)
self.browser.get('https://github.com/')
# 在搜索框鍵入關(guān)鍵字 Selenium,并回車(chē)
search_box_elem = self.browser.find_element(By.XPATH, '//input[@name="q"]')
search_box_elem.send_keys('Selenium' + Keys.RETURN)
# 點(diǎn)擊第一個(gè)搜索結果
first_result_elem = self.browser.find_element(By.XPATH, '//ul[@class="repo-list"]/li//div[@class="d-flex"]//a')
first_result_elem.click()
# 等待 Code Tab 頁(yè)出現,即倉庫首頁(yè)打開(kāi)
WebDriverWait(self.browser, 10).until(EC.presence_of_element_located((By.ID, 'code-tab')))
# 斷言倉庫首頁(yè)標題包含 Selenium
self.assertIn('Selenium', self.browser.title)
if '__main__' == __name__:
unittest.main(verbosity=2)
如上測試代碼使用的是 WebDriver 與瀏覽器(驅動(dòng))直接交互的方式。
運行該代碼前需要在本地安裝有 Chrome 瀏覽器及 ChromeDriver(從 chromium.org 下載 Chrome 對應的驅動(dòng)并解壓至指定目錄,并將安裝目錄添加至系統環(huán)境變量),測試代碼會(huì )驅動(dòng)本地瀏覽器執行完指定步驟后打印成功的信息。
2 使用 jar 文件的方式搭建 Grid
Grid jar 文件依賴(lài)的 Java 版本為 11 或以上。
欲使用 Grid,Standalone 模式是最簡(jiǎn)單快速的一種。
可以從 github.com/SeleniumHQ/… 發(fā)布頁(yè)面下載最新的selenium-server-<version>.jar文件,然后使用如下命令啟動(dòng):
java -jar selenium-server-<version>.jar standalone
Grid 啟動(dòng)完成后,打開(kāi)網(wǎng)址http://localhost:4444可以看到可使用的所有瀏覽器類(lèi)型以及會(huì )話(huà)的狀態(tài)。
接著(zhù),對測試代碼稍作修改(獲取browser的方式替換為如下寫(xiě)法)即可成功運行。
self.browser = webdriver.Remote(
command_executor='http://localhost:4444',
options=webdriver.ChromeOptions()
)
而要想更好的使用 Grid,需要了解其里邊的幾個(gè)角色。
·Hub:負責將從 WebDriver 接收的瀏覽器操作指令分發(fā)至對應的 Node,并將從 Node 接收的結果返回給 WebDriver。
· Node:負責接收來(lái)自 Hub 的指令,并調用瀏覽器驅動(dòng)來(lái)完成頁(yè)面操作。
Hub 與 Node 可位于不同的主機,通過(guò) HTTP 協(xié)議來(lái)通信。
使用 Hub 與 Node 分工的方式來(lái)啟動(dòng) Grid 的命令如下:
# 啟動(dòng) Hub
java -jar selenium-server-<version>.jar hub
# 啟動(dòng) Node 1
java -jar selenium-server-<version>.jar node --port 5555
# 啟動(dòng) Node 2
java -jar selenium-server-<version>.jar node --port 6666
啟動(dòng)完成后,從網(wǎng)址http://localhost:4444可以看到有兩個(gè)可以使用的 Node。
測試代碼使用 Grid 的方式不會(huì )因此發(fā)生變化,仍指向http://localhost:4444即可。
3 使用 Docker 鏡像的方式搭建 Grid
使用 Docker 快速啟動(dòng)一個(gè) Standalone 模式 Grid 的命令如下:
# 啟動(dòng)一個(gè) Chrome Standalone Grid
docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" selenium/standalone-chrome:4.4.0
打開(kāi)http://localhost:4444同樣可以看到控制臺頁(yè)面。
新版 Grid 另一個(gè)非常便捷的功能是,直接在瀏覽器打開(kāi)http://localhost:7900(密碼為secret)即可看到運行測試的桌面。
測試代碼同樣只需將 RemoteWebDriver 地址指向http://localhost:4444即可運行。
使用 Hub 與 Node 分工的方式啟動(dòng) Grid 的 Docker 命令如下:
# 創(chuàng )建網(wǎng)絡(luò )
docker network create grid
# 啟動(dòng) Hub
docker run -d -p 4442-4444:4442-4444 --net grid --name selenium-hub selenium/hub:4.4.0
# 啟動(dòng)一個(gè) Chrome Node
docker run -d -p 7900:7900 --net grid -e SE_EVENT_BUS_HOST=selenium-hub \
--shm-size="2g" \
-e SE_EVENT_BUS_PUBLISH_PORT=4442 \
-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
selenium/node-chrome:4.4.0
還可以按需添加別的瀏覽器 Node,如下命令添加了 Edge 和 Firefox Node。
# 添加一個(gè) Edge Node
docker run -d -p 7901:7900 --net grid -e SE_EVENT_BUS_HOST=selenium-hub \
--shm-size="2g" \
-e SE_EVENT_BUS_PUBLISH_PORT=4442 \
-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
selenium/node-edge:4.4.0
# 添加一個(gè) Firefox Node
docker run -d -p 7902:7900 --net grid -e SE_EVENT_BUS_HOST=selenium-hub \
--shm-size="2g" \
-e SE_EVENT_BUS_PUBLISH_PORT=4442 \
-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
selenium/node-firefox:4.4.0
這就是 Grid 的威力所在,其提供一個(gè)瀏覽器池,測試項目只需指向 Grid 地址即可使用所需的瀏覽器,非常的方便。
想查看瀏覽器運行桌面,直接訪(fǎng)問(wèn)http://localhost:7900(Chrome)、http://localhost:7901(Edge)或http://localhost:7902(Firefox)即可。
另外一種傳統的查看瀏覽器運行桌面的方式是 VNC。VNC 是一種遠程桌面顯示技術(shù),有服務(wù)端和客戶(hù)端兩部分組成。Grid 的各 Node 鏡像開(kāi)放了5900端口來(lái)提供 VNC 服務(wù)。我們想使用這種方式查看 Node 內部的桌面,需要下載一個(gè) VNC Client。
本文使用的 VNC Client 為 VNC Viewer。從 VNC Viewer 下載頁(yè) 下載并安裝好 VNC Viewer 后。
使用如下命令再啟動(dòng)一個(gè) Chrome Node,并開(kāi)放5900端口:
docker run -d -p 5900:5900 --net grid -e SE_EVENT_BUS_HOST=selenium-hub \
--shm-size="2g" \
-e SE_EVENT_BUS_PUBLISH_PORT=4442 \
-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
selenium/node-chrome:4.4.0
打開(kāi) VNC Viewer,鍵入localhost:5900后回車(chē),輸入密碼(secret)后即可看到 Chrome Node 的桌面。
4 使用 Kubernetes 描述文件的方式搭建 Grid
擁有 Kubernetes 環(huán)境的話(huà),在 Kubernetes 搭建好 Grid,會(huì )變得非常實(shí)用。這樣,從 Kubernetes Ingress 暴露 Grid 的 URL 出來(lái),可以供團隊內的任何測試項目使用。自動(dòng)化流水線(xiàn)的測試階段也變得簡(jiǎn)單,無(wú)需準備測試用例運行環(huán)境,直接指向 Grid 的 URL 即可。
本文基于 Docker Desktop 自帶的 Kubernetes 環(huán)境,基于官方提供的 Kubernetes 描述文件 稍作改動(dòng)來(lái)搭建一個(gè) Selenium Hub/Node 環(huán)境(修改后的 K8s Yaml 文件已整理至我的 個(gè)人 GitHub 倉庫),然后開(kāi)放 Grid Hub 的 URL 出來(lái)供測試項目使用,再開(kāi)放一個(gè) Chrome Node 的桌面 URL 出來(lái)供測試人員查看。
應用 Selenium Hub/Node Deployment及Service 描述文件。
kubectl apply -f selenium-hub-deployment.yaml
kubectl apply -f selenium-node-chrome-deployment.yaml
kubectl apply -f selenium-hub-service.yaml
kubectl apply -f selenium-node-chrome-service.yaml
暴露 Selenium Hub:
kubectl expose deployment selenium-hub --name=selenium-hub-external --labels="app=selenium-hub,external=true" --type=LoadBalancer
暴露 Selenium Chrome Node:
kubectl expose deployment selenium-node-chrome --name=selenium-node-chrome-external --labels="app=selenium-hub,external=true" --type=LoadBalancer
這樣,在本地訪(fǎng)問(wèn)http://localhost:4444和http://localhost:7900就可以分別看到 Selenium 控制臺和 Chrome Node 桌面。
同樣可以使用 VNC 的方式訪(fǎng)問(wèn)位于 Kubernetes 內瀏覽器 Node 的桌面。
使用如下命令將 Chrome Pod 的 5900 端口轉發(fā)到本地:
PODNAME=`kubectl get pods --selector="app=selenium-node-chrome" --output=template --template="{{with index .items 0}}{{.metadata.name}}{{end}}"`
kubectl port-forward $PODNAME 5900:5900
這樣,使用 VNC Viewer 訪(fǎng)問(wèn)localhost:5900即可看到 Chrome Node 所在的桌面。
綜上,我們引入一段 Selenium 測試代碼,分別使用jar文件方式、Docker 鏡像方式和 Kubernetes 描述文件方式搭建了 Selenium Grid,并介紹了使用方法;還說(shuō)明了在各種環(huán)境下瀏覽器運行桌面的查看方式。為使用 Selenium 的朋友在本地調試或實(shí)際測試場(chǎng)景中的環(huán)境準備上提供了參考經(jīng)驗。
本文內容不用于商業(yè)目的,如涉及知識產(chǎn)權問(wèn)題,請權利人聯(lián)系51Testing小編(021-64471599-8017),我們將立即處理