PHPUnit で
テスト駆動開発を
  始めよう
   @yuya_takeyama
このスライドは
以前の発表を抜粋・再編集・加筆してお送りします




    http://blog.yuyat.jp/archives/1386
アジェンダ
•PHPUnit とは何か

•何故ユニットテストを書くか

•免責事項 (PHPUnit 的な意味で)

•蛇足 : オレはこう思う
What’s
PHPUnit?
PHPUnit とは
•テスティングフレームワーク

•ユニットテストを書く

•比較的簡単に書ける

•多機能
何故 PHPUnit か

•豊富なドキュメント

•日本語訳も充実
(PHP マニュアルでもおなじみ高木正弘さん)


•豊富な利用実績       (ZF, Symfony2, etc)
http://www.phpunit.de/manual/current/ja/
これ読むだけでも
かなり勉強になるの
  でオススメです
http://www.phpunit.de/manual/current/ja/
class CalculatorTest
  extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
        $this->calc = new Calculator;
    }

    public function test_add_引数の和を返す()
    {
        $result = $this->calc->add(1, 2);
        $this->assertSame(3, $result);
    }
}
class CalculatorTest
  extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {                                       1
        $this->calc = new Calculator;
    }

    public function test_add_引数の和を返す()
    {
        $result = $this->calc->add(1, 2);
        $this->assertSame(3, $result);
    }
}

      テストに必要な物の用意
class CalculatorTest
  extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
        $this->calc = new Calculator;
    }

    public function test_add_引数の和を返す()
    {
                                            2
        $result = $this->calc->add(1, 2);
        $this->assertSame(3, $result);
    }
}

          テスト対象の実行
class CalculatorTest
  extends PHPUnit_Framework_TestCase
{
    public function setUp()
    {
        $this->calc = new Calculator;
    }

    public function test_add_引数の和を返す()
    {
                                        3
        $result = $this->calc->add(1, 2);
        $this->assertSame(3, $result);
    }
}

 実行結果の検証 (アサーション)
Why
Unit-test?
ドキュメントとして

•Tests as Documentation

• API の一覧

• 動作するサンプルコード
回帰テストとして

•リグレッションテストともいう

•ある修正が新たなバグを
生んでいないか

•同じ過ちを繰り返さないため
リファクタリングとは
•振る舞いを帰ること無く

• ソースコードの内部構造を

• 変更すること

• ソースコードの体質改善
設計のためのテスト
•Test Driven Design

• ライブラリは API が 9 割

• API のユーザビリティテスト

• リファクタリングで継続的改
テストは
質のためならず
設計のためのテスト
•オブジェクト指向の原則や

•デザインパターンを武器に

•テスタビリティの高いコードを
書き

•リファクタリングで継続的改
テストを中心に据え
ることで機能・設計
を継続的に改善する
ことができる
何故テストを書くか
•ドキュメントとして

• 回帰テストとして

• 設計のため

• リファクタリングのため

• 継続的改善のため
免責
事項
(PHPUnit 的な意味で)
テストを書けば全て
が解決するわけでは
なく, テストを書くこ
とで新たに起こる問
題もある
それらの問題を何でも
PHPUnit や TDD の
せいにするのではなく,
妥協点を見つける必要
がある
という話をします
Q. テストを書い
ていたら
開発工数が増え
るんだが!!!
A. 冗長化して
書いているの
で当然です
http://d.hatena.ne.jp/nowokay/20120222
テストを書くポイントを選ぶ
•やみくもに書けばいいというものではない
•品質が求められる部分
•頻繁に変更が起こり壊れやすい部分
•不安を感じる部分
•初期コストをかけることで, あとで回収で
 きるかどうか
テストもリスク/コスト

•テストを書く時間
•テストをメンテする時間
•コストに見合った対価が得られるか
•カバレッジが同じならテストは少ない方が良い
•可読性重要
Q. テストを書いて
も開発が
駆動 (Drive) され
ないのだが!!!
A. 今作っている
ものに TDD が
フィットしてない
のでは?
TDD が向かないもの

•自分が作ろうとしているものが全くイメージで
 きない場合

•開発の初期段階で, 作ろうとしているもの自体
 がコロコロ変わる場合

•テストを書こうとすることで, これらの問題に
 早期に気づくことができる (という話もある)
とりあえず動くものを
 作ることが大事
http://d.hatena.ne.jp/sotarok/20120105/1325698126
テストファースト
が絶対ではない
 (と, 個人的には思ってます)
http://www.slideshare.net/t_wada/javaja-tdd-2nd
テストは後からでも
書けるし
後からでも
書くべき
※やみくもにテストを書いて痛い目を見ることで得ら
   れるものがあることも付記しておきます
蛇足 : オレはこう思う
プログラマの
「オレが全部書き
直してやんよ!」病
  について
オレが全部(ry
•酷いレガシーコードの塊

•こんなの読んでられない!!

•全部書き直した方が早いので
は???
オレが全部(ry
      本当に
•酷いレガシーコードの塊

•     それで
 こんなの読んでられない!!

•全部書き直した方が早いので
   いいのか?
 は???
解決したい問題は何か
レガシーコードが抱える問題


•理解するのに時間がかかる

•ちょっと改修するとすぐ壊れる

•拡張が著しく困難
要約すると
レガシーコードが抱える問題



•「オレ」が気に
入らない
解決したい問題は何か
全部書き換えればレガシーコードは無くなるのか
短期的には Yes であることもある
長期的には大体 No
コードは
腐る
全部書き換える前
にコードを腐らせ
ない技術を身につ
ける必要がある
レガシーコード
   と
立ち向かう勇気
...を, 身につけるために
これの読書会とかしたいですね
ご清聴
 ありがとう
ございました

PHPUnit でテスト駆動開発を始めよう