ホーム > タグ > CakePHP

CakePHP

大人数の開発合宿に最適な、山木旅館に行ってきた

Atami yamaki

もし、あなたが1-byte.jpの読者であれば、先日、CakePHP温泉部が開催されたことを知っていると思います。

CakePHP温泉部とは何ぞや?という方は、上記の記事を見てください。
今年は、このCakePHP温泉部員一同、熱海に行ってきました。

部員の皆さんととても楽しい時間を過ごさせて頂いたのですが、それと同じぐらい素晴らしかったのがお世話になった旅館
恐らく、熱海で大人数の開発合宿をするとすれば、ここしかないでしょう

熱海温泉の山木旅館

今回、CakePHP温泉部の舞台となったのが、”山木旅館“です。

この旅館は熱海駅から、車で5分ほどの場所に位置します。

山木旅館の位置

周りは温泉街で、静かなところです。

山木旅館周辺の風景

素晴らしい館内

素晴らしい“の意味を、はき違えないでください。
最新のホテルやホテル旅館、ビジネスホテルと比べないでください。
素晴らしいのは、その温泉旅館らしさです。

山木旅館の個室

良いでしょう。
温泉に来た感覚をしっかり、味わえます。
こんな旅館なのだから、部屋が小さい?
そんなことはありません

山木旅館の大きな部屋

じゃあ、インターネットが繋がっていない?
いいえ、しっかりインターネット回線も完備されています

開発風景

CakePHP温泉部では、2階にある3部屋を全てお借りしました
準貸し切り状態です。
1部屋は開発部屋として、残り2部屋は寝室として利用させて頂きました。

おかげで皆さん、睡眠も開発も集中して行えたはずです(睡眠は少し怪しいですが)

3つの風呂

開発合宿で必要なのは温泉
これが一番、重要です。

山木旅館では、3つの風呂があり、時間帯によって、男性と女性風呂が入れ替わります
もう一つは、家族風呂で自由に使って良いそうです。

spa2

CakePHP温泉部では、皆さん、朝風呂もしっかり味わっていました

夕食と朝食

1泊2日の宿泊では、通常の旅館と同様に、夕食と朝食を用意してくれます

山木旅館の夕食

海鮮を中心とした、素晴らしいメニューでした。

このような素晴らしい旅館で、CakePHP温泉部の2日間を、楽しく過ごせました。
1泊2万円と、他の旅館から比べると、少し高いです。
しかし、その価値は十分にあります

今回、私がCakePHP温泉部で使用する旅館を調べたのですが、

  • 部屋でインターネットが使える
  • 10人以上入る大部屋がある

この2つの条件を満たす旅館は、ここしかありませんでした
10件以上、電話をして調べました。しかし、インターネット回線がフリースポットだったり、会議室でしかインターネットが使えなかったり、とこの条件に合う旅館はなかなか見つかりませんでした。

開発合宿でこの2つの要素は、とても重要でしょう。

せっかくの合宿なので、徹夜で開発がしたい。
せっかくの合宿なので、皆とワイワイしながら開発をしたい。

これらを叶えてくれるのが、山木旅館です。

熱海で開発合宿をするときは、是非、山木旅館へどうぞ。

CakePHP温泉部の参加報告は、@binbin4649さんが書いてくれています。
こちらも併せて、どうぞ。

トリビア共有なんかよりも、100倍面白いガセビア共有gasevist

gasevist_logo.png

  • 【マカーの本当の意味】
    • 熱狂的なマクドナルドの信者のことを指す。
  • 【タイタニック2】
    • 今年夏公開される名作タイタニックの続編であるタイタニック2の主演女優はパリス・ヒルトン、主演男優はゾマホンである。
  • 【法改正により】
    • 本年度から法改正により豚の生姜焼きを食べるときには、その都度役所で申請手続きが必要となった。違反した場合には仮釈放なしの無期懲役となる。
  • 【アンパンマンのチーズ】
    • 実はチーズは血統書付きのスーパードッグ
  • 【gasevist VS trivist】
    • 実はトリビア共有サイト”trivist“よりもガセビア共有サイト”gasevist“のほうが100倍面白い

どうでしょう。
どれが本当のトリビアか、わかりましたか?

ま、全てガセなんですけどね。
最後のガセビアは、今後本当になるかもしれません。

こんなネタを共有できるガセビア共有サイトgasevist“を立ち上げました。

今日は、こんなくだらないgasevistが出来るまでを記事にします。

トリビア共有サイト”trivist”の記事がホッテントリ入りする

先日書いたこの記事がはてブのホッテントリ入りしました。

ちょっとだけ狙ってタイトルを付けたので、”はてブ100ぐらいはいくかな“と考えていました。
しかし、蓋を開けてみてびっくりしました。

  • はてブ: 455ブックマーク
  • 記事のページビュー: 8,271PV

前回の記事を見た方がいないかもしれませんが、ここでお礼を言っておきます。

いつも応援、ありがとうございます。

この記事とトリビア共有サイトtrivistを立ち上げたときは、まだ、ガセビア共有サイトgasevistのことは頭にありませんでした

トリビア共有サイト”trivist”にあるはてブがつく

トリビア共有サイトtrivist自体にあるコメント付きのはてブがつきます。

  • tktk3 うそくせぇボタンが欲しい
  • unkology がせぇボタンが欲しい

がせぇボタン?うそくせぇボタン?

確かに、Webからの投稿だと、それが嘘だか、本当だか、わかりません
中には嘘のトリビアもあるかもしれない。
そのようなトリビアを判断するボタンが欲しいという要望です。

しかし、ここであるアイディアが生まれます。

トリビアを集めるよりも、ガセビアを集めるほうが100倍面白いのでは?

ガセネタを投稿出来るサイトがあれば面白いと、コメント付きのはてブで気がついた訳です。

1日でガセビア共有サイト”gasevist”を作ってみた

この記事を書く前の記事のタイトルが、このサブタイトルです。
しかし、ガセビア共有サイトgasevistは、トリビア共有サイトtirivistをベースにほとんど変更していません。
設定を変更するためのプレフィックス定数を追加しただけ。
当たり前の記事になってしまうので、このタイトルは却下されました

しかし、実際にgasevistは、ソースコードの変更からサーバの設定まで1日で完成しました
これもある意味、前回の”ソースコードを書かない“方針の延長です。

開発の話を少し

特に目新しいことはしていないのですが、開発周りの話をしておきます。

gasevisttrivistはまったくソースコードが同じです。
サイトの判定には、アプリケーションのルートディレクトリの”GASEVIST”ファイルを使っています。
GASEVISTファイルがアプリケーションルートに存在すれば、gasevistになり、存在しなければ、trivistになります。

