Selenium + PHPUnitで簡単エンドツーエンドテストを実現する

 2012/08/16
このエントリーをはてなブックマークに追加

ここではSeleniumとPHPUnitを使って簡単にスモークテストを実現する方法を解説します。 基礎的な内容ですが、復習ということで。

下準備

  • FirefoxにSelenium IDEをインストールする
  • Selenium Serverを導入する(※ダウンロードへの直リンクはこちら)
どちらもhttp://seleniumhq.org/download/からダウンロード可能です。

Selenium IDEを使ったテストケースの作成

もうこれはあちこちのサイトで説明されているので特に説明の必要はないでしょう(笑) 簡単に言えば、Firefoxを起動し、さらにSelenium IDEをたちあげて、操作を記録していけば良いだけです。 参考サイト

テストケースを自動で実行する

ここまでの方法でFirefox上からHTML形式で作成したテストケースをSelenium IDE経由でいつでも実行できるようになります。 しかしこのやり方だと自らブラウザをたちあげてテストを実行しなければならず面倒です。 以下ではPHPUnitを使って連携する方法と、Selenium Serverの機能を使ってバッチ処理的に実行する方法を解説します。

PHPUnitと組み合わせる

PHPUnitと組み合わせて上記で作ったHTMLのテストケースを簡単に実行できます。

PHPUnitとPHPUnit_Seleniumの導入

このやり方ではPHPUnitとPHPUnit_Seleniumを利用するので、まだインストールしていない場合は以下の方法で導入します。

pear channel-discover pear.phpunit.de
pear channel-discover pear.symfony-project.com
pear install phpunit/PHPUnit
pear install phpunit/PHPUnit_Selenium

Selenium Serverの起動

起動は以下のようにします。

java -jar selenium-server-standalone-2.25.0.jar

Proxyの中にいる場合は

java -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=3128 -jar selenium-server-standalone-2.25.0.jar

のようにします。 以上で標準ではlocalhost:4444でSelenium Serverが起動します。

テストを作ってみる

さて先ほど作ったhtmlのテストケースを実行するテストを書いて見ましょう。 なお、先ほど作ったhtmlのテストケースを、このテストケースと同じディレクトリにあるhtmlフォルダに保存するか、以下の$seleneseDirectoryの値を作ったhtmlのテストケースが保存されているパスに書き換えてください。

class SeleneseTest extends PHPUnit_Extensions_SeleniumTestCase {

    public static $seleneseDirectory = "html/";

    protected function setUp() {
        $this->setHost("127.0.0.1");
        $this->setPort(4444);
        $this->setBrowser("*firefox");
        $this->setBrowserUrl("http://www.yahoo.co.jp/");
        $this->setTimeout(60000);
    }
}

以上ができたらテストを実行します。

phpunit SeleneseTest.php
PHPUnit 3.6.12 by Sebastian Bergmann.

..

Time: 39 seconds, Memory: 6.25Mb

OK (2 tests, 2 assertions)

はい。これでテスト通りました。ここでは$seleneseDirectoryで指定したパスの中にある拡張子がhtmlまたはhtmのテストケースを全て実行してくれます。 で、ここまでできればお分かりかと思いますが、

phpunit --log-junit=smoketest.xml SeleneseTest.php

としてあげればJUnit互換でテスト結果をXMLに出力できるので、簡単にJenkinsでテスト結果を出せるようになります。 ※詳細はPHPUnitのマニュアルにも記載があります。

なお、PHPUnitを使わないで実行するアプローチもありますので以下で説明します。

Selenium Serverの起動オプションにテストケースを設定する

以下のようにします。引数に-htmlSuiteを追加し、利用するブラウザ、開始URL、テストスイート名、結果出力ファイル名の順に指定します。テストスイートを指定しますので、最初に作ったテストケースをまとめるためのテストスイートを作っておいてください(Selenium IDEのメニューから「テストスイートに名前をつけて保存」をクリックして作成します。)

java -jar selenium-server-standalone-2.21.0.jar \
-port 4445 \
-htmlSuite "*firefox" "http://www.yahoo.co.jp" \
"./suite/TestSuite.html" \
"./result.html"

※先の例で既にSeleniumを4444番ポートで起動しているかもしれないのでサンプルとして起動ポートを4445にしています。なお、テストスイートを指定して起動した場合はテスト完了後にSelenium Serverは自動で終了します。

ここで出力されるhtmlは以下のようなものになります。

このhtmlのレポートをJenkinsに取り込むこともできます。それには、Selenium HTML Report Pluginを使います。詳細はこちら

まとめ

このようにhtmlで作ったテストケースでも簡単に自動実行できますし、Jenkinsに結果を取り込んだりできます。 画面回りのテストをコードを書いて作るのはコストが高いですが、Seleniumであれば比較的簡単につくれますので、スモークテスト用途等にも使えますし、特にレガシーコードを扱う場合には効果があると思います。 是非試してみてください。

なお、このアプローチで受け入れテストを全て自動化するのは現実的ではないことも多いです。というのも

  • 画面回りは変わりやすいこと
  • 開発前にテストを作るのが困難なこと
  • そしてテスト実行に時間がかかること
などが理由です。またhtmlのテストケースの場合、変数を外部から与えたりすることは得意でなく、処理を共通化することも困難なので、似たようなテストが大量にできてしまう問題もあります。したがってブラウザ経由のエンドツーエンドの受け入れテストをたくさん用意しなければならない場合は、htmlのテストケースではなく、WebDriverを叩くテストアプリケーションを書いた方が良いことも多いでしょう。Selenium IDEの場合は、各言語用のテストコードの出力も可能ですので、そちらを利用していくのが良いと思います。

またエンドツーエンドの挙動がガードできるようになれば、テストをもっとユニットレベルの段階で書くようにしていき(その過程でリファクタリングもある)テストにかかる時間を減らしたり、開発者にすばやくフィードバックが来るようにしていくことになります。

ちょっと上級編っぽい話は以下で書いてますのでご参考まで。 [PHP]BehatとSeleniumを組み合わせ受け入れテストを自動化する

 2012/08/16
このエントリーをはてなブックマークに追加