iT邦幫忙

DAY 15
7

逐步提昇PHP技術能力系列 第 15

逐步提昇PHP技術能力 - 開發工具 : 使用Selenium進行整合測試

其實本來最好再進一步深入單元測試的主題,討論一些測試技巧、phpunit提供的設施與機制、壞味道及anti-pattern等等....不過再往前會怕回不了頭,而且關於單元測試這個主題的資料網路上非常多,所以還是先來看Selenium。

Selenium是一個錄製瀏覽器腳本的工具,可以透過他的腳本,透過瀏覽器來操作,並且檢查執行的結果。整合測試其實並不一定需要用Selenium來做,在做單元測試時,如果協作的物件已經可以操作,就可以把stub或mock object換成真實的物件來測試,這樣也可以算是一種整合測試。不過根據開發方式,有可能沒辦法做什麼單元測試或比較細粒度的整合測試,這時唯一可以做的,大概就是透過selenium檢查網頁操作結果了。
參考:
http://www.seleniumhq.org/

Selenium這個工具可以分成幾個部分:

  1. SeleniumIDE:這是一個Firefox外掛,可以用它來錄製網頁操作腳本,並且將腳本存成不同語言。
  2. Selenium Remote / WebDriver:可以用許多種語言撰寫腳本,然後透過不同瀏覽器來跑。

* SeleniumIDE

如果像我這樣不熟悉Selenium腳本,首先還是會透過SeleniumIDE來錄製。

當然在使用之前要先安裝,所以先打開Firefox,然後到:http://docs.seleniumhq.org/download/,然後到SeleniumIDE標題下,可以找到最新的版本(應該是一個.xpi檔的連結)。安裝完畢後,重新啟動,就可以使用SeleniumIDE了。

使用SeleniumIDE來錄製網頁操作很簡單,只要從menu上選「工具」->「SeleniumIDE」就可以。

打開時,錄製按鈕預設是開啟的,所以可以直接開始操作網頁,在想要停止時,按一下錄製鈕來取消錄製。錄製完畢以後,就會看到錄製完的操作步驟列表。

錄製完成之後,就可以將TestCase存檔。在存檔之前,最好先播放一次看看是否成功。如果不成功,有時候是因為播放速度太快,這時可以調整一下速度。除了錄製單一個TestCase,也可以錄製多個TestCase,然後存成TestSuite。同樣地,除了播放單一個TestCase,也可播放整個TestSuite。

* Selenium Remote Control / WebDriver

PHP WebDriver:
https://github.com/instaclick/php-webdriver (more users)
https://github.com/Element-34/php-webdriver (suggested by selenium)
https://github.com/facebook/php-webdriver
Headless Browser Facility:
https://github.com/detro/ghostdriver

除了使用Firefox上的SeleniumIDE,還有更進一步的方法可以來做測試,就是透過Selenium Server。他的運作原理是,開啟一個server來監聽某個port送來的命令,收到以後,這個server便會依照傳來的命令,操作瀏覽器進行測試。

舊版的Selenium Server技術,叫做Selenium Remote Control,過程比較複雜。新版的使用一個共通標準,叫做WebDriver,這樣就有更多程式語言的支援。要透過Selenium Server來做測試,首先要下載(廢話):
http://docs.seleniumhq.org/download/,在Selenium Server標題下,可以找到下載連結(連結會隨著版本更新變動,所以我不直接貼出來)。

這其實是一個Java的server程式,包裝成jar檔。下載完成後,使用java -jar 檔名來執行,就可以開啟伺服器,預設的通訊埠是4444。之後,就可以使用某個語言的WebDriver binding來連上伺服器,驅動測試。不過因為WebDriver不太熟,所以想偷懶,看看有沒有辦法從剛剛錄製的腳本直接轉換。

打開「檔案」選單後,可以看到「Export TestCase As」,不過...選項裡沒有PHP...只好google一下"selenium formatter php",就發現:
https://addons.mozilla.org/zh-tw/firefox/addon/selenium-ide-php-formatters/

