您的位置:軟件測試 > 開源軟件測試 > 開源功能測試工具 > Selenium
selenium結(jié)合docker構(gòu)建分布式測試環(huán)境
作者:不再有的年月 發(fā)布時(shí)間:[ 2017/4/24 11:17:38 ] 推薦標(biāo)簽:Selenium 功能測試

  由于默認(rèn)的maxSession為5而maxInstances為1,所以取小的一個(gè),node端只運(yùn)行有一個(gè)session的存在,所以我們第二次運(yùn)行處于阻塞狀態(tài)。∵@些信息我們會(huì)在后面對(duì)其鏡像的構(gòu)建文件Dockerfile講解時(shí)提到。作者為什么要將maxInstances設(shè)置為1?我的理解是:一般用到Grid布局的都是一些比較大型的測試體系,一般環(huán)境搭建好了測試腳本寫好了保證有一個(gè)測試結(jié)果好。我們默認(rèn)的timeout時(shí)間是30000S,這個(gè)從上面我們hub的啟動(dòng)日志可以看出來,也是說如果hub在30000s內(nèi)沒有執(zhí)行任何操作會(huì)自動(dòng)切斷!這個(gè)timeout的時(shí)間是相當(dāng)?shù)拈L,關(guān)于這個(gè)timeout的時(shí)間長短我覺得與你的testcase有關(guān),比如你在腳本中有個(gè)比較耗時(shí)的操作例如Sleep(100),睡眠100S再進(jìn)行后續(xù)操作,如果你的timeout設(shè)置為30s,那么在30S的時(shí)候hub會(huì)主動(dòng)切斷這個(gè)連接,也是說你后面的用例是不會(huì)再執(zhí)行了....這個(gè)是個(gè)仁者見仁,智者見智的事情了,但是我覺得把timeout搞長點(diǎn)好點(diǎn)。想要多次調(diào)試腳本,大不了我們把maxInstances與maxSession設(shè)置數(shù)目大點(diǎn)了。實(shí)在不行你也可以先docker stop+node 容器的ID,再docker start +node 容器ID好了!
  說了第二個(gè)問題的一些看法,我們重點(diǎn)來看看如何解決第一個(gè)問題,在解決第一個(gè)問題的同時(shí),我們修改一些配置,一并把第二個(gè)問題給解決了!
  我們先來看看selenium/hub與seleniu/node-firefox的源Dockerfile文件,源碼的地址為:https://github.com/SeleniumHQ/docker-selenium,你可以下載或clone下來。我們來看看這個(gè)項(xiàng)目的結(jié)構(gòu):

  Base是selenium鏡像的基礎(chǔ),里面的Dockerfile除了在Ubuntu鏡像的基礎(chǔ)上安裝了一些工具包,主要工作如下:
  1.還有搭建了一個(gè)java運(yùn)行環(huán)境,用來運(yùn)行后來的selenium-server-standalone-3.3.1.jar
  2.下載了selenium-server-standalone-3.3.1.jar放在容器的/opt/selenium文件夾下
  Hub文件夾里面的Dockerfile是用來build selenium/hub鏡像的,是基于上面的Base,主要工作如下:
  1.定義了node啟動(dòng)的一些參數(shù),發(fā)現(xiàn)它把里面的timeout參數(shù)改成30s了。我并沒有pull新的selenium/hub,你們現(xiàn)在pull的可能timeout參數(shù)是30s,我的是30000s。
  2.定義了容器啟動(dòng)的腳本entry_point.sh,并把他復(fù)制到容器的/opt/bin下
  NodeBase是一切node鏡像的基礎(chǔ),我們查看里面的Dockerfile發(fā)現(xiàn)它是基于我們上面提到的Base的,主要工作如下:
  1.定義了node容器的啟動(dòng)腳本entry_point.sh并復(fù)制到容器的/opt/bin/下。
  NodeFirefox是用來build我們pull下來的selenium/node-firefox它是基于我們上面提到的NodeBase。我們查看它的Dokcerfile文件,發(fā)現(xiàn)它的主要工作如下:
  1.下載了版本號(hào)為52.0.2的firefox瀏覽器,并做了一些配置。
  2.下載了GeckoDriver,我們知道高版本的瀏覽器必須要通過GeckoDriver來啟動(dòng)一個(gè)socket,這也是selenium3.0誕生的主要原因。2.0是無法啟動(dòng)高版本的firefox的
  3.設(shè)置fire-node的一些啟動(dòng)參數(shù),我們清楚的看到NODE_MAX_INSTANCES 1與ENV NODE_MAX_SESSION 1的配置,所以如何要改變我們問題二的情況,在重新構(gòu)建鏡像的時(shí)候,要重新定義這些環(huán)境變量了。
  對(duì)上面的解釋做個(gè)說明:
  1.Dockerfile是用來build鏡像的。指令為docker build -t 鏡像名稱  Dockerfile路徑,例如:docker build -t selenium/my-firefxo-node . 用當(dāng)前路徑下的Dockerfile文件來創(chuàng)建一個(gè) selenium/my-firefxo-node鏡像文件。
  2.Dockerfile一些基礎(chǔ)知識(shí)可以百度了解,無非是一些shell指令集的大集合。
  說完了這些,我們來解決我們遇到的第一個(gè)和第二個(gè)問題,思路很簡單,對(duì)的,是利用的selenium/firefox-node重新構(gòu)建鏡像。
  截圖中文亂碼的問題我的考慮如下:
  1.docker的Ubuntu版本是沒有中文版的,所以我們要下載中文包,并把默認(rèn)語言配置成中文
  2.僅僅做了1的操作后,我們重新運(yùn)行build的鏡像,發(fā)現(xiàn)還是亂碼,查閱資料明白可能是firefox必須支持相應(yīng)的中文字體才可以避免亂碼的情況,所以我們終的Dockerfile內(nèi)容如下:
FROM selenium/node-firefox
#改變node的啟動(dòng)參數(shù)
ENV NODE_MAX_INSTANCES 10
ENV NODE_MAX_SESSION 10
# 配置中文
RUN sudo locale-gen zh_CN.UTF-8 &&
sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales
RUN sudo locale-gen zh_CN.UTF-8
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN:zh
ENV LC_ALL zh_CN.UTF-8
#更新軟件包索引
RUN sudo apt-get update -qqy
#安裝基本字體
RUN sudo apt-get -qqy --no-install-recommends install
fonts-ipafont-gothic
xfonts-100dpi
xfonts-75dpi
xfonts-cyrillic
xfonts-scalable
#安裝文泉驛微米黑字體
RUN sudo apt-get -qqy install ttf-wqy-microhei
&& sudo ln /etc/fonts/conf.d/65-wqy-microhei.conf /etc/fonts/conf.d/69-language-selector-zh-cn.conf
  說到這遇到一個(gè)現(xiàn)實(shí)的問題是,我們建立了上面的Dokcerfile文件,但是是在windows平臺(tái)上的,例如我是放在D盤的Sikilu這個(gè)文件夾下的,我們docker主機(jī)如何訪問這個(gè)Sikilu文件夾呢?
  首先,我們要明白個(gè)道理,docker是不能運(yùn)行在windows平臺(tái),我們能在windows平臺(tái)使用是因?yàn)樗\(yùn)行在Oracle VM VirtualBox里面的!所以在windows平臺(tái)搭建docker時(shí)給你安裝了個(gè)VirtualBox虛擬機(jī)。這好辦了,我們打開這個(gè)虛擬機(jī)把D盤的Sikilu設(shè)置為共享文件夾好了。具體截圖如下:

  設(shè)置完后,我們重啟虛擬機(jī)中名稱為default這個(gè)docker主機(jī)。
  我們?cè)赬shell中切換到根目錄cd /發(fā)現(xiàn)了共享的文件夾:

  我們把上面的Dockerfile放到我們共享的這個(gè)文件夾下并切換進(jìn)去。執(zhí)行docker build -t selenium/my_node-firefox .
  build的過程可能要點(diǎn)時(shí)間終build成功!我們運(yùn)行docker images

  可以看到我們build的鏡像。我們先停掉上面用selenium/node-firefox啟動(dòng)的容器:

  我們運(yùn)行如下指令:docker run -P -d --link selenium_hub:hub  selenium/my_node-firefox

  由于selenium/my_node-firefox是基于selenium/node-firefox的,所以容器內(nèi)部也是個(gè)版本為50.0的firefox瀏覽器。但是我們?yōu)樵撊萜飨螺d了中文包且下載了相應(yīng)的字體,改變了firefox瀏覽器中文亂碼的問題,同時(shí)改變了firefox node的啟動(dòng)參數(shù),使它能夠同時(shí)建立10個(gè)session!具體數(shù)字多少自己更改,當(dāng)然也可以改其他的啟動(dòng)參數(shù)!
  我們運(yùn)行上面的測試腳本,發(fā)現(xiàn)問題能得到有效的解決,當(dāng)然運(yùn)行超過10次又阻塞了,原因上面說的很清楚了我們的大session設(shè)置了10!
  還有一個(gè)問題:我們?nèi)绾谓⑵渌姹咎?hào)的node-firefox?上面說了我們pull下來的是50.0的,比如我要構(gòu)建集群測試每臺(tái)機(jī)器上不同版本的firefox,那么我們要?jiǎng)?chuàng)建不同版本的鏡像!
  這邊有2中思路,第一種思路想法也簡單
  1.下載我們特定版本的瀏覽器到我們共享的Sikilu文件夾中。
  2.運(yùn)行我們上面build的selenium/my_node-firefox這個(gè)鏡像把這個(gè)共享的文件夾掛載進(jìn)去。(-v參數(shù))
  docker run -P  -v /Sikilu/:/Sikilu --link selenium_hub:hub selenium/my_node-firefox
  3.我們刪除該容器/opt下的firefox-50.0這個(gè)瀏覽器,同時(shí)解壓掛載的宿主機(jī)Sikilu中的特定版本的firefox到/opt目錄
  4.運(yùn)行rm -rf /usr/bin/firefox
  5.ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox
  6.exit這個(gè)容器運(yùn)行docker commit -m "firefox-47.0.2"  當(dāng)前容器的ID  鏡像名稱,例如docker commit -m "firefox-47.0.2"  2d96630b4f07(我們進(jìn)入的容器id號(hào))  selenium/node-firefox47.0.2(新的鏡像名稱)
  上面的一系列操作,我們得到了一個(gè)特定版本的鏡像,下次啟動(dòng)我們r(jià)un這個(gè)鏡像可以了。
  第二種思路,在我們新build的selenium/my_node-firefox這個(gè)基礎(chǔ)新建Dockerfile,重新構(gòu)建鏡像(建議這種方式畢竟高端點(diǎn)...)內(nèi)容如下:
FROM selenium/my_node-firefox
#指定新構(gòu)建firefox版本
ARG FIREFOX_VERSION=47.0.2
#刪除已存在firefox瀏覽器
RUN a=$(find /opt/  -name "firefox" |cut -d/ -f 3)&&sudo rm -rf /opt/$a&&sudo rm -rf /usr/bin/firefox
#下載指定版本的瀏覽器
RUN sudo apt-get update -qqy
&& sudo rm -rf /var/lib/apt/lists/* /var/cache/apt/*
&& sudo wget --no-verbose -O /tmp/firefox.tar.bz2 https://download-installer.cdn.mozilla.net/pub/firefox/releases/$FIREFOX_VERSION/linux-x86_64/en-US/firefox-$FIREFOX_VERSION.tar.bz2
&& sudo tar -C /opt -xjf /tmp/firefox.tar.bz2
&& sudo rm /tmp/firefox.tar.bz2
&& sudo mv /opt/firefox /opt/firefox-$FIREFOX_VERSION
&& sudo ln -fs /opt/firefox-$FIREFOX_VERSION/firefox /usr/bin/firefox
  同樣,我們切換到共享的Sikilu文件夾中運(yùn)行:docker build -t selenium/node-firefox47.0.2  .
  如果網(wǎng)絡(luò)較慢是特別費(fèi)時(shí)間的,這時(shí)候去聽音樂去吧,一段時(shí)間后建立一個(gè)firefox版本為47.0.2的鏡像,當(dāng)我們r(jià)un這個(gè)鏡像來啟動(dòng)容器時(shí),注冊(cè)進(jìn)hub的是這個(gè)版本的瀏覽器!!
  后一個(gè)問題收尾,是我們開始提到的run一個(gè)鏡像時(shí)的--link的參數(shù)。
  docker通過link將source container中定義的環(huán)境變量全部導(dǎo)入到received container中。我們先來看看上面提到NodeBase文件下的entry_point.sh這個(gè)腳本,我們截取關(guān)鍵的一部分:是執(zhí)行selenium-server-standalone.jar這個(gè)jar包的一段:
  xvfb-run -n $SERVERNUM --server-args="-screen 0 $GEOMETRY -ac +extension RANDR"
  java ${JAVA_OPTS} -jar /opt/selenium/selenium-server-standalone.jar
  -role node
  -hub http://$HUB_PORT_4444_TCP_ADDR:$HUB_PORT_4444_TCP_PORT/grid/register
  -nodeConfig /opt/selenium/config.json
  ${SE_OPTS} &
  NODE_PID=$!
  上面的$HUB_PORT_4444_TCP_PORT表示我們hub的端口號(hào),$HUB_PORT_4444_TCP_ADDR這個(gè)代表hub的IP地址,這些是怎么來的?其實(shí)這個(gè)是因?yàn)槲覀兪褂胠ink參數(shù),docker自動(dòng)生成這些參數(shù)。我們進(jìn)入到由鏡像selenium/my_node-firefox啟動(dòng)的容器(sudo docker exec -it 24c5fb9a649a  /bin/bash),輸入env

  發(fā)現(xiàn)了這2個(gè)字段,其實(shí)這個(gè)容器的環(huán)境變量被分成5個(gè)部分,一個(gè)部分是ALIASDB_PORT開頭的一系列變量,這些變量會(huì)有很組,每組變量的命名格式如下:

  其中<alias>是我們source container的別名;<port>是在Dockerfile中使用EXPOSE導(dǎo)出的端口,還有docker run 的時(shí)候使用-p導(dǎo)出的端口;<protocol>則是這些端口對(duì)應(yīng)的協(xié)議。
  現(xiàn)在明白上文中為什么--link selenium/hub冒號(hào)后面為什么要跟hub或者HUB了吧,只有寫成這樣才會(huì)找到HUB_PORT_4444_TCP_PORT與$HUB_PORT_4444_TCP_ADDR這2個(gè)變量,免得容器是啟動(dòng)不起來的。
  到這里結(jié)束吧,本來還想多寫點(diǎn)關(guān)于docker的用法知識(shí)。但是打字打的想吐了,可能本文中一些東西說的不清不楚,但是我相信您通過查閱資料一定能得到相應(yīng)的解決!

上一頁12下一頁
軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd