Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
UnitTestのための
  クラス設計
    t_ishida
自己紹介


名前:石田 武士(@t_ishida)

所属:アライドアーキテクツ システム部
注意
日頃UnitTestしている人には当たり前の話しか
しません

PHPUnitそのもの使い方は説明しません

このセッションは過去UnitTestにトライしてよ
く分からなかった、もしくは挫折した人に最
適化されています
では、早速
テストしてますか?
テストしてますよ
何度もブラウザから叩いて、こっちの分岐
入った「っぽい」し

何度もブラウザから叩いて、期待通りの回数
ループしてる「っぽい」し

何度もブラウザから叩いて、期待通りのメ
ソッド呼び出した「っぽい」し
テストしてますよ
何度もブラウザから叩いて、こっちの分岐
入った「っぽい」し
    死亡フラグ
何度もブラウザから叩いて、期待通りの回数
ループしてる「っぽい」し

何度もブラウザから叩いて、期待通りのメ
ソッド呼び出した「っぽい」し
本当にテストしてますか?
リロードデバッグですか?

実行タイミングが同じだというだけで、関連の
無いコードを同じ場所に追記しまくってません
か?

それをリロードでデバッグして「テストをしな
いで」リリースしていませんか?
本当にテストしてますか?

リロードデバッグですか?

実行タイミングが同じだというだけで、関連の無い
      死亡フラグ
コードを同じ場所に追記しまくってませんか?

それをリロードでデバッグして「テストをしないで」
リリースしていません...
にんげんさんてすとしないです?
だって・・・


DBが絡むから値固定できないし

ファイルに吐きだすから値検証できないし

ブラウザから入力しないとダメだし
だって・・・


DBが絡むから値固定できないし
   死亡フラグ
ファイルに吐きだすから値検証できないし

ブラウザから入力しないとダメだし
結合テストをして意味があるの
は単体テストをやり尽くしたあ
    とからです
UnitTestってなに?

身も蓋もない言い方をすれば単体テスト

ただし、本セッションで言う単体テストは
xUnit系テスト、主にPHPUnitのテスト

メソッドに色んなパターンの引数を渡して戻
り値が合ってるか比べるだけです
つまり、こんなコードを
こうテスト
UnitTestの考え方

“単体”での確認が出来れば良い

故に呼んでるメソッドの先の正しさは気にし
なくて良い(その先の正しさは、それ単体で確
認するから)

メソッド単体での正しさを徹底的に確認する
UnitTestのメリット

環境から切り離してロジック単体をテストで
きる

プログラムとして保存するから何度でも実行
出来る。そして速い。(回帰テスト自動化)

電算機のテストは正確 ("hoge" != 'hoge ')
UnitTestのデメリット

テストを作るのは時間がかかる

場合によってはテストのためにクラス設計を
歪める必要がある

必ずしも、それで全てのバグを検出すること
が出来ないので過信は禁物
だからと言って、単体
テストしない理由には
  なりません
ここから本題
UnitTestのためのクラス設計


 UnitTestを意識してクラス設計する必要がある

 故に既存のコードをテストに入れるのは大変

 どれだけ大変かはレガシーコード改善ガイド
 を読むと良いです
UnitTestのための
  クラス設計の指針

強い“依存”を徹底的に排除する

 クラス間の依存

 外部システムへの依存

複雑度を下げる
モック


そのクラスのように振る舞うダミーのこと

ダミーで入力を検証する

ダミーで出力を固定する
こういうこと
モック


モックを使うということはオブジェクトを差し替える
ということ
モックを使うための注意


  つまり・・・
モックを使うための注意

メソッド内で new してたら差し替えられない

staticメソッド呼び出しは差し替えられない

組み込み関数は差し替えられない

final な クラスも差し替えられない(モックは
継承して作る)
依存の排除(クラス間の依存)


 コンストラクタやメソッドの引数でオブジェ
 クトを渡す(ファクトリを渡すのも可)

 セッタで上書き可能なメンバ変数にする
オブジェクト渡し
オブジェクト渡し
セッタで上書き
セッタで上書き
おまけ(依存なし)
依存の排除(外部システム)


 プロキシパターン
プロキシパターン




DBなんか文字列(SQL文)渡したら配列を返すク
         ラスです
プロキシパターン




ファイルの読み込みなんか文字列(path)を渡し
  たら文字列を返すただのメソッドです
複雑度を下げる

同じタイミングで実行されるからと言って関
連の無いコードを同じ場所に書かない