ソースコードに設定値を用意しても良いのですが、開発時に逐次書き換えるのが面倒なのでこうしています。
GASEVISTファイルをgitの管理下から取り除き、開発時は

touch GASEVIST

とか、

rm GASEVIST

なんてコマンドを打って切り替えてます。

デプロイはCapistranoで自動化されています。
今回は、Capistranoのレシピに設定値を1つだけ追加しました。
この設定値が存在した場合は、アプリケーションルートで”touch GASEVIST“が自動で実行されます。

さらにソースコードには、以下の行が追加されました。

if (file_exists(APP . 'GASEVIST')) {
    define('PREFIX', 'gasevist_');
}

あとは、切り替えるファイルや設定値の前にPREFIXを付けるだけです。
例えば、ロゴならこんな感じです。

<a href="/"><img src="/img/<?php echo PREFIX; ?>img_logo.gif" /></a>

今回、変更したのはビュー側のみです。
こういった切り分けがしっかり出来るのも、MVCフレームワークの強みでしょう。

これでソースコードの変更が終わったので、後はさくらサーバにVPS追加の申し込みを。
設定は前回、紹介したセットアップスクリプトを使います。

trivistと同じサーバに載せても良かったのですが、”月1000円ぐらい良いか“と新しくVPSを作りました。
Capistranoとセットアップスクリプトで、そんなに設定に時間が掛からないですしね。
それに、月1000円ならAdsenseで回収できます

これでガセビア共有サイトgasevistが完成です。

しかし、良い時代ですね。
アイディアもWebから、その実現もWebで出来ます

特にインフラ周りの進化がすごい。
一昔前に、Webサイトを一つ立ち上げようと思ったら、こんなに格安にしかも、こんなに速く作れなかったはず
自宅サーバでやるにしても、その管理が大変ですからね。
さくらサーバVPS、様様です。

次は、”VPSのまとめ“でも記事にしましょうか。

gasevistもよろしくお願いします。
trivistと違って、簡単に記事を投稿できるので、気軽にどうぞ。
クスっと笑えるガセビアをお待ちしております。

gasevist_logo.png
『gasevist』ガセのトリビア・雑学の共有サイト

1週間でトリビア共有サイト”trivist”を作ってみた

trivist_logo.png

ここのところ、ブログの更新ツイッターのつぶやきも完全にストップしていました。
集中力のない@tfmagicianにしては珍しいことです。

何をしていたか。
こんなウェブ・サービスを作っていましたよ。

実はこれ、作成期間1週間です。

シンプルなサイトなので、恐らく、開発に慣れた人なら1週間は余裕でしょう。
今日は、まだフレームワークを使った開発、あるいはウェブ・サービスの開発自体に慣れていない人に向けて、高速開発に関するtipsを紹介します。

高速開発とは何か考える

rapid_development.png

まず、高速開発を可能にする”最強最大の魔法“を考えましょう。
それはこれです。

コーディングしない

コーディングしないで、システムが出来ればなんと良いことか!
これはエンジニアにとって、当たり前のことです。
しかし、これを念頭に置くのと置かないのでは、まるで開発速度が違ってきます

できるだけ、怠慢を考えます。

面倒だから、俺はコーディングしたくないんだよ!

これで良いんです。

フレームワークを使う

cake-logo.png

trivistではフレームワークとして、CakePHPを採用しています。

フレームワークの効果は説明するまでもないでしょう。
様々な機能がパッケージングされており、高速開発を可能にします

また、フレームワークに乗ることで、複数プロジェクトで利用可能な共通資産が作成可能です。
それが次の”プラグインを使う“です。

プラグインを使う

development_with_plugin.png

大抵のフレームワークには、プラグインの機能が備わっています。
このプラグインを活用することで、高速開発が可能です。

例えば、検索エンジン用のサイトマップ
trivistのように自動でページが増えていくサイトは、自動でサイトマップを生成する必要があります
MVCのフレームワークを使ったことがある人は、この処理がすぐにイメージ出来ます。

  1. モデル: id一覧の取得
  2. コントローラ: id一覧からURLを生成する
  3. ビュー: サイトマップの吐き出し

こんなところでしょう。
プラグインを知らない人は、この処理をプロジェクト毎に毎回作成するか、コードを前のプロジェクトからコピーするかのいずれかです。
しかし、プラグインを知っていれば、これらの処理をどんなプロジェクトでも使えるように共通化することが出来ます。
共通化したコードは、pluginsディレクトリに放り込むだけ。
あとは、configディレクトリに設定ファイルを書いておしまいです。

これなら、ほとんどコードを書かなくて済みます。
さらに、プラグインがしっかりテストされていれば、アプリケーションにおけるこの部分のテストは、ほぼ省略出来ます

trivistでは、以下のプラグインを使っています。

この中で特に強力なのが、CakePHP-Twitter-API-PluginTagsPluginです。

CakePHP-Twitter-API-Pluginは、TwitterのOAuth認証が2行で書けます
(自身のユーザテーブルにデータを格納する処理は別途必要ですが)

TagsPluginは、簡単にタグ付けとそのタグクラウドを実装できます
タグ登録時の分割処理も自分で書く必要がありません。
いつもの感覚でデータを保存すると、勝手にタグ付けして、勝手にタグクラウドを作ってくれます。

UtilsPluginのCsvImportBehaviorも便利です。

と、話出したら止まらないので、ここまでにします。
よくある機能は自分で実装する前に、プラグインを探してみましょう

ブログパーツを使う

development_with_widgets.jpg

ブログパーツも活用しましょう。
最近のウェブ・サービスで必要となるのが、ソーシャルメディアのコメントを表示する機能検索機能です。
trivistでは、以下のブログパーツを活用しています。

ソーシャルメディアのコメントを取得するのって、結構面倒なんですよね。
対応するサービス分のコードを書く必要がある
また、データが膨大に増えていくのも気になります。

Zenbackは、各ページのソーシャルメディアのコメントを自動で表示してくれるブログパーツです。
jsのコードを貼り付けるだけのお手軽実装です。
これで、どれだけ工数が削減できることか。

検索機能は、全文検索に対応させる必要があります。
その上、検索結果のランク付けも必要です。

そこはもう、本業のGoogleさんに任せてしまいましょう。
Googleカスタム検索も導入は簡単。
これで、検索実装からも解放されます。

このように、ソースコードだけでなく、外部サービスも活用します
アクセスの少ない立ち上げ当初は、これで十分かと。

自動化する

auto_deploy.png

ここまで来たら、サーバも晒します

さくらサーバVPS標準のCentOSでなく、Ubuntuを使っていることにはいくつか理由があります。

  • 最新のパッケージや比較的マイナーなパッケージを、自分でビルドせずに使える
  • セットアップスクリプトをUbuntu 10.04用に書き溜めてある

特に大きいのは、2つ目です。
セットアップスクリプトを書き溜めることで、サーバのセットアップを効率化します

先程の構成を作るには、apache_phpスクリプトとmysqlスクリプトを実行して、設定ファイルを少し変更するだけです。

また、アプリケーション自体のデプロイは、Capistranoのレシピを使います。
CakePHP用のレシピを作ってあるので、それを適用するだけで、自動デプロイ環境が完成です。

サーバ関連の作業で重要なのは、一回こっきりの作業をしないことです。
大抵の作業は、必ずと言っていいほど再び行います。
それを見越して、予め準備しておきましょう

どうでしょうか。
1週間でウェブ・サービスを立ち上げられる気がしてきましたか。

とにかく、あるモノをとことん利用しましょう
あなたの欲しいモノは、恐らく世界の誰かがすでに作っています
せっかく、公開されているのに使わなければ損です。
それが自分の要求を満たさなくても、改造することで自分の要求を満たせないか、考えてみましょう。
自分で作るよりも、そっちのほうが絶対に早いです。

最後に、trivistの応援もお願いします!
うまく起動に乗れば、もっと機能を拡張したいと考えています。
もっと、共有機能を充実して、仲間内で楽しめるサイトになれば、と。
どんなトリビアでも良いので、投稿お願いします

trivist_logo.png
『trivist』おもしろいトリビア・雑学を紹介!

[イベント告知] この春はCakePHP温泉部でゆったりと

cakespa.jpg

かなり、告知が遅れてしまいましたが、スタッフとして宣伝記事を書いておきます
しかも、募集締め切りまであと4日しかない
本当はすぐに記事にしようと思っていたのですが、何かと忙しく。

何の話…?
そう、CakePHP温泉部のお誘いです。
温泉に入ってゆっくりしよう“という会です。

第1回CakePHP温泉部を振り返りながら、この会の内容を紹介してみます。

箱根と温泉

CakePHP温泉部は、今年が第2回目

去年が記念すべき第1回目です。
去年のCakePHP温泉部は写真の通り。

photo_mt_fuji.jpg

え、なんで富士山

photo_hotel.jpg

それに、CakePHP温泉部の看板を持った和気あいあいとした集合写真。

富士山は開催場所である箱根から帰る途中に撮ったモノ。
CakePHP温泉部の看板を持った集合写真は、旅館を後にするときにスタッフの方が撮ってくれたモノです。

第1回CakePHP温泉部は、これぐらいフリーでノープランな会でした。
ちょっとした発表もしましたが、勉強会より格段にゆるい形で行われました。
(そもそも、MASA-Pさん以外、発表資料をCakePHP温泉部のために用意していなかったし!)

CakePHP + My Development Story

これが私の去年の発表資料です。
レベルが低く、ちょっと恥ずかしいです。

この資料も、行きのMASA-Pさんの車の中で作りました。
あの時は渋滞で遅れて、スタバでこれを作ってたっけ。

スタッフ・ミーティングも1度しかしていないし、やることも大して決まっていないし
2日目なんて特にノープラン
あ、これ以上言うと逆に来る人が少なくなりそうですね。

とにかく、”CakePHP温泉部はとーってもゆるい会ですよ。“というのを知ってもらいたいのです。

小田原とかまぼこ

もはや、タイトルが意味不明です。
しかし、去年の参加者は思い出して、懐かしめる(笑える)はずです。

kamaboko.jpg
鈴廣かまぼこの里

帰りに、小田原のかまぼこの里に寄りました。

ちょうど時期的にはバレンタインデー。
バレンタインチョコならぬ、バレンタインかまぼこが売られていました。
写真がないのが残念ですが。

この企画も初めからあった訳でなく、@hidetoshingさんの提案で決まりました。

私は、参加者の半分以上と初対面でした。
恐らく、他の方々もそうだったはず。

それが何故だか、こんな(?)かまぼこ館に行くぐらい仲良くなっていまいました
これも温泉効果でしょう。

おまけのCakePHP

もう、CakePHPはある意味”おまけ“です。
とはいえ、ちゃんとCakePHPトークでも盛り上がりました。

第1回CakePHP温泉部では、主にCakePHPで作られたCMSを触って楽しんでいました。

特にBaserCMSは盛り上がりました。
皆でわいわいと協力しながら、BaserCMSの環境を準備したり。
XAMPじゃ駄目だ、MAMPを使え、いやいや仮想化でしょう。
なんて話をしたり。

最近はMacユーザが多いですが、CakePHP温泉部では半分ぐらいがWindowsユーザでした。
そのおかげか、BaserCMSの区切り文字定数DSに関するバグを発見出来ました。
ある意味、BaserCMSのテスト大会になっていましたね。

この話は@konsanさんの記事を読むとわかります。

これで、CakePHP温泉部の概要はわかったのではないでしょうか。
主催者MASA-Pさんの言う通り、

温泉に入って日頃の疲れを癒す

がこの会の目的なんです。
温泉に浸かりながら、ゆっくり、ゆったり、まったりとCakePHPトークでもしましょう。

こんなゆるい会で大丈夫か“と思った方もいるでしょう。
しかし、今回は前回の反省を踏まえてプランニングしています。
恐らく、前回よりは内容的に有意義になるはず。
前回のいいところを残しつつ、もうちょっと温泉部としての成果物を出せれば良いな“と考えています。

こんな会なので、誰でも大歓迎です!
CakePHPを触ったことがない人でも大丈夫です。
興味があれば参加してみてください。
色々と勉強になると思いますよ。

参加したい人はMASA-Pさんのブログからどうぞ。
締切りは10日まで、残り枠は4名程度です
応募はお早めに。

それでは、CakePHP温泉部で会いましょう!

php Conference Japan 2010に行くあなたのための予習と復習

php_conference_japan_2010.png

php Conference Japan 2010“が開催されますね。

詳しくはこちらをどうぞ。

今回はPHPの生みの親”Rasmus Lerdorf“さんがやってきます。
普段、何気なく使っているPHPを作った人に会う、これもまた、世界が広がりそうですね。

講演の情報や、タイムテーブルは公式サイトにお任せするとして、今回、1-byte.jpでは過去の”php Conference Japan”と今回講演があるいくつかのPHPに関連する技術について取り上げます。
今回、初めて”php Conference Japan”について調べたのですが、日本でのPHPの歴史がわかってなかなか面白いですよ。

過去のphp Conference Japan

まずは復習です。

“php Conference Japan”、実はもう11回目になります。
昨年は10周年を迎え、facebookやsymfonyのデベロッパを呼び、盛り上がったようです。

今回、ビジネスデイテックデイに分かれて開催していますが、これも昨年から。
規模が徐々に大きくなっているのがわかります。

