BehatとSeleniumを組み合わせ受け入れテストを自動化する
みなさんこんにちは。@ryuzeeです。
Behatは良さそうなので引き続き検証しています。 今回は、BehatとSeleniumを組み合わせて、受け入れテスト型のテストを自動化してみたので、その方法について説明しましょう。 なお、前回の記事を読まれていない場合はまずそちらを参照してください。 PHPでBDD(Behavior Driven Development)する方法
Seleniumの課題
僕が関わっている案件では受入テストを自動化しているケースももちろんあって、その際はPHPUnitとSeleniumを組み合わせています。 このテストには以下のような課題があります。
- 画面の操作をするphpコードが大量にあって、ソースを見ただけでは何をしているのか分かりにくい
- Seleniumは操作に画面の要素名利用するため、例えばサイトのデザインを大幅に変えたりすると、テストの中身も大幅に書き換えなければならない
- 上記と同様だがテスト内容とコードが密接に関連しすぎており、テストのシナリオ自体の再利用性が極めて低い
BehatとSeleniumを組み合わせることによる効果
BehatとSeleniumを組み合わせることで以下のような利点がありそうです。
- テストのシナリオのレイヤーと自動テストの実装のレイヤーが分離できる
- テストのシナリオ自体はシステムの知識があまり無いユーザーや発注者でも作成できる
- それによって少なくともテストシナリオ自体の再利用性は進む
- When、Given、Andをうまく使うことで、それに対応するテストコード自体は必然的に小さくなる
以下ではGoogle検索を例にして、BehatとSeleniumの組み合わせ方を解説します。
シナリオ
こんなシナリオならソースコードを書けない人でも書けるはずです。

Feature: Googleもしかして
Google日本語検索で、入力内容と関連しそうな内容をサジェスチョンする
Scenario: Chromeは神かどうかのテスト
Given 私はGoogle日本語版サイトにアクセスします
And 私は検索ボックスに "Chrome ゴミブラウザ" と入力します
When 検索ボタンを押します
Then その結果画面には "もしかして: Chrome 神ブラウザ" と表示されます
Given ブラウザを終了します
テストの作成
シナリオを作成したら、まずは実装は一切なく、テストを実施してみましょう。
behat フィーチャーディレクトリ名
まだステップを示すテスト内容の実体は存在しないので当然テストは失敗しますが、どんなテストコードを作るべきかは以下の図のようにBehatがSuggestしてくれます。 この内容をstepディレクトリ以下に拡張子.phpのファイルを作って貼りつけましょう。

貼りつけたらもう一回実行します。

テストコードを実装
あとはテストコードの中身を書いていけば良いでしょう。 普通にTesting_Seleniumの関数を使えば良く、もちろん画面キャプチャを取得したりもできます。
< ?php
$steps->Given('/^私はGoogle日本語版サイトにアクセスします$/', function($world) {
$world->selenium = new Testing_Selenium("*firefox", "http://www.google.co.jp/");
$world->selenium->start();
$world->selenium->open("http://www.google.co.jp");
$world->selenium->waitForPageToLoad("30000");
});
$steps->And('/^私は検索ボックスに "([^"]*)" と入力します$/', function($world, $arg1) {
$world->selenium->type("q", $arg1);
$world->selenium->captureEntirePageScreenshot(__DIR__."/1.png", "");
});
$steps->When('/^検索ボタンを押します$/', function($world) {
$world->selenium->click("btnG");
$world->selenium->waitForPageToLoad("30000");
$world->selenium->captureEntirePageScreenshot(__DIR__."/2.png", "");
});
$steps->Then('/^その結果画面には "([^"]*)" と表示されます$/', function($world, $arg1) {
try {
assertEquals(true, $world->selenium->isTextPresent("もしかして: Chrome 神ブラウザ"));
} catch (PHPUnit_Framework_AssertionFailedError $e) {
array_push($world->selenium->verificationErrors, $e->toString());
}
});
$steps->Given('/^ブラウザを終了します$/', function($world) {
$world->selenium->stop();
unset($world->selenium);
});
?>
以上ができたら実行してみましょう。

画面のキャプチャも取得できています。

なお、動作させるには、supportディレクトリのphpスクリプト内で、Testing_Seleniumをrequire_onceしておく必要があります。 Testing_Seleniumは、pearではなく、Seleniumの本家サイトのダウンロードリンク( http://code.google.com/p/selenium/downloads/list )からselenium-remote-control-1.0.3.zipを取得し、その中に同梱されているものを取得したほうが良さそうです(pearで導入したのですが、やたらと実行に時間が掛かりました。理由は調べていませんが)。
それでは。
アジャイルコーチングやトレーニングを提供しています
株式会社アトラクタでは、アジャイル開発に取り組むチーム向けのコーチングや、認定スクラムマスター研修などの各種トレーニングを提供しています。ぜひお気軽にご相談ください。
詳細はこちら