用途
Selenium Grid可以讓一個測試在不同機器上的瀏覽器執行測試
一個測試發到Hub,然後發給適合的Node執行。每個Node可以是不同作業系統、不同瀏覽器,瀏覽器也可以是不同版本
組件
先了解WebDriver session定義,再看組件會比較清楚~ W3C的文件中,寫道下面這句:
A WebDriver session represents the connection between a local end and a specific remote end.(https://w3c.github.io/webdriver/#dfn-session) 用中文簡單來說,就是本地端和特定遠端之間的連接
Selenium Grid擁有六種組件:
- Node:執行session,一個grid可有多個nodes,每個node可以是不同的作業系統
- Session Queue:以queue的形式維護session
- Distributor:將session分配給合適的Node執行
- Session Map:紀錄session id和Node的關係
- Event Bus:負責以上四種組件的溝通
- Router:接收所有請求並發給組件
當Router收到一個新的session request,它將被轉發到Session Queue
之後Distributor會從Session Queue取得session然後發給適合的Node執行,然後在Session Map紀錄sessionID和執行的Node
如果是已存在的session,Router會查詢Session Map取得正在運行session的Node ID,然後將request直接轉發到 Node,不會再轉給Session Queue。
Grid Roles
有三種不同的部屬方式,可以根據自身的需要選擇合適的方式
- Standalone:全部組件在同一台機器
- Hub and Node:除了Node,其餘組件組成Hub,Hub和Node各自啟動,可以是不同機器
- Distributed:每個組件各自啟動,可以是不同機器
使用Docker啟動Selenium grid
開發環境非常適合使用Docker啟動環境,這個Docker Selenuim可以非常方便的用compose.yaml一次啟動Hub和多個不同瀏覽器的Node
compose.yaml
1version: "3"
2services:
3 chrome:
4 image: selenium/node-chrome:latest
5 shm_size: 2gb
6 depends_on:
7 - selenium-hub
8 environment:
9 - SE_EVENT_BUS_HOST=selenium-hub
10 - SE_EVENT_BUS_PUBLISH_PORT=4442
11 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
12 ports:
13 - 7900:7900
14
15 edge:
16 image: selenium/node-edge:latest
17 shm_size: 2gb
18 depends_on:
19 - selenium-hub
20 environment:
21 - SE_EVENT_BUS_HOST=selenium-hub
22 - SE_EVENT_BUS_PUBLISH_PORT=4442
23 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
24 ports:
25 - 7901:7900
26
27 firefox:
28 image: selenium/node-firefox:latest
29 shm_size: 2gb
30 depends_on:
31 - selenium-hub
32 environment:
33 - SE_EVENT_BUS_HOST=selenium-hub
34 - SE_EVENT_BUS_PUBLISH_PORT=4442
35 - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
36 ports:
37 - 7902:7900
38
39 selenium-hub:
40 image: selenium/hub:latest
41 container_name: selenium-hub
42 ports:
43 - "4442:4442"
44 - "4443:4443"
45 - "4444:4444"
Hub開啟4444port,到時候測試用4444port跟grid連接。4442和4443port是給Event Bus使用,一個是發佈、一個是訂閱
如果需要監看瀏覽器操作流程,就要開啟port對應node 7900port。上述的compose.yaml中,chrome開啟7900,edge開啟7901等。如果不需要監看就不必開啟
docker-compose up –d
起環境以後,進入 http://localhost:4444/ui 檢查狀態
也可以curl GET 'http://localhost:4444/status'
檢查狀態
寫一個測試
這裡拿上一篇文章的測試,不過這次我改用pytest,因為比較方便!
這個測試用fixture建立一個chrome webdriver,打開鉅亨網,然後將游標懸停在導航欄的新聞上,最後assert在頁面上看到「台股盤勢」四個字
1import pytest
2from selenium import webdriver
3from selenium.webdriver import ActionChains
4from selenium.webdriver.common.by import By
5
6
7@pytest.fixture(scope="module")
8def driver():
9 driver = webdriver.Chrome()
10 driver.maximize_window()
11 yield driver
12 driver.quit()
13
14def test_search_in_python_org(driver):
15 driver.get("https://www.cnyes.com/")
16 elem = driver.find_element(
17 by=By.CSS_SELECTOR,
18 value='nav ul li a[data-global-ga-label="新聞"]>span'
19 )
20 ActionChains(driver).move_to_element(elem).perform()
21 assert "台股盤勢" in driver.page_source
現在搭配Selenium grid,webdriver必須改為remote,因為要連接Hub
1@pytest.fixture(scope="module")
2def driver():
3 driver = webdriver.Remote(
4 command_executor='http://localhost:4444',
5 options=webdriver.ChromeOptions()
6 )
7 driver.maximize_window()
8 yield driver
9 driver.quit()
修改後,我們來監看瀏覽器的操作狀況。在compose.yaml有映射7900 port,所以連接到http://localhost:7900/,可以看到這個畫面secret
)
回到command line,就可以開始測試,並且監看操作狀況啦!
1pytest
在不同的瀏覽器測試
在上面的測試裡,只用了Chrome瀏覽器測試。如果想要在一個測試中指定多種瀏覽器的option,可以使用pytest parametrizing fixtures
1def create_options(browser_name):
2 if browser_name == 'firefox':
3 options = webdriver.FirefoxOptions()
4 elif browser_name == 'edge':
5 options = webdriver.EdgeOptions()
6 else:
7 options = webdriver.ChromeOptions()
8 return options
9
10@pytest.fixture(scope="module", params=['chrome', 'edge', 'firefox'])
11def driver(request):
12 driver = webdriver.Remote(
13 command_executor='http://localhost:4444',
14 options=create_options(request.param)
15 )
16 driver.maximize_window()
17 yield driver
18 driver.quit()
在fixture加上params參數,是測試的瀏覽器list。當執行driver這個function時,request.param會按照順序取得chrome, edge, firefox。又新增了create_options function,依照傳入的瀏覽器名稱回傳options
並行測試
可以使用pytest-xdist,讓它用多個CPU加速處理多個測試
1pytest –n 3
參考
- https://www.selenium.dev/documentation/grid/
- https://github.com/SeleniumHQ/docker-selenium
- https://www.cnblogs.com/yaner2018/p/16166023.html