可能な限り、過去の”php Conference”のページを集めてみました。

  • php Conference 2000
  • PHP4の最新バージョンの紹介、XMLへのPHP応用が紹介されています。XMLは今やWeb APIで当たり前に使われてますね。

  • php Conference 2002
  • PHP5の紹介が入っています。発表者がGREEの藤本真樹さんです。当時はアストラザスタジオに所属していますね。

  • php Conference 2003
  • テンプレートエンジンSmartyの発表が入ってきます。PHP5がもう少しでリリースされるということで、この年もPHP5が取り上げられています。

  • php Conference 2006
  • ここでフレームワークの発表が入ってきます。藤本真樹さんの発表があります。グリーのCTOになった翌年ですね。

  • php Conference 2008
  • ぐるなびの開発事例、サイボウズ、楽天におけるPHPの利用、CodeIgniterの発表があります。この年はLTもあります。

  • php Conference 2009
  • この年からphp Conferenceが2日に分かれます。ビジネスデイはGREEの田中良和さんの発表が、そしてWordpressの発表があります。テックデイはCakePHP/Agavi/CodeIgniterなどのPHPフレームワークの発表が多く見られます。

テンプレートエンジンSmartyの事例2003年PHPフレームワークの講演が行われるようになってるのが2006年から。
また、GREEが”php Coference“と一緒に成長して見えるのも興味深いところです。

そして、ページの雰囲気からも、時代が感じ取れます(笑)

php Conference Japan 2010

過去の話はこんなところにして、今回の”php Conference Japan 2010“の予習をしていきましょう。

先ほども述べた通り、今回は”ビジネスデイ“と”テックデイ“に分かれています。


ビジネスデイでは、システム開発・サービス提供企業の経営者の方や、ディレ
クション・マネジメントを行われている方向けに「オープンソーシャルとPHP」
をキーワードに、市場のニーズの把握やソーシャル・プラットフォームのアプリ
ならではの特徴や運用ノウハウなど、ソーシャルアプリを展開していくために
有益な情報を得られる様々なセッションがあります。


テックデイでは、エンジニア向けに「次の世代のPHP」をテーマに、PHPの生みの親
Rasmus Lerdorf氏をお招きして、PHPの歴史から現在、未来に関してご講演頂きます。
また、今では使うことが当たり前になりつつある各PHPフレームワークの最新情報や、
世界で5億人以上が利用している超巨大SNS「Facebook」の技術者による、同社が使用
しているPHP高速化ツール「HipHop」の講演など、PHPの最先端技術動向を紹介する
セッションが並ぶ、密度の濃い一日となっております。

PHPカンファレンス2010 ウェブサイト本オープンより引用

個人的に興味があるのは以下のセッションです。

  • ビジネスデイ 14:45 – 15:20 : 新しいPHPアプリケーションのテスト手法
  • テックデイ 10:30 – 11:15 : 基調講演
  • テックデイ 11:15 – 12:00 : フレームワークアップデートLT
  • テックデイ 13:00 – 14:30 : HiPHoP for PHP

ビジネスデイは現時点で半分ほどしか内容が決まっていません。
分かっている中では、”新しいPHPアプリケーションのテスト手法“のセッションは気になるところです。

テックデイのセッションは現時点でLT以外、ほとんど決まっています。
Rasmus Lerdorfさんの講演HiPHoPの紹介フレームワークアップデートの3つが目玉でしょう。
それぞれ見ていきましょう。

Rasmus Lerdorf

php_rasmus_lerdorf.jpg


ラスマス・ラードフ(Rasmus Lerdorf, 1968年11月22日 – )はデンマーク系カナダ人のプログラマで、プログラミング言語PHPの最初のバージョンであるPHP/FIの開発者。また彼は、アンディ・ガトマンズ、ゼーブ・スラスキーによるPHPの後継バージョンの開発にも携わり、その発展に寄与した。

ラスマス・ラードフ – Wikipediaより引用

引用にある通り、PHPの初期バージョンの開発者です。
恥ずかしいことに、この”php Conference Japan”の記事を書くために情報を調べるまで、PHPを作った方の名前を知りませんでした(汗)
PHPer失格です…。

最近、話題になったニュースだとこんなものがありました。

現在は、WePayというサービスのエンジニアとして働いているようですね。

また、こんな名言集もあるようです。

ふむ…。

HiPHoP

php_hiphop_logo.jpg


HipHop transforms your PHP source code into highly optimized C++ and then compiles it with g++ to build binary files. You keep coding in simpler PHP, then HipHop executes your source code in a semantically equivalent manner and sacrifices some rarely used features – such as eval() – in exchange for improved performance.

Facebook sees about a 50% reduction in CPU usage when serving equal amounts of Web traffic when compared to Apache and PHP. Facebook’s API tier can serve twice the traffic using 30% less CPU.

hiphop-php – GitHubより

PHPerなら誰しもが使いたい(であろう)HipHopです。
facebookが開発したPHPをC++に変換してしまう恐ろしいプロジェクト

詳しくは”php Conference Japan 2010″でCakePHPの発表をしてくれる@yandoさんが翻訳を上げてくれていますのでこちらを。

フレームワークアップデート

下記は全て公式サイトへのリンク。

PHPフレームワーク、こんなに種類があるんですね。
CakePHP/symfony/Zend Frameworkはもちろん、GREEが使っている和製フレームワークEthnaも気になりますね。
LTなので、内容の濃さは気になりますが、要チェックです。

簡単にですが、“php Conference Japan 2010″の予習と復習はこんなところです。
ま、ここまで調べておいて、私はまだ行くかどうか決まっていないのですけどね。

季節外れのお祭り – PHPMatsuri

php_matsuri.jpg

10月に季節外れのお祭りがあります。
全てのPHPerのための祭典、PHP Matsuriです。

ご存知の方も多いと思いますが、昨年の同月にCakeMatsuriTOKYO2009というCakeBakerのためのイベントがありました。

このイベント、無料、低価格の勉強会が多い中、参加費が2日通しで約2万円と高価格でした。
しかしながら、2日間で参加人数100名以上、ワークショップあり、CakePHPの事例ありで大盛況に終ったイベントでもあります。

もちろん、私もこのイベントには参加させて頂き、恥ずかしい内容でLT枠で講演しました。
このイベントで知り合った方は、今でもTwitterや他のイベントで仲良くさせて頂いています。

イベントの盛り上がりとその規模の大きさは、青年団と参加者の方々のブログを見ればお分かりになると思います。

さらに見たい方はこちらのフォーラムをどうぞ。

このCakeMatsuriが進化し、パワーアップしたのが今回のPHP Matsuriです!

PHP Matsuriとは

詳しい内容は以下の公式サイトを見て頂くとして、ここでは公式サイトの内容とその見所をまとめてみます。

