Technote

by sizuhiko

PHPカンファレンス2011に参加しました

<!– more –>今回のPHPカンファレンスは、久々の1日開催と、マルチトラックということで楽しみにしていました。

が、前日朝方までBarから帰してもらえない状況 :ko: で、数分遅刻した上にかなり眠い状態…

カンファレンスのメイントラックでは5.3, 5.4の話題が多く、若干のネタかぶり?という雰囲気もありましたが、PHPも便利になっていくねという確認ができました。 マルチトラックはかなりのチャレンジだったと思うのですが、オブラブなどでの経験からすると、事前にどのセッションに参加希望かだけでも聞いておくと違ったかなぁと。そのセッションに必ず参加しないといけない、という訳ではないのですが、そのセッションをどの会場でやるか、といった目安にはなるかなぁと。ただメイン会場に通訳さんがいたので、それほど柔軟にはできない事情もあったとは思いますが。

私は3つの目的でカンファレンスに参加しました。

  1. カンファレンスのセッションを聴きに
  2. LTでCakeBehatを紹介するために
  3. PHP Matsuri青年団として、Matsuriの宣伝を!

カンファレンスの感想

カンファレンスに関してはアジャイルやTDDのセッションがあったので参加してみようと思ったのですが、どうも「参考にならない人」条件に入っているようだったし、かなりの満員御礼状態で会場に入れないということで、ずっとメイン会場にいました。あ、フレームワークアップデートだけは6Fに移動して見ていました。フレームワークアップデートではLithiumやEthena(こちらはLTでsotarokがやっていましたが)がなくちょっと残念でした。あと昨年のフレームワークアップデートはもうちょっとバリエーション豊かだった気が(気のせいかもしれませんが)。
あと興味を持ったのはHadoopをPHPから操作できるHadooPHPかなぁ。プロトタイプ用ということだったけど、ちょっと試してみたいと思いました。

CakeBehatの紹介LT

スライドをアップしました。 Behat自体の認知度はだいぶ上がって来たと思うので、後はPHPMatsuriで背中を押せば使う人が増えるんじゃないかなぁ?LTの後でSymfony,Cake以外のフレームワークからも使いたいという書き込みがあったので、Matsuriで誰かチャレンジしないかな?と期待しています。

PHPMatsuriの宣伝

LTを5分ちょうどで終えて、3回の紹介、懇親会LTでくどいくらい宣伝させていただきました。

PHPcon当日はまだ申込ができなかったのですが、すでにPHPMatsuriサイトでは参加申込が可能となっています。海外から豪華ゲストもやってきますし、開発するも講演を聴くも、いろんな方向から楽しいイベントにしたいと思っていますのでぜひ参加の検討をお願いします。

CakeFest2011に参加してきました

<!– more –>

昨年のシカゴに続いて2度目の参加となるCakeFest2011。今回はイギリスのマンチェスターにて行われました。 昨年のLTに続き、今年はPechaKucha形式(20秒x20枚)でCakeBehatについての紹介と、LTで日本のLTタイマ係であるドラ娘の紹介という2本の発表を行ってきました。

9/2(金):移動日

昼頃成田を出発し、同日の夜に現地に到着しました。
途中ロンドンで乗り継ぎだったのですが、行く前にイロイロと調べたらロンドンの乗り継ぎはあまり便利ではないということを聞いていて、どうなることかと思っていました。実際、ロンドン空港に到着すると案内表示版には、ほとんど搭乗ゲートが出ていません。遠いゲートまでは25分もあるというのに…. 結局30分前ぐらいに15分程度のゲート案内が出て、移動しました。丸っきりの廊下でしたが、国内線なのでそんなものなのかな、と。

で、マンチェスター空港から電車でホテルへ移動してチェックイン。ホテルのバーではワークショップからの参加者や、既に到着していた@yanodo, @cakephper と合流し、GUINNESSで空腹を満たして寝ました。空港からホテルまで、途中何も食べるところがない(というかよくわからない)というのは誤算でした。

9/3(土):カンファレンス初日

会場は手前に電源の準備された丸テーブルと、階段状の客席になっていて、自由に座ります。PCを持ってワークショップに参加している人は割とテーブル席で、そうでない人は階段席という感じでした。昨年のシカゴは全てテーブル席でみんなPCを持っていたような気がしたので、ちょっと意外な光景でした。しっかり話を聞いたり議論したりする、という雰囲気は濃かったように思います。

