BehatとSeleniumを組み合わせ受け入れテストを自動化する

2011/02/12

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スクリプト内で、TestingSeleniumをrequireonceしておく必要がある。Testing_Seleniumは、pearではなく、Seleniumの本家サイトのダウンロードリンク( http://code.google.com/p/selenium/downloads/list )からselenium-remote-control-1.0.3.zipを取得し、その中に同梱されているものを取得したほうが良さそうだ。(pearで導入したのだが、やたらと実行に時間が掛かった。理由は調べていないけど)

最後に、Chromeマジいいよ。まじで。

2011/02/12

著作

寄稿

Ryuzeeについて

Latest post: