Agileな
Agile
開発現場での
                                           2008
                                          10/25



実践例...
• 岸田 健一郎
 Ken-ichirou Kishida

• 永和システムマネジメント所属、
 Eiwa System Management, Inc. => www.esm.co.jp
 オブジェクト倶楽部
 ObjectClub => ...
CakePHP Conference Tokyo
実践例とするプロジェクト
• 中小企業向け業務パッケージ

• 2008年5月ぐらいから10月末まで2名で、
  およそ12人月ぐらい

• CakePHP1.2採用の理由は多言語(国際
  化)対応が必要だったため

• Cake内部に手を加...
今日はAgileについて
語る訳ではありません

Today does not necessarily talk detail about Agile.




                               CakePHP Co...
代表的な手法である
  EXxtreme Programming

開発プラクティスを
どうやって適用したか
   紹介します
  Today’s Contents “How to apply XP”
                     ...
•テスト駆動
•リファクタリング
•ペアプロ
•朝会、ふりかえり
•Etc …
        CakePHP Conference Tokyo
•テスト駆動 => Test Driven Development
•リファクタリング
•ペアプロ
•朝会、ふりかえり
•Etc …
                    CakePHP Conference Tokyo
テスト駆動開発 :
1.   クラスのスケルトンを作成する
2.   テストコードを書く
3.   テストを実行する => もちろん失敗
4.   テストにパスする簡単な実装をする
5.   テストを実行する => 成功するまで
6.   リフ...
テスト駆動開発について
詳しく知りたい方は・・


和田卓人のテスト駆動開発講座


         CakePHP Conference Tokyo
今日のポイント ~Today’s highlight
• テスト書くのなんて面倒だなぁ
  => と思っているアナタ

• テスト書いてみたけど動かなかった
  => そんなアナタ

• テストコードのサンプルってないの?
  => とお困りの...
CakePHPは
テスト駆動開発向きか?

Is CakePHP for test drive development?




                       CakePHP Conference Tokyo
基本的に戻り値が連想配列なんで、空の実
装に対して先にアサーションすると、
FAILEDだけでなくERROR
(undefined index) だらけになる

→テストコードが正しいのか判断できない
              CakePHP...
そのために
メンバ変数定義して
Set::map()使うの?

        CakePHP Conference Tokyo
なので、ある程度実装し
てからテストを書くと吉

  After writing simple programming,
  it is good to write a test !!




                        C...
適用プロジェクトの規模
分類           ファイル数         TestCase 評価数
Model        22(43Table)        14       989
Controller          23   ...
Keep :
• Cakeがβ→RC1→RC2→RC3と変化し
  ても影響度がすぐわかった

• デグレはほとんどない

• 他のメンバーが書いたコードの意味を把
  握しやすい


               CakePHP Confer...
Problem :
• テストケース考慮モレにバグが潜んでい
  た

• Controllerのテストは書きにくいのであ
  まり書いていない

• テストコードが長すぎて失敗ケースだけ
  やり直したいのに時間がかかり過ぎ

       ...
Try :
• テストコードを分割しよう

• Controller,Comonent,Model それぞ
  れどこに何を書くかパターン化してテス
  ト漏れを防ぎたい

• テストメソッド単位で実行できるように
  test.phpやTes...
Test 書いてますか?

  書いている人は挙手にご協力ください



Please raise your hand if you write code of test !



                              C...
そこで Test を書くのに
 役立つ「虎の巻」を
   紹介します

 Some hints of how to write code of Test



                          CakePHP Conferen...
つまりTestCaseの
文法を解説する訳では
   ありません

  Today does not necessarily
  talk to syntax of TestCase.
                    CakePHP C...
TestCaseの記法



  詳しくはコチラで見てください・・・




http://book.cakephp.org/ja/view/160/テスト-Testing
                            CakePHP...