PHP Matsuriではいくつかの枠に分かれているようです。

  1. ハッカソン
  2. ワークショップ
  3. 講演

ハッカソンがベースとなり、参加者は自由にワークショップや講演を聞く形式を取ります。

ハッカソンとは何?という方は居ないと思いますが、一応説明を引用します。

A hackathon, a hacker neologism, is an event when programmers meet to do collaborative computer programming. These events are typically between several days and a week in length. A hackathon refers not simply to one time hacks, but to a specific time when many people come together to hack on what they want to, how they want to – with little to no restrictions on direction or goal of the programming.

Wikipediaより


PHPMatsuriはハッカソン形式のイベントです。ハッカソンはhackとmarathonを合成した造語で90年代末からアメリカのインターネット企業が始めたのが発祥と言われています。学生、個人など幅広くのエンジニアがPCを持ち寄りさまざまな技術情報を交換し夜を徹して開発を進め、翌日に成果を講演しあうのが典型的なスタイルです。

公式サイトより

決められた時間で”自分の作りたい何か“を一致団結、みんなでワイワイしながら作る。
まさにハック + マラソン
PHP Matsuriでは朝10時から翌日12時の間で開発が行われるようです。
みんなで面白いものを作って、盛り上がろう!という感じですね。

最後に3分間で講演し、ハッカソン賞ドキュメント賞パフォーマンス賞という3つの賞もあるらしいですよ。
商品もあるんでしょうか?

このハッカソンだけでも十分、盛り上がりそうですが、それと平行して見所のある”ワークショップ“と”講演“があります。

講演

lihium_cakephp_symfony.png

PHPフレームワークに関わるコアデベロッパーの方の講演が特に見所です。

現在、公式サイトで載っているのは以下の方々の講演です。
コアデベロッパーを始めとした海外の方の講演は、同時翻訳もしてくれるようですよ。

公式サイトから紹介文を引用します。

  • Nate Abeleさん (@nateabele, Lithium公式サイト)
    • CakePHPの開発に4年に渡って貢献したリードデベロッパとして知られる。その中で全く新しい構造を追求したフレームワークの開発を着想し当初はcake3として開発を開始。その後、Lithiumとして独立に至る中心的な役割を果たす。ニューヨーク在住、趣味はギター。
  • Joël Perrasさん (@jperras, NERDERATI)
    • オープンソースに7年以上関わり、CakePHPのコアデベロッパでもあり、Lithiumの創設メンバーとしても活動。最近はNoSQLに関する活動にも尽力。カナダ在住。今回が2度目の来日。
  • Graham Weldonさん (@predominant, Graham Weldon)
    • CakePHPの中でも特に要望の高いメンテナンスに継続的に携わり、またCakePHPを活用するCakeDCの一員としても活動中。昨年の来日以降、日本語も学習中。オーストラリア在住。
  • Kris Wallsmithさん (@kriswallsmith, Kris Wallsmith)
    • symfonyのプロジェクトにてリリースマネージャを務める。多忙な中、緊急来日での講演。アメリカ在住。

Lithiumの講演”フレームワーク嫌いの人の為のフレームワーク Lithium“は是非聞いてみたいところですね。
Baker必見かと。

詳しくはこちらのタイムテーブルから。

ワークショップ

workshop.jpg

ワークショップではコアデベロッパーの方々から直接指導してもらえるようです。
こんな機会滅多にありませんよね。

現在、公式サイトのタイムテーブルに載っているのは以下のワークショップです。

  • Symfony2 ワークショップ by Kris Wallsmith
  • CakePHP ワークショップ by Graham Weldon
  • Lithium ワークショップ by Nate Abele & Joel Perras

個人的にはやはり、Nate AbeleさんとJoel PerrasさんによるLithiumのワークショップが気になるところ。
これまた、Bakerには外せないワークショップだと思います。

ただし、ワークショップは通訳がつかないそうですよ。
しかし、自分の世界を広げるチャンスですね。

こんな熱のあるイベント、今まであったでしょうか。

2日間のハッカソンコアデベロッパーの方のワークショップと講演2〜3人部屋に押し込められての泊まり込み(いや、ちゃんとした広い部屋でしょう。冗談です。)、…どれも魅力的です。
個人的には2万円の価値は十分にあるかと。

と、ここまで盛り上げておいてあれなのですが、私は行けません。
私の分まで楽しんできて欲しいので、こんな記事を書いてみました。
そして、来年また開催してもらうために…。

ぜひ、皆さんで盛り上げてください!

最後にイベントの概要を載せておきます。

[イベント概要]

  • 日程: 2010年10月2日(土) 10:00 〜 2010年10月3日(日) 17:00
  • 会場: 晴海グランドホテル
  • 参加費用: 22,000円(会場利用料、食事4食、宿泊費込み)
  • 募集人数: 100名

注意: 宿泊前提のため、1日だけの参加は出来ないようです。

9月31日からチケットが販売されています。残りどれぐらいなのでしょうか?
チケット購入はこちらからどうぞ!

あ、ちなみにこの公式サイトはCakePHPのCMS”Croogo“で出来てるそうですよ。
さすが、PHP Matsuriですね。

CakePHPを使ったテスト駆動開発

ブログ初ポストはCakePHPを使ったテスト駆動開発です。

CakePHPはユニットテストとしてSimpleTestに対応しています。
SimpleTestをインストールするだけで、モデルやコントローラ、シェル、ルーティングクラスなどのユニットテストが出来るようになります。

今日はこのCakePHPとSimpleTestを使ってテスト駆動開発の流れを説明します。
ただ、僕自身テスト駆動開発を学んだのは去年のCake祭りなので、至らない点が多々あります。
もし何かあれば、コメントでご指摘ください。

今更感もありますが、この場を借りてCake祭りでテスト駆動の指導をしてくださった、@sizuhikoさんに感謝します。

開発手順

まずは開発手順を示します。少し細かいですが、テスト駆動では以下のような順で開発していきます。

  1. 設計する。
  2. テストケースを書く。
  3. テストケースをデバッグする。
  4. コードを書く。
  5. テストケースを実行する。
  6. コードをデバッグする。
  7. テストケースを全て通す
  8. コードが完成する。

コードとテストケースが分かれていること、それに始めにある程度設計してしまうのがポイントです。
設計といっても、私がやるのは白紙のA4用紙にクラスとメソッド名を書き出すぐらいです。
こうして置くと、テストケースもコードも書きやすくなります。

これだけ見ても、実感がないと思うので実例で説明していきます。

ランキングモデルの開発

良くある例としてCakePHPを使ったランキングを作ります。
といっても全てを作る時間はないので、ランキングデータを取り扱うランキングモデルをテスト駆動開発で作ります。

