天天看點

Docker+Selenium搭建和踩坑記錄

 前記:python+flask+bootstrap+macaca 搭建 web/ android 自動化測試管理平台

  使用 python + flask 搭建的 selenium web 自動化測試平台已經運作一段時間。 一直以來都是需要在自己的windows 機上啟動 selenium server 作為運作的媒介,不是很友善。于是考慮使用docker 來作為運作用例的平台。

  安裝步驟:

  1. 安裝docker。

  首先打算在測試的linux 伺服器上搭建,無奈伺服器linux版本太低(上面的部署的服務還挺多的,不想冒更新核心版本的風險),嘗試了很多次都無法愉快地把docker 跑起來,最終選擇先在windows 伺服器下先嘗試搭起來。 具體安裝步驟網上很多,這裡就不多說了。

  2. 拉取所需的docker鏡像。

  目前使用到兩個鏡像:

  docker pull selenium/hub

  docker pull selenium/node-chrome

  3. 啟動對應docker鏡像。

  按selenium docker 官方github上的推薦方式啟動如下:

docker network create grid

docker run -d -p 4444:4444 --net grid --name selenium-hub selenium/hub

docker run -d --net grid -e hub_host=selenium-hub -v /dev/shm:/dev/shm selenium/node-chrome

  服務順利起來了,可以檢視到對應selenium節點:

  http://192.168.99.100:4444/grid/console#

Docker+Selenium搭建和踩坑記錄

  4. 跑一下測試腳本,可以正常調用服務進行測試:

from selenium import webdriver

chrome_options = webdriver.chromeoptions()

driver = webdriver.remote(command_executor='http://192.168.99.100:4444/wd/hub',

desired_capabilities = chrome_options.to_capabilities())

driver.get('http://www.baidu.com/')

driver.find_element_by_id("kw").send_keys("docker selenium test")

driver.find_element_by_id("su").click()

driver.get_screenshot_as_file("c://img1.png")

driver.quit()

Docker+Selenium搭建和踩坑記錄

  踩坑記

  1. 外網通路docker 裡的selenium 服務。

  設計的架構裡,測試平台将調用對應的 selenium server 服務發起測試。但現在docker隻能在windows 伺服器内通路,是以需要把對應的端口轉發出去。

  步驟:

  1.1 把selenium docker鏡像對應的 ip 192.168.99.100,端口為4444 的docker服務轉發到本地(對應的區域網路ip 為 172.16.100.1):

  cmd 執行:

  netsh interface portproxy add v4tov4 listenport=4444 listenaddress=172.16.100.1 connectport=4444 connectaddress=192.168.99.100

  1.2 windows 防火牆中添加端口4444 的對應轉發規則(防火牆》進階設定 ,分别添加入站規則和出站規則)

  這樣,區域網路的伺服器就可以通過 172.16.100.1:4444 調用selenium hub 的服務了。

  2. 視窗最大化失敗

  在腳本中對浏覽器進行最大化操作:

  driver.maximize_window()

  這個指令一向運作是沒問題的,但是在docker 中卻報錯如下:

  message: unknown error: failed to change window state to maximized, current state is normal

  查了一下,說是selenium 的bug。 找了一下,沒有合适的解決方案,粗暴解決如下:

try:

driver.maximize_window()

except webdriverexception as e:

log.log().logger.info(e)

driver.set_window_size(1920, 1080)  #如果最大化失敗,設定視窗大小為 1920*1080

  3. chrome option 不生效。

  因為部分用例需要模拟移動裝置,或設定浏覽器為英文,是以使用 chrome option進行設定。 原來的初始化腳本如下:

desired_caps_web = webdriver.desiredcapabilities.chrome

devicelist = ['galaxy s5', 'nexus 5x', 'nexus 6p', 'iphone 6', 'iphone 6 plus', 'ipad', 'ipad pro']

if devicename!='' :

if devicename not in devicelist:

devicename = devicelist[2]

chrome_option = {

'args': ['lang=en_us','start-maximized'],

'extensions': [], 'mobileemulation': {'devicename': ''}

}

chrome_option['mobileemulation']['devicename'] = devicename

else:

'args': ['lang=en_us','--start-maximized'],

'extensions': []

desired_caps_web['goog:chromeoptions']=chrome_option

log.log().logger.info(desired_caps_web)

driver = webdriver.remote.webdriver.webdriver(command_executor=server_url,desired_capabilities=desired_caps_web)

  但同樣,之前一直正常運作的腳本,到 docker 裡不起作用。

  看下docker selenium node 節點的log ,發現列印了如下資訊:

  capabilities are: capabilities {browsername: chrome, chromeoptions: {args: [lang=zh_cn.utf-8],  mobileemulation: {devicename: iphone 6}}, goog:chromeoptions: {}, javascriptenabled: true, version: }

  多了個 goog:chromeoptions {} 的配置項是怎麼回事?

  認真看下,capabilities 裡我設定的 chromeoptions 已經正确傳進來了,但是後面的 goog:chromeoptions: {} 似乎覆寫了對應的配置。

  嘗試下把腳本裡的參數名稱從 “chromeoptions ” 改為 “goog:chromeoptions” ,奇迹出現了:

  capabilities are: capabilities {browsername: chrome, goog:chromeoptions: {args: [lang=zh_cn.utf-8], mobileemulation: {devicename: iphone 6}}, javascriptenabled: true, version: }

  腳本也能正常運作了,對應的浏覽器語言、移動裝置模拟設定也已生效!

  于是修改對應腳本為:

  desired_caps_web['goog:chromeoptions']=chrome_option

  問題解決!

  至此,腳本可以愉快的跑起來了!