Level:0 DBは$testで設定する
class DATABASE_CONFIG {
        var $default = array(
        );
        var $test = array(
        ...
Level:1 関連は自分でセットする
class PostTest extends Post {
   var $useDbConfig = 'test_suite';
}
class CategoryTest extends Categor...
Level:2 名前付け重要
post.test.php :                     同じ名前があると
class PostTest extends Post {
   var $useDbConfig = 'test_suit...
Level:3 fixtureに注意
class PostFixture extends CakeTestFixture {
       var $name = ‘Post';
      var $import = array('model...
Level:4 コンポーネントは自分でセット
class LoginComponent extends Object {
  var $components = array('Session');


         コンポーネントのテストで...
Level:5 独自FormHelperは初期化が複雑

class AppFormHelper extends FormHelper {
}

class AppFormTest extends CakeTestCase {
   funct...
Level:6 計算結果はassertIdentical

function test01.12300は前後の0が省略フォーマットされる() {
    $this->assertIdentical('1.123',
     $this->N...
Level:7 Shellテストの決まり
if(!class_exists('Shell')){
    class Shell extends Object {}
}                      クラスがない場合がある
    ...
Level:8 Controllerにロジックを書かない

• aclとかAuthとかセッションとか依存
  関係が多すぎて大変

• なるべくComponentを使おう

• でもWebAPIとかAjaxとか、結果を評
  価したい場合もある...
コントローラでテストしたもの
• WebAPI (REST Interface)
  testAction, result=>render でチェック

• エラーページへリダイレクトされる
  かWebTestCaseでチェック
  ※ただし...
WebAPIのチェック
$data = array(‘Post' => array(
     'id from' => 16, // ここから
     'id to' => 27, // ここまで
));
$result = $this->...
WebTestCaseでのチェック
function testセッションエラーの場合エラー700が戻る() {
   // ログインしておく
   $this->addHeader('Accept-Language:ja');
    $thi...
Level:9 Mockは積極的に使おう

• テストごとに前工程をダラダラ書く
  のはムダ

• テストコードがすっきりして本来テ
  ストしたい目的がわかりやすい

• ただし、RC3でコントローラテスト
  する場合は使用方法に注意・・...
MockObjectの使い方

class UsersControllerTestCase extends CakeTestCase {
   function setUp() {
      Mock::generate('LoginComp...
MockObjectの使い方
class UsersControllerTestCase
                     extends CakeTestCase {
  function testログインしているユーザ名を取得() ...
1.2 RC3 では・・・
class UsersControllerTest extends CakeTestCase {
function startController(&$controller, $params) {
      $co...
内部変数に直接はアレなので
App::import('Controller', ‘Users');

class UsersControllerTestController
extends UsersController {
   var $L...
startControllerを変更
class UsersControllerTest extends CakeTestCase
{
  function startController(&$controller, $params)
  {
...
実はパラメータで変えられます
class UsersControllerTestCase
                     extends CakeTestCase {
  function testログインしているユーザ名を取得() ...
困ったら
• Booksを見よう
  翻訳された皆様に感謝!!
   でも書いてないこともタマにある
   => 今日のスライドが参考になれば・・

• Cake本体のテストコード見る
  Cake自体の理解度も向上する


         ...
まとめ
• 面倒がらずに一度書けば、何度でも役に
  立つのがテストコード

• 初期化に罠が多いので、注意しよう。逆
  にテストケース自体は普通の書き方。

• Cake本体のテストコードがお手本


             CakePH...
これで明日から
  日曜日ですが・・・




         CakePHP Conference Tokyo
Testで
みんなHappyに

     CakePHP Conference Tokyo
ご清聴ありがとう
 ございました

    CakePHP Conference Tokyo
Upcoming SlideShare
Loading in …5
×

Agileな開発現場での実践例

3,793 views

Published on

CakePHPカンファレンス東京2008で講演してきました。

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,793
On SlideShare
0
From Embeds
0
Number of Embeds
11
Actions
Shares
0
Downloads
34
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Agileな開発現場での実践例

  1. 1. Agileな Agile 開発現場での 2008 10/25 実践例 A practice in the Agile development team 岸田 健一郎 Ken-ichirou Kishida CakePHP Conference Tokyo
  2. 2. • 岸田 健一郎 Ken-ichirou Kishida • 永和システムマネジメント所属、 Eiwa System Management, Inc. => www.esm.co.jp オブジェクト倶楽部 ObjectClub => http://ObjectClub.jp • CakePHP暦 => 2年半ぐらい • PHP/JavaScript/ActionScript/HTML /CSS etc….. [Technote] http://my.opera.com/sizuhiko/blog/ CakePHP Conference Tokyo
  3. 3. CakePHP Conference Tokyo
  4. 4. 実践例とするプロジェクト • 中小企業向け業務パッケージ • 2008年5月ぐらいから10月末まで2名で、 およそ12人月ぐらい • CakePHP1.2採用の理由は多言語(国際 化)対応が必要だったため • Cake内部に手を加えたのはScaffold出力 メッセージの日本語化だけ CakePHP Conference Tokyo
  5. 5. 今日はAgileについて 語る訳ではありません Today does not necessarily talk detail about Agile. CakePHP Conference Tokyo
  6. 6. 代表的な手法である EXxtreme Programming 開発プラクティスを どうやって適用したか 紹介します Today’s Contents “How to apply XP” CakePHP Conference Tokyo
  7. 7. •テスト駆動 •リファクタリング •ペアプロ •朝会、ふりかえり •Etc … CakePHP Conference Tokyo
  8. 8. •テスト駆動 => Test Driven Development •リファクタリング •ペアプロ •朝会、ふりかえり •Etc … CakePHP Conference Tokyo
  9. 9. テスト駆動開発 : 1. クラスのスケルトンを作成する 2. テストコードを書く 3. テストを実行する => もちろん失敗 4. テストにパスする簡単な実装をする 5. テストを実行する => 成功するまで 6. リファクタリング・・・ CakePHP Conference Tokyo
  10. 10. テスト駆動開発について 詳しく知りたい方は・・ 和田卓人のテスト駆動開発講座 CakePHP Conference Tokyo
  11. 11. 今日のポイント ~Today’s highlight • テスト書くのなんて面倒だなぁ => と思っているアナタ • テスト書いてみたけど動かなかった => そんなアナタ • テストコードのサンプルってないの? => とお困りのアナタ CakePHP Conference Tokyo
  12. 12. CakePHPは テスト駆動開発向きか? Is CakePHP for test drive development? CakePHP Conference Tokyo
  13. 13. 基本的に戻り値が連想配列なんで、空の実 装に対して先にアサーションすると、 FAILEDだけでなくERROR (undefined index) だらけになる →テストコードが正しいのか判断できない CakePHP Conference Tokyo
  14. 14. そのために メンバ変数定義して Set::map()使うの? CakePHP Conference Tokyo
  15. 15. なので、ある程度実装し てからテストを書くと吉 After writing simple programming, it is good to write a test !! CakePHP Conference Tokyo
  16. 16. 適用プロジェクトの規模 分類 ファイル数 TestCase 評価数 Model 22(43Table) 14 989 Controller 23 12 878 Component 8 9 423 View 159 ----- ----- Helper 15 5 26 Shell 3 3 113 CakePHP Conference Tokyo
  17. 17. Keep : • Cakeがβ→RC1→RC2→RC3と変化し ても影響度がすぐわかった • デグレはほとんどない • 他のメンバーが書いたコードの意味を把 握しやすい CakePHP Conference Tokyo
  18. 18. Problem : • テストケース考慮モレにバグが潜んでい た • Controllerのテストは書きにくいのであ まり書いていない • テストコードが長すぎて失敗ケースだけ やり直したいのに時間がかかり過ぎ CakePHP Conference Tokyo
  19. 19. Try : • テストコードを分割しよう • Controller,Comonent,Model それぞ れどこに何を書くかパターン化してテス ト漏れを防ぎたい • テストメソッド単位で実行できるように test.phpやTestCaseを書き換えたい CakePHP Conference Tokyo
  20. 20. Test 書いてますか? 書いている人は挙手にご協力ください Please raise your hand if you write code of test ! CakePHP Conference Tokyo
  21. 21. そこで Test を書くのに 役立つ「虎の巻」を 紹介します Some hints of how to write code of Test CakePHP Conference Tokyo
  22. 22. つまりTestCaseの 文法を解説する訳では ありません Today does not necessarily talk to syntax of TestCase. CakePHP Conference Tokyo
  23. 23. TestCaseの記法 詳しくはコチラで見てください・・・ http://book.cakephp.org/ja/view/160/テスト-Testing CakePHP Conference Tokyo
  24. 24. Level:0 DBは$testで設定する class DATABASE_CONFIG { var $default = array( ); var $test = array( 'driver' => 'mysql', 'persistent' => false, 'host' => 'localhost', 'port' => '', 'login' => 'root', 'password' => 'root', 'database' => ‘post', 'schema' => '', 'prefix' => 'test_suite_', 'encoding' => 'utf8' ); } CakePHP Conference Tokyo
  25. 25. Level:1 関連は自分でセットする class PostTest extends Post { var $useDbConfig = 'test_suite'; } class CategoryTest extends Category { var $useDbConfig = 'test_suite'; } しなくても動くけど、 JOINされません class PostTestCase extends CakeTestCase { function setUp() { $this->Model = new PostTest(); $this->Model->Category = new CategoryTest(); CakePHP Conference Tokyo
  26. 26. Level:2 名前付け重要 post.test.php : 同じ名前があると class PostTest extends Post { var $useDbConfig = 'test_suite'; GroupTestで「既に存在 } するクラス」になり、失 敗する。 class CategoryTest extends Category { なので、上の方はテスト var $useDbConfig = 'test_suite'; } ケース名+モデル名とい う規則で、 category.test.php : PostTestCategory classCategoryTest とすると良い。 extends Category { var $useDbConfig = 'test_suite'; } CakePHP Conference Tokyo
  27. 27. Level:3 fixtureに注意 class PostFixture extends CakeTestFixture { var $name = ‘Post'; var $import = array('model'=>‘Post'); function create() { return false; スキーマ情報をイン } ポートすると、テーブ ルが自動生成されない function drop() { return false; } } CakePHP Conference Tokyo
  28. 28. Level:4 コンポーネントは自分でセット class LoginComponent extends Object { var $components = array('Session'); コンポーネントのテストで、そのコンポー ネントが別のコンポーネントを使っている 場合、初期化されないので注意 class LoginComponentTest extends CakeTestCase { function setUp() { $this->Controller = &new LoginTestController(); $this->Login = &new LoginComponent(); $this->Login->Session = &new SessionComponent(); CakePHP Conference Tokyo
  29. 29. Level:5 独自FormHelperは初期化が複雑 class AppFormHelper extends FormHelper { } class AppFormTest extends CakeTestCase { function setUp() { parent::setUp(); Router::reload(); $this->AppForm = new AppFormHelper(); $this->AppForm->Html =& new HtmlHelper(); $this->Controller =& new AppFormTestController(); $this->View =& new View($this->Controller); } CakeのFormHelperテストの初期化を拝 借しましょう。 CakePHP Conference Tokyo
  30. 30. Level:6 計算結果はassertIdentical function test01.12300は前後の0が省略フォーマットされる() { $this->assertIdentical('1.123', $this->NumberUtil->formatFloat(quot;01.12300quot;)); } function test01.12300は前後の0が省略フォーマットされる() { $this->assertEqual('1.123', もし結果が“1.12300”と帰ってきても、 $this->NumberUtil->formatFloat(quot;01.12300quot;)); 成功してしまいます。 } CakePHP Conference Tokyo
  31. 31. Level:7 Shellテストの決まり if(!class_exists('Shell')){ class Shell extends Object {} } クラスがない場合がある ので先頭でチェック App::import( 'Vendor', 'MonthlyUpdateShell', array( 'file' => 'Shells'.DS.'monthly_update.php‘ )); fileを指定してimportしよう CakePHP Conference Tokyo
  32. 32. Level:8 Controllerにロジックを書かない • aclとかAuthとかセッションとか依存 関係が多すぎて大変 • なるべくComponentを使おう • でもWebAPIとかAjaxとか、結果を評 価したい場合もある CakePHP Conference Tokyo
  33. 33. コントローラでテストしたもの • WebAPI (REST Interface) testAction, result=>render でチェック • エラーページへリダイレクトされる かWebTestCaseでチェック ※ただしfixtureもMockも使えません CakePHP Conference Tokyo
  34. 34. WebAPIのチェック $data = array(‘Post' => array( 'id from' => 16, // ここから 'id to' => 27, // ここまで )); $result = $this->testAction( ‘/api/posts/index', array('return'=>'render', 'data' => $data)); $xml = Set::reverse(new Xml($result)); $this->assertEqual(11, count($xml[‘Posts.index'][‘Posts'][‘Post'])); CakePHP Conference Tokyo
  35. 35. WebTestCaseでのチェック function testセッションエラーの場合エラー700が戻る() { // ログインしておく $this->addHeader('Accept-Language:ja'); $this->assertTrue($this->get('/users/login')); $this->assertTitle('ログイン'); $this->setFieldByName('data[User][account]', 'admin'); $this->setFieldByName('data[User][password]','password'); $this->assertTrue($this->clickSubmit('Login')); $this->assertTitle(‘ホーム'); $this->addHeader('User-Agent: Session Error); // どこかのページへ遷移 $this->assertTrue($this->get('/users/index')); // HTTPレスポンスの評価 $this->assertResponse('700'); $this->assertTitle(‘セッションエラー'); } CakePHP Conference Tokyo
  36. 36. Level:9 Mockは積極的に使おう • テストごとに前工程をダラダラ書く のはムダ • テストコードがすっきりして本来テ ストしたい目的がわかりやすい • ただし、RC3でコントローラテスト する場合は使用方法に注意・・・ CakePHP Conference Tokyo
  37. 37. MockObjectの使い方 class UsersControllerTestCase extends CakeTestCase { function setUp() { Mock::generate('LoginComponent'); $this->Login = &new MockLoginComponent(); } function startController(&$controller, $params) { $controller->Login = $this->Login; } CakePHP Conference Tokyo
  38. 38. MockObjectの使い方 class UsersControllerTestCase extends CakeTestCase { function testログインしているユーザ名を取得() { $this->Login->setReturnValue( ‘getLoginName', ‘岸田健一郎’); $result = $this->testAction( '/api/users/1/name', array('return'=>'render')); $this->assertEqual( ‘岸田健一郎’, $result); CakePHP Conference Tokyo
  39. 39. 1.2 RC3 では・・・ class UsersControllerTest extends CakeTestCase { function startController(&$controller, $params) { $controller->Login = $this->Login; $controller->Component-> __loaded['Login'] = $this->Login; } コントローラ内でのコンポーネント初期化タイミ ングがstartControllerより後になったので __loaded でブロックしないとMockが使えないが・・・ CakePHP Conference Tokyo
  40. 40. 内部変数に直接はアレなので App::import('Controller', ‘Users'); class UsersControllerTestController extends UsersController { var $LoginMock; function beforeFilter(){ $this->Login = $this->LoginMock; return parent::beforeFilter(); } テスト用のコントローラーを作って、 } beforeFilterでモックと置き換えましょう CakePHP Conference Tokyo
  41. 41. startControllerを変更 class UsersControllerTest extends CakeTestCase { function startController(&$controller, $params) { $controller->LoginMock = $this->Login; } でもtestActionってURLからコントローラを生成 するから独自コントローラ使えなくネ?? CakePHP Conference Tokyo
  42. 42. 実はパラメータで変えられます class UsersControllerTestCase extends CakeTestCase { function testログインしているユーザ名を取得() { $result = $this->testAction( '/api/users/1/name', array( 'return'=>'render', 'controller'=>'UsersControllerTest', )); CakePHP Conference Tokyo
  43. 43. 困ったら • Booksを見よう 翻訳された皆様に感謝!! でも書いてないこともタマにある => 今日のスライドが参考になれば・・ • Cake本体のテストコード見る Cake自体の理解度も向上する CakePHP Conference Tokyo
  44. 44. まとめ • 面倒がらずに一度書けば、何度でも役に 立つのがテストコード • 初期化に罠が多いので、注意しよう。逆 にテストケース自体は普通の書き方。 • Cake本体のテストコードがお手本 CakePHP Conference Tokyo
  45. 45. これで明日から 日曜日ですが・・・ CakePHP Conference Tokyo
  46. 46. Testで みんなHappyに CakePHP Conference Tokyo
  47. 47. ご清聴ありがとう ございました CakePHP Conference Tokyo

×