今回のCakeFestは部分的に2トラックになっていて、私は主にメイン会場に居ました。初日は@yandoさんがCandyCane(RedmineをCakePHPで移植したもの)の発表をして大きな反響を得ていました。私も微力ながらCandyCaneの開発に携わっていたので、この反響の大きさは嬉しかったです。その後はPHPMatsuriのサイトでも利用しているCMS Croogoについて@fahadから発表がありました。fahadは現在ロンドンで働いているということで、同じ会社からは数名のCakePHP使いが参加していました。

午後は大混雑のMarkによるPHPUnitの話を聞くために奥の部屋(いわゆる会議室)に移動していました。

Pecha Kucha Talksでの発表

本編にも申し込んでいたのですが、そちらかは落選してしまったので、当日の昼休みに夕方から始まるPecha Kuchaに申し込みました。20秒でスライドが自動送りされるという、英語が堪能ではない環境では大変難しい状況だったのですが、何とか思いは伝えられ、当日の夜や翌日には何人かの人に興味を持ってもらえました。ただ海外でもテストを書くということはあまり浸透していないようで、BDDの前にまだTDDがねー的な話があったのも、そんなに日本の状況と変わりないのだな、と思いました。

Pecha Kuchaのスライドはコチラから参照できます。

休憩時間など

CakeFestではセッション間に30分以上の十分な休憩時間が用意されており、各々中庭で歓談したりバーでビールを飲んだりと、なかなか楽しい雰囲気でした。 バーには陽気なバーテンダーがいて、場を盛り上げてくれていました。

9/4(日):カンファレンス2日目

phpnutの基調講演、国際化対応、CakePHP2.0、コアデベロッパーによるパネルディスカッションと、主にCakeDCからの発表が多かった1日でした。またMongoDBを絡めた発表も2つあり、1つは日本から参加の@cakephperさんによるMongoDB Datasource。ちょうどメイン会場が国際化対応だったので見れなかったのですが、だいぶ盛り上がっていたようです。
お昼には恒例のリアルケーキも登場。ちょうどその場にいたコアデベロッパーが揃って記念撮影。左から2番目が国際化対応の発表をしたrenanでオランダで働いているそうです。ブラジル人でもある彼は、国際化対応について問題点と解決策をわかりやすく解説していました。これは日本語圏のユーザにとってもありがたいですね。どの国でも作られたプラグインなどが国際化考慮されていれば言語ファイルなどを用意するだけで良い訳ですし。

で、マンチェスターまで行ってLTの参加枠もあるなら、せっかくなのでLTもやってきました。昨年のLTが長い話を全然打ち切れなくてすっきりしないものになっていたので、日本ではLTのタイマ係=ドラ娘という役がありまして〜という発表をしました。スライドは昨晩から少しずつ作って、長い休憩時間も使い無事完成。LTだと自分のペースで話せるので少し楽です。CakeFest参加者にはDoraGirl, DoraMUSUMEというものをバッチリ印象づけて、このネタでさらに多くの人に声をかけてもらうことができました。あのアプリ(DoraGirl)はどこからダウンロードするの?どうやって使うの?とか。

CakeFestで得たもの

もちろん最新のCakePHP2.0情報を得たり、コアデベロッパーの発表を聴くということはとても有意義なことです。ただもちろん参加するにあたり、最低1つ以上質問をしたいし、発表もしたい。幸いCakeFestでは当日申し込みのPechaKuchaやLTなどで容易に発表可能(倍率1倍 w)ということもあり、昨年の5分から今年は12分弱という時間をもらうことができました。質問はもっとも内容が理解できたMarkのPHPUnitの話でアノテーションの使いどころなどに関して聞きました。

また発表や質問を通じて、コアデベロッパーにアイツは何者?とか、こういうことをやっている人、例えば私だとなんかやたらテストについて発表したり質問したりする人、という印象で持ってもらえていると思っています。(事実Markに関してはそういう風に声をかけてくれる。)

で、じゃぁすぐに何かに役立つわけではないかもしれないけど、何かコア部分に関してやりとりしたくなったときや、もちろん日本のイベントに来てもらえるということも、そういった事の積み重ねではないかなぁ、と思っているのです。ですので、来年は日本からより多くの参加者がCakeFestに行ってもらえると嬉しいなぁと思っています。

その他、雑多にふりかえると

ビールが安い!

例えばGUINNESSのパイントが約3ポンド。500しないぐらい。日本の半額以下ですね。これなら毎日相当量飲めそう。事実他のビールも含めだいぶいっぱい飲みましたが…

マンチェスター・ユナイテッド博物館がいい!

イギリスでのサッカーの歴史を感じる博物館で、展示内容もすばらしかったです。

