Selenium2&PHPUnitでCUI実行


## 概要

Selenium2 と PHPUnit で、CentOSでコマンド実行にて自動テストを行う。

##準備
### Selenium Server
※Javaのインストール要

以下からSelenium Standalone Serverをダウンロード

http://docs.seleniumhq.org/download/

好きな場所に配置。
```
/usr/local/bin/selenium-server-standalone-2.44.0.jar
```
起動スクリプトを準備すると楽。

### Xvfb
```
yum install xorg-x11-server-Xvfb
```

```sh:/etc/init.d/xvfb
  . /etc/init.d/functions
  PATH=/sbin:/bin:/usr/sbin:/usr/bin
  PROG=/usr/bin/Xvfb
  PROGNAME=`basename $PROG`

  export DISPLAY=:1
  [ -f $PROG ] || exit 0

  case "$1" in
      start)
          echo -n $"Starting $PROGNAME: "
          daemon $PROG :1 -screen 0 1024x768x8 > /dev/null 2>&1 &
          echo
          ;;
      stop)
          echo -n $"Stopping $PROGNAME:"
          killproc $PROGNAME
          echo
          ;;
      status)
          status $PROGNAME
          ;;
      *)
          echo $"Usage: $PROGNAME {start|stop|status}" >&2
          exit 1
          ;;
  esac
  exit 0
```


### Firefox
Selenium Serverのバージョンによって、相性がある。
以下の組み合わせは動作確認済み。
Selenium Server 2.44.0 
Mozilla Firefox 35.0.1

yumは最新版が入ってしまうので、以下から対象バージョンを探す。
https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/

ダウンロードしたファイルを解凍して、好きな場所に配置。
```
/usr/local/share/firefox
```
### PHPUnit
Composer使用。

```javascript:composer.json
{
    "require-dev": {
        "phpunit/phpunit": "4.6.*",
        "phpunit/phpunit-selenium": ">=1.2"
    }
}
```
プロジェクトルート直下にtestsディレクトリを置いて、
テストコード配置

テストコードサンプル

```php:tests/AccessBrowserTest.php
<?php
class AccessBrowserTest extends PHPUnit_Extensions_Selenium2TestCase {

  public static $browsers = array(
    array(
      'browserName' => 'firefox',
      'host' => 'localhost',
      'port' => 4444
    )
  );

  protected function setUp() {
    parent::setUp();
    $this->setBrowserUrl('http://xxxxx.jp');
    $this->setDesiredCapabilities(array(
      "firefox_profile" => file_get_contents($this->constant->profilePCPath)
    ));
    $this->setSeleniumServerRequestsTimeout(5000);
  }

  public function test01() {
    $this->url('http://xxxxx.jp/');
    //以下好きにテストコードを記述
    }
}
```

```xml+php:tests/phpunit.xml
<phpunit
        colors="true"
        verbose="true">
    <php>
        <ini name="display_errors" value="on"/>
    </php>
    <testsuites>
        <testsuite name="Unit Test">
            <file>AccessBrowserTest.php</file>
        </testsuite>
    </testsuites>
</phpunit>
```

必ずPHPUnit_Extensions_Selenium2TestCaseを継承して作成する事。
2が付いてないPHPUnit_Extensions_SeleniumTestCaseは、記述方法が異なるため。

##実行
###Selenium Server 起動
```
java -jar /usr/local/bin/selenium-server-standalone-2.44.0.jar -port 4444 -Dwebdriver.firefox.bin=/usr/local/share/firefox/firefox -trustAllSSLCertificates  -log /var/log/selenium/selenium-output.log
```

###Xvfb起動
起動スクリプト経由で起動

```
/etc/init.d/xvfb start
```

###PHPUnit実行

```
vendor/bin/phpunit -c tests/phpunit.xml
```

## スマホ対応
Firefox のプロファイルを書き換えてUAを変更すれば、
スマホ用ページのテストも可能。

###プロファイルの作成
※Windowsの場合

firefox.exeに引数をつけて起動

```
"firefox.exe" -ProfileManager -no-remote
```

新しいプロファイルを作成して、Firefox起動。
about:configで、UAを上書き

```
設定名:general.useragent.override
値(例):Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A365 Safari/600.1.4|
```
作成したプロファイルをzipファイルにして、base64に変換する。

プロファイルの場所
```
%APPDATA%\Mozilla\Firefox\Profiles 
```

CentOS上で圧縮、base64変換した場合

```sh
cd ve9ubtem.mobile(ディレクトリ名は個々に異なる)
zip -r ../firefox-profile.zip *
base64 ../firefox-profile.zip > firefox-profile.base64
```

base64に変換した文字列をPHPUnitのテストコードで指定。

```php
  protected function setUp() {
    parent::setUp();
    $this->setBrowserUrl('http://xxxxx.jp');
    $this->setDesiredCapabilities(array(
      "firefox_profile" => ”プロファイル base64文字列をここへ指定”
    ));
  }
```

実行時、指定したプロファイルでFireFoxが起動する。

##おまけ

### PHPUnitテスト開始〜完了まで、内部の流れ。

1.PHPUnitは、Selenium Serverへリクエストを投げる。

2.Selenium Serverは仮想ディスプレイXvfbを見つけて、FireFox起動、もしくは見つける。

3.Selenium Server - FireFox間でテスト実行する。

4.Selenium Serverは PHPUnit へテスト結果のレスポンスを戻す。

5.PHPUnit で正常・異常を判定。

異常終了の切り分けは大まかに２箇所。

* PHPUnit - Selenium Server 間の疎通が取れない場合
 * PHPUnitにてSelenium Serverから受け取ったレスポンスにあるエラーを確認する。

* Selenium Server - Xvfb もしくは、Firefox 間と疎通が取れない場合
  * Selenium Server自体が出力するエラーログを確認する。

構築中に思ったこと
PHPUnitのSeleniumTestクラス〜Selenium Serverのリクエスト・レスポンス部分が、ブラックボックス。
エラーの原因がわからない場合は、デバッグコードを仕込みつつSeleniumTestクラスを見たが早い（かった）

以上。