ifの入れ子になったらメソッドを分割する

ループの中は別メソッドにする(走査と操作は
分ける)
ざっくばらんなまとめ

そのクラスに関連するオブジェクトはメンバ
変数にする

メンバ変数はセッターで上書き可能にする

メソッドは小まめに分ける

外部システムとの絡みはラッパーを作る
テストしない理由?

テスト書いている時間がないから

上司がテストに対する理解がなくて時間とら
せてくれないから

あとで書くから

複雑過ぎてテストが書けないから
テストしない理由?

テスト書いている時間がないから


   死亡フラグ
上司がテストに対する理解がなくて時間とら
せてくれないから

あとで書くから

複雑過ぎてテストが書けないから
時間無くてテスト書けない


それは手動でテストしている時間も無いはずな
のでリリースしてはならないコードです
上司の理解を得られない

理解を得る必要はありません

勝手に書いてください

自分の時間と健康と心の平穏を守るためにや
るのです
複雑過ぎてテスト書けない



それは、そもそも手動でもテストできません

メソッドを分割して複雑度を下げてください
あとで書く


絶対にあとで書きません
書いておけば妖精さんがテ
  ストしてくれます
ご清聴ありがとうございました
    http://tech.aainc.co.jp
You’ve finished this document.
Download and read it offline.
Upcoming SlideShare
2013 02 09_osc2013_hamamatsu_osm
Next
Upcoming SlideShare
2013 02 09_osc2013_hamamatsu_osm
Next
Download to read offline and view in fullscreen.

Share

UnitTestのためのクラス設計

Download to read offline