あと全般、ずっと雨模様だったり、涼しかった(寒いに近いぐらい)だったり。 帰国日はマンチェスター空港からの出発が天候不良で1時間近く遅くなり、ロンドンに付いたら1時間半遅れ、3時間の乗り継ぎ時間があったのですが、おみやげ買ったりロンドン空港内の移動(すごい遠い)したりしていたら全く余裕がなく帰国便に搭乗となりました。ロンドン経由にするなら乗り継ぎ時間にかなり余裕を見ておいた方がいいなぁと感じました。

ロンドン空港はオリンピックに向けて、新ターミナルを作っていたりとまた大きくなる印象。さらに複雑になるのかなぁ〜

CakePHPアプリケーションをBehatでテストする

はじめに

Behatとは、Ruby on Railsでは有名なBDDフレームワークcucumberのPHP版クローンです。以前私が発表した資料が過去記事にありますので、詳しくはそちらを参照ください。

利点は、顧客が理解できるシナリオを自然言語(つまり日本語)で記述し、それ自体がテスト実行可能であるということです。

今までCakePHPアプリケーションのテストは単体テストではSimpleTest、ブラウザベースのテストはSeleniumを使うことが多かったと思いますが、これからはBehat/Minkによってテストの幅が広がるでしょう。

しかし、BehatはSymfonyベースで、これまでCakePHPのアプリケーションを実行するためのプラグインなどは準備されてきませんでした。そこで、「rake cucumber」に習い「cake behat」として実行できるシェルタスクを用意しました。

それが「CakeBehat」シェルです。

https://github.com/sizuhiko/CakeBehat

インストール

前提事項

  1. gitが利用可能なこと
  2. PHPUnitがインストールされていること
  3. CakePHPがインストールされていること
  4. MySQLなどデータベースがインストールされていて、テスト用データベースが準備されていること

導入

CakePHPのvendorsディレクトリへ移動して、以下のコマンドを実行してください。

git clone git@github.com:sizuhiko/CakeBehat.git
git clone git://github.com/Behat/Behat.git && cd Behat
git submodule update --init
cd ..
git clone git://github.com/Behat/Mink.git && cd Mink
git submodule update --init

すると、vendors 配下に CakeBehat, Behat, Mink の3つのディレクトリができているはずです。

次に、CakeBehat/vendors/shells から behat.php と behat.yml.default を CakePHPのvendors直下へコピーします。

すると、vendors直下には、behat.php, behat.yml.default, CakeBehat, Behat, Minkがあるはずです。

続いて、CakeBehat/features を CakePHPのappやcakeと同じディレクトリ階層にコピーします。

初期導入は以上で終了です。

環境設定

Behat/Mink環境設定

vendors直下にコピーしたbehat.yml.defaultをbehat.ymlにコピーします。

4行目に

      start_url: http://test.localhost:8888/application-name/

という設定があります。これはアプリケーションのルートパスを設定するもので、ホスト名、ポート番号、アプリケーション名などを指定します。ホスト名はできるだけtest環境と識別可能なものにしておく事がオススメです。

これでおわり?

基本的な環境設定は、ここまでで、behatは実行可能な状況になっています。では具体的にサンプルアプリケーションのコードを使って解説します。

サンプルアプリケーション(ブログ)

CakeBahet/sample の中にCookBookの「CakePHPブログチュートリアル」の初期状態(Postの一覧と詳細だけ)のコードを準備しました。

データベースの切り替え

config/database.phpはそのまま生成すると$defaultがあります。UnitTestを実施する場合などは$testを作成していることもあるでしょう。Behat/Minkはブラウザアクセスで実行されるので、工夫が必要になります。またテストデータの投入で$testを参照するので、必ず定義が必要になります。 そこで Bakery の「Easy peasy database config」にも書いてるように、環境によってデータベース設定が切り替えられるように対応します。

このサンプルでは、アクセスされたサーバ名を基準に切り替えるようにしており、test.localhost なら test用データベース、それ以外ならdevelopment用データベースを利用するようにしています。

hostsファイルに 127.0.0.1 localhost, test.localhost としておけば、test.localhostでアクセス可能になるでしょう。簡単ですね。

テストシナリオの記述

Behatのシナリオ記述は基本的にcucumberと同じです。もし基本的な記述方法がわからない場合は、達人出版社「はじめる! Cucumber」を読むと良いと思います。

ブログチュートリアルの一覧表示と、詳細表示のテストとして、以下のようなシナリオを書きました。

sample/features/posts.features