設計

モデル名やスキーマを次のようにします。

  • モデル名 : Ranking
    • addGood : goodを追加するメソッド
    • getGoodTitles : goodの順にデータを取得するメソッド
  • テーブル名 : rankings
    • id : 主キー
    • good : 良いと思った人の数
    • title : ブログのタイトル

ブログにgoodボタンをつけて、それを押すとスキーマのgoodが1増えるイメージです。
例としてはありがちですが、facebookの「良いね!」機能から考えました。

今回は書きませんが、コントローラからaddGoodメソッドやgetGoodTitlesメソッドを呼びます。

テストケース・コーディング

設計が決まったらテストケースを書いていきます。さっそく書き始めたいですが、その前に色々とやることがあります。
空の状態(CakePHPのappディレクトリ)からの開発を想定してますので、モデルやテーブルを作る必要があります。

まず、データベース設定をして、この画面が出るようにしましょう(設定の仕方は省略します)。

startup.jpg

次はschema.phpを作りましょう。schema.phpはCakePHPでデータベースのスキーマを管理出来るファイルです。
ここにスキーマ情報を書き込んでおけば、データベースのマイグレーションが簡単になります。

cake schema generate

Welcome to CakePHP v1.3.2 Console
---------------------------------------------------------------
App : ranking
Path: /home/tfmagician/ranking
---------------------------------------------------------------
Cake Schema Shell
---------------------------------------------------------------
Generating Schema...
Schema file: schema.php generated

schema.php

<?php
/* SVN FILE: $Id$ */
/* Ranking schema generated on: 2010-07-13 17:07:41 : 1279010981*/
class RankingSchema extends CakeSchema {
  var $name = 'Ranking';

  function before($event = array()) {
    return true;
  }

  function after($event = array()) {
  }

}
?>

まだ、データベーステーブルを作っていないので空の状態でテンプレートが出来上がります。
ここに設計したスキーマ情報をプロパティとして加えます。

  var $rankings = array(
    'id'    => array('type' => 'integer',  'null' => false, 'default' => NULL, 'key' => 'primary'),
    'title' => array('type' => 'string',   'null' => false, 'default' => NULL, 'key' => 'index'),
    'good'  => array('type' => 'integer',  'null' => false, 'default' => 0),
    'indexes' => array(
      'PRIMARY' => array('column' => 'id',    'unique' => 1),
      'title'   => array('column' => 'title', 'unique' => 0),
    ),
    'tableParameters' => array(
      'charset' => 'utf8',
      'collate' => 'utf8_general_ci',
      'engine'  => 'MyISAM',
    ),
  );

これを元にCakePHPにテーブルを作らせます。

cake schema create

Welcome to CakePHP v1.3.2 Console
---------------------------------------------------------------
App : ranking
Path: /home/tfmagician/ranking
---------------------------------------------------------------
Cake Schema Shell
---------------------------------------------------------------

The following table(s) will be dropped.
rankings
Are you sure you want to drop the table(s)? (y/n)
[n] > y
Dropping table(s).
rankings updated.

The following table(s) will be created.
rankings
Are you sure you want to create the table(s)? (y/n)
[y] >
Creating table(s).
rankings updated.
End create.

これで指定したスキーマのテーブルが出来ているはずです。phpmyadminなどで確認しておきましょう。

次にテストで使うコードとモデルのコードをbakeで作成します。

cake bake model

Welcome to CakePHP v1.3.2 Console
---------------------------------------------------------------
App : ranking
Path: /home/tfmagician/ranking
---------------------------------------------------------------
---------------------------------------------------------------
Bake Model
Path: /home/tfmagician/ranking/models/
---------------------------------------------------------------
Possible Models based on your current database:
1. Ranking
Enter a number from the list above,
type in the name of another model, or 'q' to exit
[q] > 1
Would you like to supply validation criteria
for the fields in your model? (y/n)
[y] > y

Field: id
Type: integer
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
1 - alphanumeric
2 - between
3 - blank
4 - boolean
5 - cc
6 - comparison
7 - custom
8 - date
9 - decimal
10 - email
11 - equalto
12 - extension
13 - inlist
14 - ip
15 - maxlength
16 - minlength
17 - money
18 - multiple
19 - notempty
20 - numeric
21 - phone
22 - postal
23 - range
24 - ssn
25 - time
26 - url
27 - userdefined
28 - Do not do any validation on this field.
... or enter in a valid regex validation string.

[28] >

Field: title
Type: string
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
1 - alphanumeric
2 - between
3 - blank
4 - boolean
5 - cc
6 - comparison
7 - custom
8 - date
9 - decimal
10 - email
11 - equalto
12 - extension
13 - inlist
14 - ip
15 - maxlength
16 - minlength
17 - money
18 - multiple
19 - notempty
20 - numeric
21 - phone
22 - postal
23 - range
24 - ssn
25 - time
26 - url
27 - userdefined
28 - Do not do any validation on this field.
... or enter in a valid regex validation string.

[19] >
Would you like to add another validation rule? (y/n)
[n] >

Field: good
Type: integer
---------------------------------------------------------------
Please select one of the following validation options:
---------------------------------------------------------------
1 - alphanumeric
2 - between
3 - blank
4 - boolean
5 - cc
6 - comparison
7 - custom
8 - date
9 - decimal
10 - email
11 - equalto
12 - extension
13 - inlist
14 - ip
15 - maxlength
16 - minlength
17 - money
18 - multiple
19 - notempty
20 - numeric
21 - phone
22 - postal
23 - range
24 - ssn
25 - time
26 - url
27 - userdefined
28 - Do not do any validation on this field.
... or enter in a valid regex validation string.

[20] >
Would you like to add another validation rule? (y/n)
[n] >
Would you like to define model associations
(hasMany, hasOne, belongsTo, etc.)? (y/n)
[y] >
One moment while the associations are detected.
---------------------------------------------------------------
Please confirm the following associations:
---------------------------------------------------------------
Would you like to define some additional model associations? (y/n)
[n] >

---------------------------------------------------------------
The following Model will be created:
---------------------------------------------------------------
Name:       Ranking
DB Table:   `rankings`
Validation: Array
(
    [title] => Array
        (
            [notempty] => notempty
        )

    [good] => Array
        (
            [numeric] => numeric
        )

)

Associations:
---------------------------------------------------------------
Look okay? (y/n)
[y] >

Baking model class for Ranking...

Creating file /home/tfmagician/ranking/models/ranking.php
Wrote `/home/tfmagician/ranking/models/ranking.php`
SimpleTest is not installed. Do you want to bake unit test files anyway? (y/n)
[y] > y

You can download SimpleTest from http://simpletest.org

Baking test fixture for Ranking...