UnitTestのためのクラス設計

  1. 1. UnitTestのための クラス設計 t_ishida
  2. 2. 自己紹介 名前:石田 武士(@t_ishida) 所属:アライドアーキテクツ システム部
  3. 3. 注意 日頃UnitTestしている人には当たり前の話しか しません PHPUnitそのもの使い方は説明しません このセッションは過去UnitTestにトライしてよ く分からなかった、もしくは挫折した人に最 適化されています
  4. 4. では、早速
  5. 5. テストしてますか?
  6. 6. テストしてますよ 何度もブラウザから叩いて、こっちの分岐 入った「っぽい」し 何度もブラウザから叩いて、期待通りの回数 ループしてる「っぽい」し 何度もブラウザから叩いて、期待通りのメ ソッド呼び出した「っぽい」し
  7. 7. テストしてますよ 何度もブラウザから叩いて、こっちの分岐 入った「っぽい」し 死亡フラグ 何度もブラウザから叩いて、期待通りの回数 ループしてる「っぽい」し 何度もブラウザから叩いて、期待通りのメ ソッド呼び出した「っぽい」し
  8. 8. 本当にテストしてますか? リロードデバッグですか? 実行タイミングが同じだというだけで、関連の 無いコードを同じ場所に追記しまくってません か? それをリロードでデバッグして「テストをしな いで」リリースしていませんか?
  9. 9. 本当にテストしてますか? リロードデバッグですか? 実行タイミングが同じだというだけで、関連の無い 死亡フラグ コードを同じ場所に追記しまくってませんか? それをリロードでデバッグして「テストをしないで」 リリースしていませんか? 結合テストだけしてテストした気になっていませんか?
  10. 10. にんげんさんてすとしないです?
  11. 11. だって・・・ DBが絡むから値固定できないし ファイルに吐きだすから値検証できないし ブラウザから入力しないとダメだし
  12. 12. だって・・・ DBが絡むから値固定できないし 死亡フラグ ファイルに吐きだすから値検証できないし ブラウザから入力しないとダメだし
  13. 13. 結合テストをして意味があるの は単体テストをやり尽くしたあ とからです
  14. 14. UnitTestってなに? 身も蓋もない言い方をすれば単体テスト ただし、本セッションで言う単体テストは xUnit系テスト、主にPHPUnitのテスト メソッドに色んなパターンの引数を渡して戻 り値が合ってるか比べるだけです
  15. 15. つまり、こんなコードを
  16. 16. こうテスト
  17. 17. UnitTestの考え方 “単体”での確認が出来れば良い 故に呼んでるメソッドの先の正しさは気にし なくて良い(その先の正しさは、それ単体で確 認するから) メソッド単体での正しさを徹底的に確認する
  18. 18. UnitTestのメリット 環境から切り離してロジック単体をテストで きる プログラムとして保存するから何度でも実行 出来る。そして速い。(回帰テスト自動化) 電算機のテストは正確 ("hoge" != 'hoge ')
  19. 19. UnitTestのデメリット テストを作るのは時間がかかる 場合によってはテストのためにクラス設計を 歪める必要がある 必ずしも、それで全てのバグを検出すること が出来ないので過信は禁物
  20. 20. だからと言って、単体 テストしない理由には なりません
  21. 21. ここから本題
  22. 22. UnitTestのためのクラス設計 UnitTestを意識してクラス設計する必要がある 故に既存のコードをテストに入れるのは大変 どれだけ大変かはレガシーコード改善ガイド を読むと良いです
  23. 23. UnitTestのための クラス設計の指針 強い“依存”を徹底的に排除する クラス間の依存 外部システムへの依存 複雑度を下げる
  24. 24. モック そのクラスのように振る舞うダミーのこと ダミーで入力を検証する ダミーで出力を固定する
  25. 25. こういうこと
  26. 26. モック モックを使うということはオブジェクトを差し替える ということ
  27. 27. モックを使うための注意 つまり・・・
  28. 28. モックを使うための注意 メソッド内で new してたら差し替えられない staticメソッド呼び出しは差し替えられない 組み込み関数は差し替えられない final な クラスも差し替えられない(モックは 継承して作る)
  29. 29. 依存の排除(クラス間の依存) コンストラクタやメソッドの引数でオブジェ クトを渡す(ファクトリを渡すのも可) セッタで上書き可能なメンバ変数にする
  30. 30. オブジェクト渡し
  31. 31. オブジェクト渡し
  32. 32. セッタで上書き
  33. 33. セッタで上書き
  34. 34. おまけ(依存なし)
  35. 35. 依存の排除(外部システム) プロキシパターン
  36. 36. プロキシパターン DBなんか文字列(SQL文)渡したら配列を返すク ラスです
  37. 37. プロキシパターン ファイルの読み込みなんか文字列(path)を渡し たら文字列を返すただのメソッドです
  38. 38. 複雑度を下げる 同じタイミングで実行されるからと言って関 連の無いコードを同じ場所に書かない ifの入れ子になったらメソッドを分割する ループの中は別メソッドにする(走査と操作は 分ける)
  39. 39. ざっくばらんなまとめ そのクラスに関連するオブジェクトはメンバ 変数にする メンバ変数はセッターで上書き可能にする メソッドは小まめに分ける 外部システムとの絡みはラッパーを作る
  40. 40. テストしない理由? テスト書いている時間がないから 上司がテストに対する理解がなくて時間とら せてくれないから あとで書くから 複雑過ぎてテストが書けないから
  41. 41. テストしない理由? テスト書いている時間がないから 死亡フラグ 上司がテストに対する理解がなくて時間とら せてくれないから あとで書くから 複雑過ぎてテストが書けないから
  42. 42. 時間無くてテスト書けない それは手動でテストしている時間も無いはずな のでリリースしてはならないコードです
  43. 43. 上司の理解を得られない 理解を得る必要はありません 勝手に書いてください 自分の時間と健康と心の平穏を守るためにや るのです
  44. 44. 複雑過ぎてテスト書けない それは、そもそも手動でもテストできません メソッドを分割して複雑度を下げてください
  45. 45. あとで書く 絶対にあとで書きません
  46. 46. 書いておけば妖精さんがテ ストしてくれます
  47. 47. ご清聴ありがとうございました http://tech.aainc.co.jp
  • tamatamada

    Aug. 17, 2017
  • taroyamakawa18

    Aug. 14, 2017
  • yukkun007

    Jul. 25, 2017
  • takeokouno

    May. 18, 2015
  • yamadamasatsugu

    Jul. 21, 2014
  • yurikawamoto94

    May. 1, 2014
  • kekosasaki

    Jan. 15, 2014
  • YokotaEiji

    Apr. 12, 2013
  • takanobumiyazawa9

    Feb. 12, 2013
  • BungoHatayama

    Jan. 6, 2013
  • yunosuke

    Oct. 30, 2012
  • nemurin

    Oct. 2, 2012
  • ruibando

    Oct. 2, 2012
  • okam0n

    Oct. 2, 2012
  • m19cmjigen

    Oct. 2, 2012
  • nakanoakihito

    Sep. 30, 2012
  • koutetsu666

    Sep. 24, 2012

Views

Total views

10,449

On Slideshare

0

From embeds

0

Number of embeds

811

Actions

Downloads

52

Shares

0

Comments

0

Likes

17

×