0:00:06.947,0:00:08.467 ユニットテストで人生に勝利する by Mark Story 0:00:08.467,0:00:12.843 ユニットテストは開発の中で大事なプロセスです 0:00:12.843,0:00:21.186 ユニットテストは手動でクリックするようなテストと違い 0:00:21.186,0:00:24.107 自動化されたテストです 0:00:24.107,0:00:27.402 今日は僕がどうしてユニットテストをしているか 0:00:27.402,0:00:31.169 また実際のテストの方法についてお話しします 0:00:31.169,0:00:34.899 テストしづらい部分をテストする方法や 0:00:34.899,0:00:47.973 テストを最新の状態に保つ Continuous Integration についてもお話します 0:00:47.973,0:00:52.009 大学を出てすぐにプログラミングを始めました 0:00:52.009,0:00:54.719 お金が必要だったので(笑) 0:00:54.719,0:01:01.123 CakePHPを使って2年半になります 0:01:01.123,0:01:07.070 DebugKit や ApiGenerator などのプラグインを作りました 0:01:07.070,0:01:10.465 普段は FreshBooks で働いています 0:01:10.465,0:01:13.613 オンライン上で請求書を発行するようなサービスで 0:01:13.613,0:01:16.673 そこではリードデベロッパをしています 0:01:16.673,0:01:18.830 ユニットテストは僕を素晴らしくしてくれるのでしょうか? 0:01:18.830,0:01:21.863 激しくその通りです 0:01:21.863,0:01:24.273 何故ユニットテストをするのでしょうか 0:01:24.273,0:01:37.430 余分な時間は掛かりますが、その他のコードが正しく動いているのを確認する為です 0:01:37.430,0:01:42.532 特に後になってから起きた問題を修正する時間を削減するのが主な理由ですね 0:01:42.532,0:01:47.073 何かを変更した後にそれまで動いていた部分が動いている事を確認する 0:01:47.073,0:01:50.320 何かを変更して動いていた物を壊してしまった事はある人はどれくらい居ますか? 0:01:50.320,0:01:53.617 (挙手多数) 0:01:53.617,0:02:06.505 テストを書けばそういう事は起きません 0:02:06.505,0:02:10.729 バグを見つけたらその部分のテストを書けば 0:02:10.729,0:02:14.017 同じバグが発生する事はありません 0:02:14.017,0:02:19.770 またユニットテストは複雑なコードの設計の助けにもなります 0:02:19.770,0:02:23.552 プログラムをシンプルな部品に分割する 0:02:23.552,0:02:33.004 例えば「CMSを作れ」という素晴らしいチケットがあった時 0:02:33.004,0:02:36.765 細かいテストにブレークダウンして 0:02:36.765,0:02:42.156 テストを一つづつパスさせれば、何かが動いた事になります 0:02:42.156,0:02:45.776 またテストは生きたドキュメントにもなります 0:02:45.776,0:02:52.110 内容を忘れてもテストを見ればわかります 0:02:52.110,0:03:01.063 また問題を早めに見つける事もできます 0:03:01.063,0:03:08.394 何か変なものをコードに入れてしまってもすぐにわかります 0:03:08.394,0:03:14.336 コードの確実性を高める事もできます 0:03:14.336,0:03:22.433 とにかく知っている範囲で動くようにテストを書きます 0:03:22.433,0:03:33.734 クリックしながらテストをすると3時間かけても 自分の所では動いたと思うとしか言えません 0:03:33.734,0:03:36.804 でも僕らには自動化された殺人兵器があります 0:03:36.804,0:03:44.561 自動化されたテストの利点はまさに自動化されている事です 0:03:44.561,0:03:49.168 CIもできますし、テストを素早く実行できます 0:03:49.168,0:03:56.033 変更をする度に5時間かけてクリックするのではなく 0:03:56.033,0:04:14.283 ボタンをクリックするだけで何か失敗していないかやきちんと動いているかが確認できますね 0:04:14.283,0:04:17.697 テストできるものは全てテストするべきです 0:04:17.697,0:04:20.458 夜中に問題を起こしそうなコード 0:04:20.458,0:04:24.178 問題が起きる恐怖を軽減する為にテストを書きましょう 0:04:24.178,0:04:36.872 また金銭に関わるようなコードにもテストを書けばユーザーやあなたが金銭を失わないようにできます 0:04:36.872,0:04:47.175 また以前にも問題が起きた壊れやすいコードにもテストを書きましょう 0:04:47.175,0:04:51.414 また手動でテストしにくいものにもテストを書きます 0:04:51.414,0:05:06.492 PDFの生成のように時間がかかる部分にテストを書いた事があります 0:05:06.492,0:05:09.217 またテストには異なる種類があります 0:05:09.217,0:05:14.965 ユニットテストと機能テスト、結合テストです 0:05:14.965,0:05:21.555 ユニットテストはアプリケーションの細かい部分のテスト 0:05:21.555,0:05:36.460 オブジェクトやメソッド、関数単位で正しい結果を返しているかなどをテストします 0:05:36.460,0:05:44.232 また多くの場合モックを使います これはテストしづらい部分をテストするのにとても便利です 0:05:44.232,0:05:51.291 テスト駆動開発をする際にもユニットテストは便利です 0:05:51.291,0:05:56.669 テスト駆動開発ではコードを書く前にテストを書きます 0:05:56.669,0:06:07.951 テストを書いて コードを書いて またテストを書いてコードを書く その繰り返しですね 0:06:07.951,0:06:12.877 テストが失敗するようなコードを本番環境向けに書かない 0:06:12.877,0:06:16.642 僕は普段、コードを書いてそれからテストを書きます 0:06:16.642,0:06:22.053 そしてテストが壊れないように余分なコードを消します 0:06:22.053,0:06:35.570 機能テストは部品が一緒にうまく動作するかをテストします 0:06:35.570,0:06:41.195 上位のオブジェクトから部品が正しく動いているかをテストする 0:06:41.195,0:06:53.747 例えばCakePHPもModelが変更されたら結合テストを行う 0:06:53.747,0:06:55.652 あなたが書いたコードだけなく データベースと通信する部分などが正しく動いている事をテストする 0:06:55.652,0:06:58.964 機能テストは比較的時間がかかります 0:06:58.964,0:07:03.234 多くのリソースやデータベースを使うからです 0:07:03.234,0:07:07.131 さらにはリモートのサービスを実行したりもします 0:07:07.131,0:07:11.372 ユニットテストは基本的に1つのクラスのテストです 0:07:11.372,0:07:14.222 細かい部品ごとに正しい動作をテストする 0:07:14.222,0:07:18.475 それをまとめてに行うのが結合テストです 0:07:18.475,0:07:21.974 テストをする時にはいくつかの課題があります 0:07:21.974,0:07:24.779 ちょっと水を飲みます 0:07:24.779,0:07:28.636 話すのが速すぎるかな? 大丈夫? 0:07:28.636,0:07:33.161 まずはテストを書くのに時間がかかる事 0:07:33.161,0:07:46.646 しかし同じバグを何度も修正するのはもっと時間がかかります 0:07:46.646,0:07:48.821 正しいテストを書けば同じバグはもう起こりません 0:07:48.821,0:07:52.187 テストは問題がある事しか証明しません 0:07:52.187,0:07:55.853 問題が無い事は証明しません 0:07:55.853,0:07:58.466 1つテストがあるのはバグが無いという意味ではなく、1つのバグがテストされたという事にしかなりません 0:07:58.466,0:08:06.591 またユニットテストはテストがある部分のエラーしか見つけられません 0:08:06.591,0:08:15.969 コンピューターはテストがある部分だけテストします 0:08:15.969,0:08:24.350 なのでありえるパラメータ範囲などもテストを書かないといけません 0:08:24.350,0:08:28.474 テストの利点はなんでしょうか 0:08:28.474,0:08:32.871 余分な手間が最初にかかりますが、問題を早く見つける事ができます 0:08:32.871,0:08:42.384 QAテスターや上司がクリックして「どうして壊れてるんだ」と聞かれる前に問題を見つけられます 0:08:42.384,0:08:45.234 またテストのプロセスを自動化する事が出来ます 0:08:45.234,0:08:57.288 自動化はすばらしいです フレームワークも色々な事を自動化してくれますが テストはもっと自動化してくれます 0:08:57.288,0:09:02.242 またユニットテストは結合テストに発展させる事もできます 0:09:02.242,0:09:09.913 セレニウムのスクリプトを書いてコンソールから 0:09:09.913,0:09:14.289 ブラウザでクリックするようなテストを実行できます 0:09:14.289,0:09:17.533 これはほんとに素晴らしいです 0:09:17.533,0:09:22.848 決められた仕様をテストにすれば 0:09:22.848,0:09:31.774 テストがパスすれば仕様を満たせている事が確認できます 0:09:31.774,0:09:38.958 以上でテストの素晴らしさの賞賛は終わりです 0:09:38.958,0:09:44.094 次にモックオブジェクトの話題 0:09:44.094,0:09:53.391 モックオブジェクトはテストしづらい部分をテストする際にとても便利です 0:09:53.391,0:10:06.340 個別のテストを書きづらい時にモックオブジェクトを使えば簡単になります 0:10:06.340,0:10:11.472 オブジェクト同士を呼び合わないようにテストさせる事ができます 0:10:11.472,0:10:16.752 オブジェクトがそれぞれ間違った方法で呼び出し合って 0:10:16.752,0:10:23.095 テストが失敗するのを防げます 0:10:23.095,0:10:27.022 またモックは実装前にオブジェクトの振る舞いを確認する助けにもなります 0:10:27.022,0:10:37.004 例えば何かのサービスにPOSTして結果を配列で返すようなクラスの場合 0:10:37.004,0:10:42.455 例えばそのサービスが友達のジョーが書くとしたそれがどうなるのか予測できません 0:10:42.455,0:10:52.116 必要な配列を返すモックがあればジョーの方で問題があっても関係ない 0:10:52.116,0:10:59.392 ジョーの部分が終ったらジョーがその部分に対してテストを書けばよい 0:10:59.392,0:11:03.680 そうすれば僕はジョーの所で何をやっているかは知らなくても大丈夫 0:11:03.680,0:11:10.112 モックをグローバル関数やグローバルなスコープで読み込まれるファイルに使えるでしょうか? 0:11:10.112,0:11:13.745 使えません 0:11:13.745,0:11:22.365 モックを使うにはクラスになっていて、処理がメソッドの中にある必要があります 0:11:22.365,0:11:26.067 モックはどういう時に使うべきでしょうか? 0:11:26.067,0:11:29.194 モックは外部と通信するようなコストが高かったり 危険の大きい時に使うのがベストです 0:11:29.194,0:11:39.760 テストを実行する度に顧客にEメールを送信なんて事ありえないよね(笑) 0:11:39.760,0:11:48.960 メール送信処理はサーバーとの通信などのコストも高い 0:11:48.960,0:11:53.011 そういった外部依存を少なくする 0:11:53.011,0:11:59.018 TwitterやPaypalなどと通信する部分にモックを使うのもパーフェクトな例 0:11:59.018,0:12:13.861 Twitterが落ちてしまうとコードが壊れていないのにテストが失敗してしまう 0:12:13.861,0:12:20.125 この部分にモックを使っておけばTwitterが落ちても開発を継続できる 0:12:20.125,0:12:26.020 また落ちた事が無いようなサービスにモックを使っておけば 0:12:26.020,0:12:35.220 そのサービスが落ちてしまった時に自分のコードに何が起きるのかを知る事ができる 0:12:35.220,0:12:45.604 例えばPaypalが落ちた時にコードが爆発してしまうのか そのまま動いてしまうかは知っておくべきだ 0:12:45.604,0:12:49.467 ユニットテストとモックを使えばこういった事態を想定できる 0:12:49.467,0:12:57.787 またユニットテスト中で不必要に大量にディスクに書き込みをしてしまう場合もモックにできる 0:12:57.787,0:13:01.565 データベースもご存知の通り遅いのでモックにできる 0:13:01.565,0:13:04.621 データベースに /dev/null でも使ってない限りはね (笑) 0:13:04.621,0:13:12.347 /dev/null はWEBスケーラブルだ (有名なジョーク) 0:13:12.347,0:13:19.779 データベースへの書き込みは遅くてコストかかるのでモックを使えばたくさんのテストを実行するのに便利だ 0:13:19.779,0:13:25.389 本当にデータベースに通信しなければいけない場合は別だけど 大抵の場合はそうじゃないね 0:13:25.389,0:13:38.601 クラスが2つある場合 それぞれが正しく呼び出し合っている事を確認することになる 0:13:38.601,0:13:49.724 その場合にスタブとしてモックを使う事ができる それぞれが期待する動作をモックに実装する 0:13:49.724,0:13:53.784 期待しないパラメータが呼び出されたらテストが失敗するようにしておく 0:13:53.784,0:13:57.336 そうやって問題の範囲を絞って 0:13:57.336,0:14:08.539 個別のコードが動くために必要な部分をスタブ化して扱いやすくする 0:14:08.539,0:14:20.415 そうすれば問題を分離できる 0:14:20.415,0:14:24.106 例えばこのメソッドがNullを返すとエラーが起きる時に 0:14:24.106,0:14:27.836 ファイルがおかしい時にNullになるなんて時にモックを使ってテストすれば問題を分離できる 0:14:27.836,0:14:33.019 どうやってモックを作るか 0:14:33.019,0:14:40.175 モックにするには依存関係を実行時に変更できる必要がある 0:14:40.175,0:14:48.140 僕が使っている3つの方法はコンストラクタ渡しとファクトリーメソッドとセッターメソッドだね 0:14:48.140,0:14:50.532 それぞれの例ではPHPUnitのモックを使っているけど質問があれば聞いてください 0:14:50.532,0:15:06.745 コンストラクタ渡しはJavaなんかで古くから使われている依存関係の処理で 0:15:06.745,0:15:12.139 依存するクラスのオブジェクトをコンストラクタで受け取るようにする方法だ 0:15:12.139,0:15:21.091 このCarクラスの場合はエンジンとドライバーのオブジェクトをコンストラクタで受け取っている 0:15:21.091,0:15:28.277 モックを使いたい時はエンジンやドライバーのモックオブジェクトを変わりに渡せばいい 0:15:28.277,0:15:31.941 次はファクトリーメソッド 0:15:31.941,0:15:36.671 ファクトリーメソッドはサブクラスでモックを返すようにオーバーライドすればいい 0:15:36.671,0:15:40.390 このRaceCarクラスはエンジンのオブジェクトをgetEngineメソッドから取得する 0:15:40.390,0:15:51.297 モックを使う場合はgetEngineメソッドを別のオブジェクトを返すようにオーバーライドすればいい 0:15:51.297,0:16:02.238 さらに別の方法がセッターメソッド 0:16:02.238,0:16:09.677 フレームワークやツールでよくあるようにsetやgetでオブジェクトを操作する方法だ 0:16:09.677,0:16:14.857 これなら簡単にオブジェクトを入れ替える事ができる 0:16:14.857,0:16:20.770 GiantEngineを入れ替えたければsetEngineを使える 0:16:20.770,0:16:26.618 モックはテストの目的によっては重要になる 0:16:26.618,0:16:31.252 モックやスタブで危険なオブジェクトやメソッドをテストから除く事ができる 0:16:31.252,0:16:39.811 モックを使ってオブジェクトが他のオブジェクトを正しく扱っているかを確かめられる 0:16:39.811,0:16:45.802 この例ではgetMockメソッドでモックを取得し 0:16:45.802,0:16:50.172 何かしら危険なtypeメソッドをスタブ化している 0:16:50.172,0:17:12.006 最初はjsonのパラメータが渡され 次の例ではxmlのパラメータが渡されている事をチェックしている 0:17:12.006,0:17:31.896 RequestHandlerオブジェクトが正しく動いていればテストはパスするはず 0:17:31.896,0:17:46.246 テストの中でオブジェクトを作る時にモックを作り 期待するパラメータごとの結果をスタブ化する 0:17:46.246,0:18:09.820 これはCake2の実際のテストの例だけど 0:18:09.820,0:18:15.959 危険な処理のスタブ化 0:18:15.959,0:18:19.196 ヘッダーの送信の処理は危険な処理だ 0:18:19.196,0:18:26.652 外部のサービスに通信する処理もそうだし 0:18:26.652,0:18:35.524 呼び出しの度に課金が発生するようなサービスをテストの度に呼び出すのはよくないやりかただ 0:18:35.524,0:18:39.664 そういった場合にスタブを使えばいい 0:18:39.664,0:18:54.364 さっきのやり方と同じでヘッダを送るメソッドをスタブ化している 0:18:54.364,0:19:00.759 statusCodeメソッドが呼び出された場合は301 0:19:00.759,0:19:12.725 headerが呼び出された場合はLocationとURLの2つのパラメーターが渡る事を期待している 0:19:12.725,0:19:32.701 どうしてスタブ化するかというと オブジェクトがheader関数を呼んでしまうからだ 0:19:32.701,0:19:38.323 スタブ化しないで実行してしまうとテストの度にcakephpのサイトを見る事になってしまう 0:19:38.323,0:19:46.901 モックを使ってテスト時に起こる良くない現象を解決している 0:19:46.901,0:19:51.213 コストのかかる処理のスタブ化 0:19:51.213,0:19:56.300 このCampainMontiorは遅いので隠してしまおう 0:19:56.300,0:20:11.120 幾つか連絡先の情報を作っておいてモックを作り 0:20:11.120,0:20:23.133 このメソッドが呼ばれた時はこのデータが返ってくるとみなす 0:20:23.133,0:20:33.615 DependencyInjectionでこのクラス全体を置き換える事もできるけど 0:20:33.615,0:20:43.613 モックを使って自動的にメソッドが呼ばれた時の戻り値を設定してる 0:20:43.613,0:20:48.582 わかるかな? 0:20:48.582,0:21:01.749 この場合だとonceなので2回呼び出された場合はテストが失敗する 0:21:01.749,0:21:14.451 厳密に数値ごとの結果を定義してテストを失敗させることもできる 0:21:14.451,0:21:17.706 このセクションのまとめ 0:21:17.706,0:21:31.802 モックはテストを素早く実行させたり、テストの事前事後の処理を少なくする事ができる 0:21:31.802,0:21:40.986 外部サービスを呼ぶような場合もスタブ化してしまえば 0:21:40.986,0:21:45.060 本当の意味でのユニットテストが実行できる 0:21:45.060,0:21:52.572 重要なところをテストして余分なものを分離する 0:21:52.572,0:22:04.544 以上でモックの話はおわり 0:22:04.544,0:22:09.282 もちろんSimpleTestにもモックオブジェクトはある 0:22:09.282,0:22:14.495 コアクラスのテストケースを見れば大量にモックを使っているのがわかると思う 0:22:14.495,0:22:19.130 自動殺人ロボット 0:22:19.130,0:22:23.500 人体模型でも出来る自動テストだ 0:22:23.500,0:22:38.003 実行されていないテストは消していい 0:22:38.003,0:22:42.758 こういう場合ビルドサーバーを建てよう 0:22:42.758,0:22:47.881 Hudsonはとても使いやすいJava製のビルドサーバーだ 0:22:47.881,0:22:57.432 たくさんのプラグインがあってメールを送ったり、Jabberにメッセージを送ったりできる 0:22:57.432,0:23:03.784 テストがコードをどれだけカバーしているかのカバレッジレポートを出すこともできる 0:23:03.784,0:23:17.529 テストを毎晩とか毎時とか毎日にスケジュールしたり、ポストコミットのフックを設定もできる 0:23:17.529,0:23:21.438 起動したHudsonはコードをチェックアウトして 0:23:21.438,0:23:26.795 さらにスクリプトを実行してテストを行う 0:23:26.795,0:23:30.523 SvnでもGitでも使える 0:23:30.523,0:23:35.424 MercurrealやBazarも大丈夫 使わない理由はないね 0:23:35.424,0:23:43.826 一般的なのはコミットやプッシュの度にテストを実行する 0:23:43.826,0:23:52.688 短い間隔でジョブを待機させてテストする 0:23:52.688,0:24:08.614 開発が進んでない場合も夜間にテストを実行する 0:24:08.614,0:24:19.222 サーバーが空いている時にカバレッジレポートを出力する 0:24:19.222,0:24:24.503 Hudsonのセットアップは今見せようと思ったけどネットワークがおかしいみたいで 0:24:24.503,0:24:28.608 夕べやったやつをお見せします 0:24:28.608,0:24:39.706 wgetでダウンロードしてjavaコマンドで実行する 0:24:39.706,0:24:47.330 ターミナルの大きさお変えて 0:24:47.330,0:24:50.688 Hudsonのディレクトリを開く 0:24:50.688,0:25:08.481 見えるかな? 0:25:08.481,0:25:14.364 Hudsonは他のJavaプログラムと違ってコンテナやTomcat無しで 0:25:14.364,0:25:19.731 5000の依存関係をコンパイルしたりしなくても 0:25:19.731,0:25:24.233 1ファイルをダウンロードして実行できる 0:25:24.233,0:25:28.263 インストールに何時間もかかってTomcatを入れてなんて 0:25:28.263,0:25:38.447 事も前にあったけど 0:25:38.447,0:25:44.257 これでローカルでHudsonが動いている 0:25:44.257,0:25:49.089 localhostの8080にアクセスして 0:25:49.089,0:26:01.992 おっと 0:26:01.992,0:26:09.539 (.comを指摘されて)みなさんのほうが賢いみたいだ 0:26:09.539,0:26:14.835 これが僕のマシンの上のHudson 0:26:14.835,0:26:28.648 この画面でHudsonの管理ができる 0:26:28.648,0:26:33.549 ビルドの履歴をプロジェクトリストから見たり 0:26:33.549,0:26:43.839 最後にテストが失敗したか成功したかが見れる 0:26:43.839,0:26:53.145 これはプロジェクトの例 0:26:53.145,0:27:03.555 テストのプロジェクトを作ってみよう 0:27:03.555,0:27:16.255 フリースタイルプロジェクトを選んで 0:27:16.255,0:27:34.451 gitリポジトリを使う 0:27:34.451,0:27:48.588 このブランチを使って 0:27:48.588,0:27:53.887 手動でビルドしたり定期的にビルドしたり SCMから呼ばれたりもできる 0:27:53.887,0:27:57.054 実行するシェルの設定 0:27:57.054,0:28:05.300 cakeのコンソールを使ってテストを実行 0:28:05.300,0:28:18.304 コアのヘルパーのテストを実行するようにする 0:28:18.304,0:28:25.777 メールの送信を設定 0:28:25.777,0:28:29.968 誰かメールを受け取りたいかい? 0:28:29.968,0:28:53.110 誰もいない? じゃあグラハムだ 0:28:53.110,0:29:01.966 ビルドが失敗する度に君にメールを送る 0:29:01.966,0:29:05.553 ビルドを壊した人にメールを送るなんてのもあるね 0:29:05.553,0:29:14.095 これでプロジェクトは設定できた 0:29:14.095,0:29:19.126 これでビルドが失敗するとすぐに「マークがビルドを失敗させた」と周知する事ができる 0:29:19.126,0:29:32.172 これで壊した人が責任をもって直すようになるね 0:29:32.172,0:29:44.449 実にすばらしい 0:29:44.449,0:29:47.287 ビルド中だね 0:29:47.287,0:29:49.971 ♪ 0:29:49.971,0:29:53.280 Hudsonには複数のプロジェクトを作成できる 0:29:53.280,0:30:00.070 Hudsonはリポジトリからローカルにコードを持ってきて 0:30:00.070,0:30:04.306 指定されたコマンドを実行する 0:30:04.306,0:30:09.810 cakeコマンドとか必要なら他のコマンドも先に実行できる 0:30:09.810,0:30:18.251 そして最後のコマンドのexitステータスが失敗ならビルドは失敗した事になる 0:30:18.251,0:30:23.684 exitステータスが成功ならビルドも成功 0:30:23.684,0:30:30.462 コンソールのアウトプットを見てみよう 0:30:30.462,0:30:34.543 githubからクローン中だね 0:30:34.543,0:30:38.473 時間がかかりそうだ 0:30:38.473,0:30:54.266 (ネットワークが不調)失敗しそうだ 0:30:54.266,0:30:58.248 ビルド失敗だね 0:30:58.248,0:31:04.622 1分前に失敗 グラハムにはメールが届くはずだ 0:31:04.622,0:31:12.032 設定を変更 0:31:12.032,0:31:20.011 (ローカルのリポジトリに変更) 0:31:20.011,0:31:32.683 これで動くかな 0:31:32.683,0:31:42.132 ディレクトリ名で動くらしい グラハムによると 0:31:42.132,0:31:51.754 実行中だ 0:31:51.754,0:32:04.231 ネット接続が面白い事になってるね 0:32:04.231,0:32:15.614 失敗だ 0:32:15.614,0:32:26.124 ネットワーク接続があればなー 0:32:26.124,0:32:34.568 遅いな 0:32:34.568,0:32:47.223 やっぱり繋がってないな 0:32:47.223,0:32:53.413 本来ならここにビルド成功を示す青いラインがでる 0:32:53.413,0:33:00.604 ちゃんと動いていればね 0:33:00.604,0:33:25.191 コンソールにテストの内容と結果が表示される 0:33:25.191,0:33:31.027 グラハム メールは来た? 0:33:31.027,0:33:40.241 これで発表は終わりです 0:33:40.241,0:33:50.208 質問があればどうぞ 時間は大丈夫? 0:33:50.208,0:34:01.778 HudsonでSereniumは使えるか? 使えるよ 0:34:01.778,0:34:11.606 PHPUnitからSereniumを実行しているかSereniumRCを使ってブラウザを動かしていれば 0:34:11.606,0:34:15.919 ちょっと設定は面倒だけど 0:34:15.919,0:34:24.996 PHPUnitからSereniumを実行して結果をチェックする 0:34:24.996,0:34:31.380 HudsonがPHPUnitを実行してPHPUnitがSereniumを実行して Sereniumがブラウザを実行し 0:34:31.380,0:34:35.996 PHPUnitがテストが失敗したかどうかを伝える 0:34:35.996,0:34:40.197 これで回答になったかな? OK 0:34:40.197,0:34:48.514 何が動かないか? 設定が面倒だけど 0:34:48.514,0:34:58.546 依存関係も多くないし 0:34:58.546,0:35:22.092 Hudsonはユニットテストフレームワークには関与しない 0:35:22.092,0:35:30.416 単にコンソールを見るのでSimpleTestでも問題ない 0:35:30.416,0:35:34.339 Hudsonのコンソールを見ればわかるけど 0:35:34.339,0:35:42.063 何が実行されてどうして失敗したのか 0:35:42.063,0:35:44.676 OK 0:35:44.676,0:35:49.523 後ろの人 0:35:49.523,0:36:13.812 まだ無理だね 0:36:13.812,0:36:18.625 じゃあありがとうございました