# language: ja
フィーチャ: ブログの記事を閲覧した
  なぜならブログの記事を閲覧することで、最新の情報を入手したいからだ

  背景:
    前提 ブログ記事に以下の内容が登録されていること:
      | タイトル | 本文 |
      | タイトル | これは、記事の本文です。 |
      | またタイトル | そこに本文が続きます。 |
      | Title strikes back | こりゃ本当にわくわくする!うそ。 |

  シナリオ: 記事一覧を閲覧できること
    前提 トップページ を表示している
    ならば "タイトル" と表示されていること
    かつ "またタイトル" と表示されていること
    かつ "Title strikes back" と表示されていること

  シナリオ: 記事の本文を閲覧できること
    前提 トップページ を表示している
    かつ "またタイトル" のリンク先へ移動する
    ならば "そこに本文が続きます" と表示されていること

どうですか?最低限の決まりがあるように見えますが、普通のドキュメントとして読む事も可能ですよね?少なくともプログラマでなければ読めないSeleniumのようなテストコードとは違うと思います。これがBehatの特徴でもあります。

Hint

Behat/Minkでどんなステップ記述が利用可能かどうかは、

cake/console/cake behat --steps --lang ja

のように実行すると一覧表示されます。

テストデータの登録

サンプルでは「ブログ記事に以下の内容が登録されていること:」のように記述しました。これは最初から用意されているものではなく、独自に定義する必要があるステップです。ステップは features/steps の下に phpファイルを作成すれば自動的に読み込まれ、利用可能になります。

sample/features/steps/posts_step.php

$steps->Given('/^ブログ記事に以下の内容が登録されていること:$/', function($world, $table) {
  $hash = $table->getHash();
  $world->truncateModel('Post');
  $post = $world->getModel('Post');
  foreach ($hash as $row) {
    $post->create(array('Post'=>array('title'=>$row['タイトル'], 'body'=>$row['本文'])));
    $post->save();
  }
});

ステップの雛形自体は、ステップが存在しないときにBehatを実行すると、以下のように画面表示されるので、そのままコピペして作成すると簡単です。

