終電23時15分って早くね?

都内のIT企業で働くカラオケ大好きエンジニアの雑記

Laravel Meetup Tokyo Vol.6 に行ってきた!

だいぶ遅くなってしまいましたが、Laravel Meepup Tokyo Vol.6に行ってまいりました。
で、LTの機会をいただいたので、「LaravelアプリケーションをSeleniumでテストしてみた」というのを発表してみました。

f:id:blue_goheimochi:20150710013154p:plain

が、結論から言うとLaravel関係なくSeleniumの話やんけーって感じの内容だったのでどうなのかな・・・と思ったのですが、
ちょっとですがTwitterで反応していただりとかしてよかったです!笑
一応スライドとサンプルを公開しておきます・・・

実際、当日にはサンプルが間に合わずデモができなかったのですが、
サンプルをあげましたのでそちらで確認してみてもらえばなーと思います。

スライドはこちら。


サンプルのコードはこちら。github.com

サンプルの内容

●動かし方

コードをGitHubから持ってきてもらい、

$ vagrant up

$ vagrant ssh

$ cd /vagrant/src/

$ vendor/bin/phpunit

でテスト実行の確認までできます。

f:id:blue_goheimochi:20150709152823p:plain

テスト中に取得されるスクリーンショットが、/vagrant/src/tests/screenshotのディレクトリの中にできていると思います。

●何をやっているの?

PHPUnitからSelenium Serverを通してFirefoxを起動しブラウザテストをしています。

Selenium Serverのインストール&実行やFirefoxのインストールなど、
もろもろはChefのレシピを書いていてそっちがやってくれます。

ぶっちゃけ大変なのはその辺のサーバー環境の設定で、
それさえできていればSelenium Serverを用いたテストは割と簡単です。

●必要な設定は?

-サーバーの設定
サンプルではCentOSを使用しておりますが、
サーバー用途のだと当然ディスプレイとかの設定がないので、
仮想のディスプレイをXvfbを利用してエミュレートする必要があったりで、
以下のインストールが必須です。

Selenium Server
・Xvfb
Firefox

正直サンプルを作るにあたりこの部分が一番時間かかりました。笑
実際の設定内容についてはChefのレシピを見ていただければと・・・

PHPUnit周りの設定

  • composer.jsonの修正
"require-dev": {
    "phpunit/phpunit": "~4.0",
    "phpspec/phpspec": "~2.1",
    "phpunit/phpunit-selenium": ">=1.3.1"
}

require-devの部分に"phpunit/phpunit-selenium": ">=1.3.1"を追記しています。
phpunitからSelenium WebDriverのAPIを使うために必要です。

  • テストケースの作成

PHPUnit_Extensions_Selenium2TestCaseをextendしたテストケースを作成します。

<?php
class WebTest extends PHPUnit_Extensions_Selenium2TestCase
{
    protected function setUp()
    {
        $this->setBrowser('firefox');
        $this->setBrowserUrl('http://www.example.com/');
    }

    public function testTitle()
    {
        $this->url('http://www.example.com/');
        $this->assertEquals('Example WWW Page', $this->title());
    }

}
?>

https://phpunit.de/manual/current/ja/selenium.html#selenium.selenium2testcase.examples.WebTest.php

上記ページの引用ですがもっとも簡単な感じだとこんな風です。
http://www.example.com/を開いて、タイトルタグが「Example WWW Page」であるかをみるテストですね。

$this->setBrowserUrl('http://www.example.com/');でURLを設定しているので、
$this->url('http://www.example.com/');は$this->url('/');でも大丈夫です。

●後はPHPUnitを実行するだけ

後はphpunitを実行するだけです。

サーバーの設定さえしっかりできてれば、結構簡単にやれちゃいます。
そしてやっぱりLaravelである必要はなくて(笑)、
↑のテストケースでも$this->setBrowserUrl('http://www.example.com/');のURLを変えれば、
実際はどんなサイトでもテストできちゃいます。
(※他の人のサイトにはやらな・・(ry)

なので、既存のWebアプリケーションあるけどUnitテストそろえるのつらいな・・・
とかそういう状況であればSeleniumを使ったE2Eのテストからはじめてみるのもいいのかなぁ・・・
とか思っていて、実際にそういう方向から個人的には攻めたりもしています。

●Laravel特有の設定

とはいえLaravelでやった感を出したかったので、いくつかLaravel用に設定した部分を書きます。

-ArtisanコマンドとかをPHPUnit_Extensions_Selenium2TestCaseをextendしたテストケースでも使う。
LaravelでUnitテストを書くとするとtestディレクトリの中のTestCase.phpをextendして使うかと思います。
そうすることで、Artisanコマンドなどが使用できるようになるかと思うのですが、
PHPUnit_Extensions_Selenium2TestCaseを直接extendしてしまうともちろん使えないので、
Illuminate\Foundation\Testing\TestCaseと同じような構成をとるために、
src/tests/TestCaseSelenium.phpにTestCaseSeleniumクラスを作成して、
TestCaseクラスを使うときと同様にLaravelの機能が使えるようにしています。

この辺はもうちょっといいやりかたがある気がするので誰か教えてください・・・

-testingの環境変数の設定

テスト用の環境変数としてtestingを利用しています。
sqliteのファイルの切り替えなどを行いたいためですが、
SeleniumのテストでFirefoxからアクセスする場合当然ですが、
phpunit.xmlに設定しているenvは適応されません。

ですので、

というような感じで、VirtualHostに対する環境変数Apatchで設定しています。

SetEnv APP_ENV testing
SetEnv SQLITE_FILE_NAME testing.sqlite

ドメインを切るのってなんかスマートじゃない気はしますが・・・

というのがLaravel特有の設定かなーと思うところでした。

以上でーす。


ちなみに・・・

2015年7月18日(土)に「Laravel Meetup Tokyo Vol.7」が開催されるようです。
現時点でちょっと空きがあるみたいですので、
興味ある方はぜひ行ってみてはどうでしょうか??

laravel.doorkeeper.jp