BrowserStack Automateでブラウザテストを自動化（PHP版）


# はじめに

先日Google Analyticsなどの計測タグを少しカスタマイズする機会があったのですが、これを多種多様なブラウザで「問題なく計測されること」「エラーが発生しないこと」をテストするのはなかなか骨が折れるなと思い、BrowserStackの自動テスト環境Automateを試してみました。

そしたらこれがまたとても便利なので、ハマりどころも含めここに書き残しておきます。

# BrowserStack Automateって？

BrowserStack上の様々なOS・ブラウザでのテストを、スクリプトを使って自動化できる仕組み、なのですが、少し捕捉すると:

ブラウザテストを自動化するときに便利なものに、実際にブラウザをスクリプトから操作できるSelenium WebDriverがあります。PhantomJSなどのヘッドレスブラウザもありますが、こちらはWebKitベースのみなので今回のテスト目的からは外れます（jsのテストはできるが、ブラウザごとの挙動に依存したテストができない）。

Selenium WebDriverを使う場合、基本的にはこんな流れになります。

1. スクリプトから、
2. [facebook/php-webdriver](https://github.com/facebook/php-webdriver)などを使いつつ、
3. Selenium Serverを叩くと、
4. Selenium ServerがブラウザごとのDriverを使って、
5. ブラウザを立ち上げて実際に操作する

自前ですべて用意する場合、Selenium Serverも、ブラウザごとのDriverも、ブラウザも、そしてそれを載せるOSも、すべて用意する必要があります。vmにまみれてvm死すること必至です。

BrowserStack Automateは、3以降がすべてあらかじめ用意されています。やることは、AutomateのSelenium Serverを叩くだけ。「このOSのこのブラウザでテストしたい」と伝えると、その場で対応するvmをクラウド上に立ち上げてテストを回してくれます。

# 使い方

とてもシンプルなので、[facebook/php-webdriverのドキュメント](https://github.com/facebook/php-webdriver)や[Automateのドキュメント](https://www.browserstack.com/automate/php)を読んでもわりとすぐはじめられるかと思いますが、ここでも若干の捕捉を付けて書いてみようと思います。

## 1. php-webdriverをインストール

まずはこれ。composer.jsonに以下を追記して、'composer update'

```
"require": {
    "facebook/webdriver": "^1.1"
}
```

## 2. スクリプトを書いて実行

スクリプトはこのような感じになります。
これを実行すれば、(OS・ブラウザにもよりますが)大体10-20秒程度で結果が返ってきます。

```php
require 'vendor/autoload.php';

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;

// AutomateのSelenium ServerのURL
// user/accesskeyはこちらから取得: https://www.browserstack.com/accounts/settings
$host = 'http://user:accesskey@hub.browserstack.com/wd/hub';

// OSやブラウザなどを指定
$caps = [
    'os' => 'Windows',
    'os_version' => '8.1',
    'browser' => 'IE',
    'browser_version' => '11.0'
];

// WebDriverのインスタンスを作成
// 3,4つ目の引数はそれぞれcurlに渡るconnection/request timeoutで、
// Automateの処理に時間がかかってtimeoutしてしまうことを防ぐ。（デフォルトは30000）
// 特に、iOSやAndroidはエミュレータを立ち上げるので時間がかかる。
$driver = RemoteWebDriver::create($host, $caps, 300000, 300000);

// $driverを使ってブラウザ操作を行う。例えば:

// Googleを開いて、
$driver->get('https://www.google.com');

// 検索ボックスのエレメントを取得して、
$element = $driver->findElement(WebDriverBy::name("q"));

// 検索ボックスにキーワードを入力して送信
$element->sendKeys('rebuild.fm 出演者');
$element->submit();

// 開いたページのタイトルをプリント
print $driver->getTitle();

$driver->quit();
```

## RemoteWebDriverのAPIリファレンス

[は、こちら](http://facebook.github.io/php-webdriver/classes/RemoteWebDriver.html)

# 便利な使い方

$capsで指定できるオプションに、いくつか便利なものがあります。

なお、利用できるオプションのフルリストは、

* [WebDriverが用意しているオプション](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities)
* [Automateがカスタムで用意しているオプション](https://www.browserstack.com/automate/capabilities)

の両方が利用できるようです。

また、OS・ブラウザの組み合わせによる設定値については、[このページ](https://www.browserstack.com/automate/php)でプルダウンを選んで出力することもできます。

## BuildとProject

これを指定しておくと、結果の確認がラクになります。buildを指定しておくと、同じビルドの複数テストが1つにまとまり、さらにprojectを指定しておくと、同じプロジェクトの複数ビルドが1つにまとまります。

```php
$caps['build'] = 'version1';
$caps['project'] = 'My Project';
```

## オレオレ証明書

最近はもうLet's Encryptのおかげで減りつつありますが、テスト対象のSSLがオレオレ証明書のこともあるかと思います。そんな時に

```php
$caps['acceptSslCerts'] = "true";
```

としておくと、SSL警告が出たときに自動的に「無視する」をクリックしてくれます。

---

以上、とっかかりを掴むときなどのお役に立てますと幸いです。