CakeBehatではテストデータを登録するのが容易になるように、Modelを取得できるようにしています。またテストデータを消去するためにtruncateできる仕組みも用意しました。

  1. データの削除:$world->truncateModel(‘Post’);
  2. モデルの取得:$post = $world->getModel('Post’);

後は、AAで書いた表をそのまま利用できる(1行目が自動的にタイトル行として解釈されています)ので Model->createとModel->saveを利用すれば、いつものCakePHPの感覚でデータを登録できるはずです。 データベースは自動的に$testで定義された宛先に接続するようになっています。

実行してみよう

cakeやappのディレクトリに移動して、以下のコマンドを実行します。

cake/console/cake behat

さいごに

基本的なアプリケーションであれば、テスト可能な状況になっていると思います。

何かあれば、CakeBehatをforkしてアップデートに参加してもらえればと思います。

現時点で気になっているのは、

  1. モデルの初期化を shells/behat.php の _loadModels() で実行しているのですが、App::objects('model’)でモデルの一覧を取得しているので、プラグインのModelまで初期化できていません。ここで初期化する理由は、Shell(CakePHP) -> Behat(Symfony) -> CakePHPのように呼び出されると、初期化されていないモデルが利用できないので、事前に全てClassRegistry::initしておくことで、この問題を回避しています。プラグイン内のモデルを使う場合は、この記述を変更して、プラグインのモデルも利用可能にする必要があります。
  2. テストデータの削除を明示的にtruncateModelしないといけない。本来は features/support/hook.php のフックポイントでtruncateModelを呼び出せるように仕込んでおきたかったのですが、フックポイントから呼び出すとSTRICTエラーが出てしまい、うまく動作しません。ということから、データ投入ステップで一度データを削除するように記述しています。
  3. GithubのReadmeとWikiがまだ未着手で。。

といったところです。

このネタで、CakeFestに応募しようと思うのですが、後9日か。。。

PHPカンファレンス関西に参加してきました

<!– more –>4/2に開催されたPHPカンファレンス関西に参加してきました。

実行委員の皆様お疲れさまでした。ものすごい楽しいイベントでした。

僕はLTでBehatの話をしたのですが、他のプレゼンテーションがとてもバラエティにとんでいて、とても勉強になったし、交流もできて良かったです。

プログラムの内容や、それぞれの内容は他の参加者の方が詳しく書いていたりするので、簡単にKPT形式で振り返っておきます。

※アンケート書いたけど、やっぱり落ち着いたところで考えると違いますね。

KEEP

  1. 前日入りは楽
  2. 会場がキレイ(税金がふんだんに投入されている感のある・・・以降自粛)
  3. 関西での大規模イベント(東京からの参加でしたが。。。)
  4. スムーズな進行、時間通りに進んでいて感動した
  5. 懇親会LTも大スクリーンで見やすい
  6. 懇親会の食事が美味しい
  7. ドラ娘がかわいい

Problem

  1. 電源が少ない。自分はAirだし、Wifiルータも10時間持つURoad-9000だったので大丈夫でしたが、全体的に困っていた人が多かった印象
  2. 欲を言えば2トラックぐらいあると良かったかも(もっとコード的な欲望がある人向けセッションみたいな)
  3. 16Fのレストランはテンパっていた w (本編に関係ないですが)
  4. 懇親会同一会場は待ち時間が微妙
  5. (本編LTで)ドラ娘の仕事が少なかった(懇親会では大変そうでした。お疲れさまでした)
  6. LT発表者が東方面だった

Try

  1. 次はハッカソン? (ザワっ
  2. 青年団も何か告知できるようにしておきたかった (謎
  3. また来年もあれば参加したい

で、スライドなんですが、いつものslideshareにアップしてたんですが、何度やっても失敗するようになったので、おさらばすることにしました(過去のファイルはそのまま置いておきますが)。取り急ぎ、MyOperaのストレージに置いたので、こちらをダウンロードして見てください。

また、懇親会のジャンケン大会で本をもらいました。

最後に、東京に帰る新幹線で、WiMAXルータURoad-9000がどのくらい使えるか検証してみました。

  1. トンネル以外は概ね問題なく接続でき、とても快適
  2. トンネル以外での不調エリアは、米原、浜名湖近辺だけ
  3. 上記いずれも体感です(ご了承ください)

ということで、N700系であればWifi使えるけど、それ以外どうする?といった場合、WiMAXも十分行けますよ、あなた。(宣伝)

Behatのインストールについての注意事項

<!– more –>4/2 に行われるPHPカンファレンス関西にて、BehatについてLTをすることになりました。

そこで最近Behatをダウンロードしてみたのですが、git submoduleでのSymfonyコンポーネントのインストールで問題がありますので、解決策を書いておきます。

  1. Behat 本体のインストール

    git clone git://github.com/Behat/Behat.git

  2. サブモジュールのインストール

    cd Behat git submodule update –init

とくに問題がなければ、しばらくして終了しますが、本稿執筆次点では以下のようなエラーで中断してしまいます。

Initialized empty Git repository in /Behat/vendor/Symfony/Component/Translation/.git/
remote: Counting objects: 220, done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 220 (delta 147), reused 141 (delta 94)
Receiving objects: 100% (220/220), 52.61 KiB, done.
Resolving deltas: 100% (147/147), done.
fatal: reference is not a tree: d5cdaba8550b7b99f37d2aad345dd8ebbe3efb9c
Unable to checkout 'd5cdaba8550b7b99f37d2aad345dd8ebbe3efb9c' in submodule path 'vendor/Symfony/Component/Translation'

そこで、エラーになったサブモジュールの変更ログを確認します。

git log --oneline -p -- vendor/Symfony/Component/Translation

上記コマンドを実行すると、以下のように表示されます。

85d8dac updated vendors
diff --git a/vendor/Symfony/Component/Translation b/vendor/Symfony/Component/Translation
index f70e0ba..d5cdaba 160000
--- a/vendor/Symfony/Component/Translation
+++ b/vendor/Symfony/Component/Translation
@@ -1 +1 @@
-Subproject commit f70e0ba1b04e7db4b3aa6d122470291d4fb34732
+Subproject commit d5cdaba8550b7b99f37d2aad345dd8ebbe3efb9c
da2503a updated submodules
diff --git a/vendor/Symfony/Component/Translation b/vendor/Symfony/Component/Translation
new file mode 160000
index 0000000..f70e0ba
--- /dev/null
+++ b/vendor/Symfony/Component/Translation
@@ -0,0 +1 @@
+Subproject commit f70e0ba1b04e7db4b3aa6d122470291d4fb34732

ここで表示されたログの1行目「85d8dac updated vendors」の85d8dacを使ってチェックアウトします。

git checkout 85d8dac~ -- vendor/Symfony/Component/Translation
git submodule update

こうすることで、サブモジュールのインストールが継続できます。

  1. 実行する

    bash-3.2$ ./bin/behat.php ……………………………………………………………. ……………………………………………………………. ……………………………………………………………………….

    36 scenarios (36 passed) 222 steps (222 passed) 0m7.045s

成功したら、インストールは完了です。