版本1.3.2有點舊(要跟上SeleniumIDE的話,最好是2.4.0),不過也沒得選,直接安裝了。

安裝完畢後重新啟動Firefox,打開SeleniumIDE,然後叫出之前存檔的TestCase,選好TestCase之後,再到「Export TestCase As」看一下,就出現兩個新的選項,包括:PHP (PHPUnit)以及PHP (Testing_Selenium)...既然可以用PHPUnit驅動,那就選PHPUnit,然後存檔。

* 透過PHPUnit驅動Selenium測試?

存成PHP檔之後,先根據檔名改一下class的名稱,然後用phpunit跑跑看。不過之前沒有安裝phpunit的selenium套件,所以在執行前先用composer安裝一下。首先來改一下composer.json:

{
    "require":{
    },
    "require-dev": {
        "phpunit/phpunit":"~3.7.5",
        "phpunit/php-invoker":"~1.1.0",
        "phpunit/phpunit-selenium":"~1.3.2"
    }
}

改完之後,要執行composer update來安裝,因為composer.lock並沒有這個套件,所以必須用composer update才能更新。接下來改一下phpunit.xml,加上剛剛存檔的selenium test case,放在新的testsuite,命名為selenium:

<phpunit>
  <testsuites>
    <testsuite name="utils">
      <file>tests/TestScormTimeUtils.php</file>
    </testsuite>
    <testsuite name="selenium">
    	<file>tests/TestSelenium.php</file>
    </testsuite>
  </testsuites>
</phpunit>

然後配合存檔的檔名,改一下類別名稱:

<?php
require 'vendor/autoload.php';

class TestSelenium extends PHPUnit_Extensions_SeleniumTestCase
{
  protected function setUp()
  {
    $this->setBrowser("firefox");
    $this->setBrowserUrl("http://localhost/");
  }

  public function testMyTestCase()
  {
    $this->open("/b2ba2/");
    $this->type("id=uname", "user1");
    $this->type("id=password", "franklin168");
    $this->click("css=div.login > a");
    $this->waitForPopUp("newwindow", "30000");
  }
}

接下來就可以啟動Selenium Server:

Feng-Hsu-Pingteki-MacBook-Air:ironman6 fillano$ java -jar selenium-server-standalone-2.35.0.jar 
2013/10/15 ?U?? 10:04:02 org.openqa.grid.selenium.GridLauncher main
??T: Launching a standalone server
22:04:07.988 INFO - Java: Apple Inc. 20.14-b01-443
22:04:07.989 INFO - OS: Mac OS X 10.8.5 x86_64
22:04:08.029 INFO - v2.35.0, with Core v2.35.0. Built from revision c916b9d
22:04:08.416 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
22:04:08.418 INFO - Version Jetty/5.1.x
22:04:08.420 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
22:04:08.423 INFO - Started HttpContext[/selenium-server,/selenium-server]
22:04:08.424 INFO - Started HttpContext[/,/]
22:04:08.533 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@a210b5b
22:04:08.533 INFO - Started HttpContext[/wd,/wd]
22:04:08.573 INFO - Started SocketListener on 0.0.0.0:4444
22:04:08.574 INFO - Started org.openqa.jetty.jetty.Server@5ae80842

然後執行phpunit,加上指定的testsuite名稱,也就是selenium:

Feng-Hsu-Pingteki-MacBook-Air:2-3a fillano$ phpunit --testsuite selenium --verbose
PHPUnit 3.7.27 by Sebastian Bergmann.

Configuration read from /Users/fillano/builds/ironman6/2-3a/phpunit.xml

.

Time: 15.34 seconds, Memory: 3.75Mb

OK (1 test, 0 assertions)

不過測試畫面一閃而過,來不及抓取,所以看一下Selenium Server的輸出:

22:09:06.096 INFO - Command request: getNewBrowserSession[firefox, http://localhost/] on session null
22:09:06.097 INFO - creating new remote session
22:09:06.098 INFO - Allocated session 67f173be41d24d579fbd83871909694e for http://localhost/, launching...
jar:file:/Users/fillano/builds/ironman6/selenium-server-standalone-2.35.0.jar!/customProfileDirCUSTFFCHROME
22:09:06.280 INFO - Preparing Firefox profile...
22:09:08.298 INFO - Launching Firefox...
22:09:13.919 INFO - Got result: OK,67f173be41d24d579fbd83871909694e on session 67f173be41d24d579fbd83871909694e
22:09:13.925 INFO - Command request: setTimeout[30000, ] on session 67f173be41d24d579fbd83871909694e
22:09:13.934 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e
22:09:13.957 INFO - Command request: getExpression[/b2ba2/, ] on session 67f173be41d24d579fbd83871909694e
22:09:14.023 INFO - Got result: OK,/b2ba2/ on session 67f173be41d24d579fbd83871909694e
22:09:14.028 INFO - Command request: open[/b2ba2/, ] on session 67f173be41d24d579fbd83871909694e
22:09:18.909 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e
22:09:18.917 INFO - Command request: getExpression[id=uname, ] on session 67f173be41d24d579fbd83871909694e
22:09:18.949 INFO - Got result: OK,id=uname on session 67f173be41d24d579fbd83871909694e
22:09:18.953 INFO - Command request: getExpression[user1, ] on session 67f173be41d24d579fbd83871909694e
22:09:18.980 INFO - Got result: OK,user1 on session 67f173be41d24d579fbd83871909694e
22:09:18.985 INFO - Command request: type[id=uname, user1] on session 67f173be41d24d579fbd83871909694e
22:09:19.110 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e
22:09:19.118 INFO - Command request: getExpression[id=password, ] on session 67f173be41d24d579fbd83871909694e
22:09:19.155 INFO - Got result: OK,id=password on session 67f173be41d24d579fbd83871909694e
22:09:19.165 INFO - Command request: getExpression[franklin168, ] on session 67f173be41d24d579fbd83871909694e
22:09:19.199 INFO - Got result: OK,franklin168 on session 67f173be41d24d579fbd83871909694e
22:09:19.206 INFO - Command request: type[id=password, franklin168] on session 67f173be41d24d579fbd83871909694e
22:09:19.232 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e
22:09:19.236 INFO - Command request: getExpression[css=div.login > a, ] on session 67f173be41d24d579fbd83871909694e
22:09:19.250 INFO - Got result: OK,css=div.login > a on session 67f173be41d24d579fbd83871909694e
22:09:19.256 INFO - Command request: click[css=div.login > a, ] on session 67f173be41d24d579fbd83871909694e
22:09:20.117 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e
22:09:20.129 INFO - Command request: getExpression[newwindow, ] on session 67f173be41d24d579fbd83871909694e
22:09:20.174 INFO - Got result: OK,newwindow on session 67f173be41d24d579fbd83871909694e
22:09:20.193 INFO - Command request: getExpression[30000, ] on session 67f173be41d24d579fbd83871909694e
22:09:20.267 INFO - Got result: OK,30000 on session 67f173be41d24d579fbd83871909694e
22:09:20.276 INFO - Command request: waitForPopUp[newwindow, 30000] on session 67f173be41d24d579fbd83871909694e
22:09:20.927 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e
22:09:20.930 INFO - Command request: testComplete[, ] on session 67f173be41d24d579fbd83871909694e
22:09:20.930 INFO - Killing Firefox...
22:09:21.302 INFO - Got result: OK on session 67f173be41d24d579fbd83871909694e

嗯,看起來是有在測試,PHPunit也有跑出結果...再來換個瀏覽器看看,把測試程式中的firefox改成safari,然後跑跑看:

這次有抓到畫面,因為safari跑比較慢XD


上一篇
逐步提昇PHP技術能力 - 開發工具 : 使用PHPUnit進行單元測試
下一篇
逐步提昇PHP技術能力 - 開發工具 : 使用pdepend / phpmd 等工具檢測程式碼品質
系列文
逐步提昇PHP技術能力30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
SunAllen
iT邦研究生 1 級 ‧ 2013-10-15 23:29:53

沙發
筆記筆記 雖然還看不懂,但會努力學習的

我要留言

立即登入留言