Creating file /home/tfmagician/ranking/tests/fixtures/ranking_fixture.php
Wrote `/home/tfmagician/ranking/tests/fixtures/ranking_fixture.php`
Bake is detecting possible fixtures..

Creating file /home/tfmagician/ranking/tests/cases/models/ranking.test.php
Wrote `/home/tfmagician/ranking/tests/cases/models/ranking.test.php`

(あ、忘れていましたが、cakeコマンドはcakeコンソール(cake/console/cake)のことです。適宜置き換えてくださいね。)

これでテストケースとフィクスチャ(後で説明します)、モデルのテンプレートが完成しました。
あとはコーディングしていくだけです。

と、一つ忘れていたことがありました。SimpleTestのインストールです。
SimpleTestはアプリケーションのvendorsか、CakePHP本体と同じ階層のvendorsに配置します。

cd vendors/
wget http://downloads.sourceforge.net/simpletest/simpletest_1.0.1.tar.gz
tar zxvf simpletest_1.0.1.tar.gz
rm simpletest_1.0.1.tar.gz

配置したら、ブラウザからtest.phpにアクセスします。

test.php
test_php.jpg

左メニューからApp > Test Casesをクリック
test_cases.jpg

コンテンツからmodels / Rankingをクリック
ranking_test.jpg

bakeで作ったテンプレートのテストが実行されているのがわかります。
まだ何も書いていないですが、テンプレートのテストが実行され、1件のテストケースが通っています。

これでテストが実行出来るようになりました。テストケースをコーディングします。
テストケースはさきほどのbakeの最後に書かれている通り、tests/cases/models.ranking.test.phpにあります。
これを元に、オリジナルのテストケースをコーディングします。

tests/cases/ranking.test.php

/* Ranking Test cases generated on: 2010-07-13 18:07:16 : 1279014616*/
App::import('Model', 'Ranking');

// テストケース用のクラスはTestCaseで終わる名前にし、CakeTestCaseを継承する。TestCaseより前はファイル名と一致させる。必ずしもテストするクラス名と一致させる必要はない。
class RankingTestCase extends CakeTestCase {
  var $fixtures = array('app.ranking');

  function startTest() {
    $this->Ranking =& ClassRegistry::init('Ranking');
  }

  function endTest() {
    unset($this->Ranking);
    ClassRegistry::flush();
  }

  /**
   * addGoodメソッドのテスト
   */
  // testで始まるメソッドがテストとして実行される。テストメソッドは必ずtestでメソッド名を始めること。
  function testAddGood() {
    debug('addGoodメソッドのテスト');

    // 正常: id=1のデータに対してaddGoodメソッドを実行する。
    // 確認: 返り値がtrueであること、goodがプラス1されていること。
    $ret = $this->Ranking->addGood(1);
    $this->assertTrue($ret);
    $params = array(
      'conditions' => array('id = ' => 1),
      'fields' => array('good'),
      'recursive' => -1
    );
    $data = $this->Ranking->find('list', $params);
    $expected = array(1 => 2);
    // この部分がテスト: 期待する結果とメソッドの戻り値を比較して等しいならテストが通る。等しくないならテストが失敗する。
    $this->assertEqual($expected, $data);

    // 異常: id=2のデータに対してaddGoodメソッドを実行する。
    // 確認: 返り値がfalseであること。
    $ret = $this->Ranking->addGood(1);
    // この部分がテスト: メソッドの戻り値がfalseならテストが通る。false以外ならテストが失敗する。
    $this->assertFalse($ret);

  }

  /**
   * getGoodTitlesメソッドのテスト
   */
  // testで始まるメソッドがテストとして実行される。テストメソッドは必ずtestでメソッド名を始めること。
  function testGetGoodTitles() {

    // 正常: 取得件数を5件に設定し、getGoogTitlesメソッドを実行する。
    // 確認: 上位から5件のデータが取得出来ること。
    $ret = $this->Ranking->getGoogTitles(5);
    $expected = array(
      array(
        'Ranking' => array(
          'id' => 1,
          'title' => 'title1',
          'good' => 10,
        ),
      ),
      array(
        'Ranking' => array(
          'id' => 2,
          'title' => 'title1',
          'good' => 9,
        ),
      ),
      array(
        'Ranking' => array(
          'id' => 3,
          'title' => 'title1',
          'good' => 8,
        ),
      ),
      array(
        'Ranking' => array(
          'id' => 4,
          'title' => 'title1',
          'good' => 7,
        ),
      ),
      array(
        'Ranking' => array(
          'id' => 5,
          'title' => 'title1',
          'good' => 6,
        ),
      ),
    );
    // この部分がテスト: 期待する結果とメソッドの戻り値を比較して等しいならテストが通る。等しくないならテストが失敗する。
    $this->assertEqual($expected, $ret);

  }

}
?>

コメント中にも書いてありますが、assertメソッドがテストです。
例えばassertEqualメソッドは、「2つの変数が等しいことを期待する」という意味になります。
この期待に応えない(変数が等しくない)場合、テストは失敗します。後でスクリーンショットで示します。

またテストメソッドが実行される順は、次のようになります。

  1. startTest
  2. テストメソッド1(testで始まるメソッド)
  3. endTest
  4. startTest
  5. テストメソッド2(testで始まるメソッド)
  6. endTest

なのでこのテストケースでは、以下の順でテストが実行されます。

  1. startTest
  2. testAddGood
  3. endTest
  4. startTest
  5. testGetGoodTitles
  6. endTest

必ずstartTestとendTestメソッドが呼ばれる点がポイントです。これらのメソッドでクラスの初期化などの処理を実施し、テストを書きやすくします。

このテストではデータの挿入、更新を行っています。しかし、さきほどテーブルを作ったばかりなのでデータはまだ入っていないはずです。
逐一、テストの度に手作業でデータを入れてもいいのですが、それはとても面倒です。そこでフィクスチャという機能を使います。

CakePHPのフィクスチャ機能はテーブルのデータをPHPのコードとして書いておくと、勝手にテスト前にデータを挿入してくれます。
挿入のタイミングはテストメソッド(テストケースの中のtestで始まるメソッド)毎です。つまり、特定のテストメソッドでデータを更新したり削除しても、次のテストメソッドでは新しいデータが入っています。
これを知っておくと、テストケースを書くのが楽になります。

tests/fixtures/ranking_fixture.php

/* Ranking Fixture generated on: 2010-07-13 18:07:16 : 1279014616 */
class RankingFixture extends CakeTestFixture {
  var $name = 'Ranking';

  // スキーマ情報をfieldsプロパティとして書いておきます。indixesはインデックスの指定、tableParametersはテーブルの設定値です。schema.phpを同じ形式で指定します。
  var $fields = array(
    'id' => array('type' => 'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
    'title' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'index'),
    'good' => array('type' => 'integer', 'null' => false, 'default' => '0'),
    'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'title' => array('column' => 'title', 'unique' => 0)),
    'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'MyISAM')
  );

  // データをrecordsプロパティとして書いておきます。
  var $records = array(
    array(
      'id' => 1,
      'title' => 'title1',
      'good' => 5,
    ),
    array(
      'id' => 2,
      'title' => 'title2',
      'good' => 6,
    ),
    array(
      'id' => 3,
      'title' => 'title3',
      'good' => 7,
    ),
    array(
      'id' => 4,
      'title' => 'title4',
      'good' => 8,
    ),
    array(
      'id' => 5,
      'title' => 'title5',
      'good' => 9,
    ),
    array(
      'id' => 6,
      'title' => 'title6',
      'good' => 10,
    ),
  );
}
?>

フィクスチャの書き方は省略します。ただ、連想配列で指定するので少し考えれば意味はわかるかと思います。
書き方がわからない場合はschema.phpを参考にしてください。

テストケースのデバッグ

作成したテストケースをデバッグします。まだモデル側のコードは書いていませんが、まずはtest.phpを開いてみましょう。

test.php
ranking.jpg

メソッドをまだ用意していないため、モデルにクエリを発行されてしまっています(CakePHPでは存在しないメソッドは全てクエリとして扱われます)。
これではデバッグにならないので、モデルにメソッドだけ用意しましょう。

models/ranking.php

<?php
class Ranking extends AppModel {
  var $name = 'Ranking';
  var $displayField = 'title';
  var $validate = array(
    'title' => array(
      'notempty' => array(
        'rule' => array('notempty'),
        //'message' => 'Your custom message here',
        //'allowEmpty' => false,
        //'required' => false,
        //'last' => false, // Stop validation after this rule
        //'on' => 'create', // Limit validation to 'create' or 'update' operations
      ),
    ),
    'good' => array(
      'numeric' => array(
        'rule' => array('numeric'),
        //'message' => 'Your custom message here',
        //'allowEmpty' => false,
        //'required' => false,
        //'last' => false, // Stop validation after this rule
        //'on' => 'create', // Limit validation to 'create' or 'update' operations
      ),
    ),
  );

  function addGood($id) {
  }

  function getGoodTitles($n) {
  }
}
?>

再度、test.phpを開きます。

test.php
test_debug.jpg

そうすると、一つだけクエリが発行されているのがわかります。
すでにお気づきの方がいるかもしれません。そうです、テストケースで実行しているRankigクラスのメソッド名がgoogTitlesとなっているのです。
よくあるtypoですね。修正し、再度テストケースを実行します。

test.php
test_debug_passed.jpg

これでテストケースのコードは大丈夫のようです。この段階でテストは通っていなくとも大丈夫です。
なんせ、まだ本体のコードを書いていないのですから。

コーディング

それでは本体のコードを書いていきます。先ほど追加した空のメソッドに以下のようにコーディングします。

models/ranking.php

  function addGood($id) {
    $this->id = $id;
    if(!$this->exists()) {
      return false;
    }
    return $this->updateAll(array('good' => 'good + 1'), array('id = ' => $id));
  }

  function getGoodTitles($n) {
    $params = array(
      'limit' => $n,
      'page' => 1,
      'order' => 'good DESC',
      'recursive' => -1,
    );
    return $this->find('all', $params);
  }

コーディングが完了したらtest.phpのページを再度開きます。

test.php
test_passed.jpg

テストが通ると、テストした件数と緑色のバーが表示されます。
この緑色のバーと作成したテスト件数があっていれば、テストは完全に通っています。

ここではあっさりテストを通してしまいましたが、実は1度のコーディングでテストが完了した訳ではありません。
この程度のコードでも2〜3度、テストを失敗し、コードを書き直しています。

やってみるとわかるのですが、テストケースがあることで簡単に、かつ手軽にコードを書き換えることができます。

テストケースを使ったテスト駆動開発を知るまでは、var_dumpを活用し、逐一途中のデータを見ながらコードを書いていました。
しかし、この方法だと仕様が自分の頭の中にしかないため、メソッドの機能が多様化してしまったり、想定しないバグに出くわしたりします。

テストケースを書くことで、頭の中にあるメソッドの仕様をコードとして書き出すことになります。
そうすることで、曖昧だった点や考慮しなければいけないケースも浮き彫りとなります。
さらにコードとして書き出すことで、メソッドを作る上での目標が定まり、コーディングしやすくなります。

テストケースというコードが増えるため、これを書くのを面倒に思ってしまいますが、この面倒さ以上のメリットがテスト駆動開発にはあると私は思います。

テスト駆動開発をする上でのポイント

最後に、テスト駆動開発でのポイントを書いておきます。参考にしてください。

  • テストケースを必ず始めに書く。
    • 後から書こうと思うと面倒くさくなる。また、後から書くと先ほど書いたメリットを受諾出来ない。
  • メソッド、クラスの機能追加時も必ずテストケースを書く。
    • テストケースも更新していかないと、せっかく書いたコードが無駄になる。テストケースはコードがしっかり動いていることの証拠である。
  • バグを見つけたときこそ、必ずテストケースを書く。
    • テストケースは上記と同様にコードがしっかり動いていることの保証である。
  • バグを見つけたときは、テストケースでしっかり対策する。
    • 統合テストでバグを見つけた場合はデバッグし、原因を見つける。その原因をメソッドレベルにまで落とし、そのメソッドのテストケースを書き、解決する。従ってテストケースも独立していることが重要である。
  • テストケースを出来るだけ独立させる。
    • 対象のメソッド、クラス以外の部分で仕様変更があった場合に、テストが通らなくなるのはテストケースのメンテナンスが面倒になる。出来るだけテストケースの対象を1つのメソッド、あるはクラスにしぼる。

これまでテスト駆動開発をやってきて学んだことを上げてみました。
テスト駆動開発で重要なことは一言で言うとメンテナンスしやすいテストケースを書くことだと思います。
テスト駆動開発をこれから始める方は、この点に注意すると、私の二の舞*1にならないかと思います。

ご参考になれば幸いです。

*1 テスト駆動開発を始めた頃は良かったのだが、その後メンテナンスが大変になった。結局、テストケースを全て捨てることに…。

ホーム > タグ > CakePHP

スポンサードリンク
書いている人
つぶやき
  • setup.pyのinstall_requiresにgitのリポジトリを指定したい。どうすればいいかな。 1 day ago
  • ツイッタークライアントを久々に開いたけど、なんか違和感。 3 days ago
  • 最近、イベント参加出来てないな(_ _) 3 days ago
  • More updates...
RSS 気になるニュース
過去の記事

ページの上部に戻る