Pro Yearly is on sale from $80 to $50! »

「質」のいいユニットテストを書くためのプラクティス / practices to write better unit test

「質」のいいユニットテストを書くためのプラクティス / practices to write better unit test

#phperkaigi 2019での発表資料です。

88964b936e864ca7d326272eaa70fa9a?s=128

Kazuki Higashiguchi

March 29, 2019
Tweet

Transcript

  1. © - BASE, Inc. 「質」のいいユニットテストを 書くためのプラクティス . . #phperkaigi -

    @hgsgtk
  2. © - BASE, Inc. このトークの全体図

  3. © - BASE, Inc. このトークの⽬標 「初級者」から「中級者」へ

  4. © - BASE, Inc. 想定する「初級者」 • ユニットテストフレームワークの⽂法がわかる • ⼀通りユニットテストを書いた •

    どういうテストが良いかわからない
  5. © - BASE, Inc. ユニットテストについて話すこと 考え⽅と実践 - 「How Testing?」 ⽬的

    - 「Why Testing?」 まとめ - 「That’s why Testing」
  6. © - BASE, Inc. ⾃⼰紹介 東⼝和暉 (Kazuki Higashiguchi) Twitter /

    GitHub : @hgsgtk サーバーサイドエンジニア BASE BANK, Inc. / Dev Division
  7. © - BASE, Inc. ユニットテストについて話すこと 考え⽅と実践 - 「How Testing?」 ⽬的

    - 「Why Testing?」 まとめ - 「That’s why Testing」
  8. © - BASE, Inc. 「費⽤対効果の⾼い」 このトークでの「質」 の定義

  9. 費⽤対効果?

  10. 我々はなぜ ユニットテストを書くのか?

  11. © - BASE, Inc. なぜユニットテストを書くのか • 品質向上、バグを防ぎたい? • テストによるドキュメンテーション? •

    設計改善の指標?
  12. © - BASE, Inc. 根本的な理由は コスト削減

  13. © - BASE, Inc. コスト削減の指標 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS
  14. © - BASE, Inc. ユニットテストによるコスト削減 ⼿動ユニットテストのコスト ドキュメンテーションコスト 設計改善によるメンテナンスコスト ⽋陥の早期発⾒による修正コスト デバッグコスト

  15. © - BASE, Inc. ユニットテストの作成‧維持コスト 新規テスト作成コスト テスト実⾏時間の待ちコスト 既存テスト維持コスト ⾃動テストのためのCI維持コスト ユニットテストの学習コスト

  16. © - BASE, Inc. コスト削減の指標 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  17. © - BASE, Inc. 「テストの経済性」 • 『xUnit Test Patterns』より 「テストの経済性」

    • 最初は、⾃動化テストの学習‧ 実践コストによってコストが嵩 む • 徐々に落ち着いてきて、テスト による節約コストも増えてくる • 結果として、コストは相殺され ていく ref: https://qiita.com/hgsgtk/items/ 00daa278516d1995dac6
  18. © - BASE, Inc. テストの⾮経済性 • 維持コストが⾼いテストがテス ト⾃⾝のコストが上げていく • 可読性が悪い

    • 修正頻度が多い • 修正が難しい • テストによる節約コストも少な い効果の薄いテスト • 結果的にトータルコストが増⼤ していく ref: https://qiita.com/hgsgtk/items/ 00daa278516d1995dac6
  19. © - BASE, Inc. コスト削減の指標 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ >
  20. © - BASE, Inc. まとめ:⽬的 - 「Why Testing?」 • 根本的な⽬的はコスト削減

    • xUTPの「テストの経済性」 • 費⽤対効果の⾼いユニットテストを⽬指す
  21. © - BASE, Inc. まとめ:⽬的 - 「Why Testing?」 「⽬的」

  22. ここで⼀旦CM

  23. © - BASE, Inc. BASEのプロダクトについて ネットショップ作成サービス 「BASE」 ショッピングアプリ 「BASE」 価値の交換をよりシンプルにし、

    世界中の⼈々が最適な経済活動を⾏えるようにする。 MISSION
  24. © - BASE, Inc.

  25. はい

  26. © - BASE, Inc. ユニットテストについて話すこと 考え⽅と実践 - 「How Testing?」 ⽬的

    - 「Why Testing?」 まとめ - 「That’s why Testing」
  27. © - BASE, Inc. 費⽤対効果の良いテストを書くために、 何を意識するべきか ユニットテストの「考え⽅」

  28. © - BASE, Inc. ユニットテストの「考え⽅」 「考え⽅」

  29. © - BASE, Inc. ユニットテストの「実践」 「実践」

  30. 意図を伝えるテスト

  31. © - BASE, Inc. 意図を伝えるテスト

  32. © - BASE, Inc. 意図を伝えるテスト • テストはメンテナンスされていく • 読み⼿にとって理解しやすくメンテナンスしやすいテ ストへ

  33. © - BASE, Inc. 主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  34. © - BASE, Inc. Test as Documentation 意図を伝えるテスト

  35. © - BASE, Inc. このメソッドはどういう仕様? public function canUse(int $user_id): bool

    { $user = $this->User->findById($user_id); if (empty($user)) { return false; } if (!$user->isProhibit()) { return false; } if ($user->status === 7) { return false; } return true; }
  36. © - BASE, Inc. ユニットテストがない場合 ΤϯδχΞ このメソッド何をし てくれるんだろう? • 動作コードを読んで理解する

    • もしあれば、ドキュメント(単体仕 様書など)を読む • 実際に動かして理解する • それでもわからない場合は、作成者 に聞きに⾏く
  37. © - BASE, Inc. ユニットテストがない場合 ΤϯδχΞ このメソッド何をし てくれるんだろう? • 動作コードを読んで理解する

    • もしあれば、ドキュメント(単体仕 様書など)を読む • 実際に動かして理解する • それでもわからない場合は、作成者 に聞きに⾏く よくあるケース • 複雑なコードでひと⽬ではわからない • 意図通りなのかわからない
  38. © - BASE, Inc. ユニットテストがない場合 ΤϯδχΞ このメソッド何をし てくれるんだろう? • 動作コードを読んで理解する

    • もしあれば、ドキュメント(単体仕 様書など)を読む • 実際に動かして理解する • それでもわからない場合は、作成者 に聞きに⾏く よくあるケース • そもそもない • メンテナンスされてなくて古い
  39. © - BASE, Inc. ユニットテストがない場合 ΤϯδχΞ このメソッド何をし てくれるんだろう? • 動作コードを読んで理解する

    • もしあれば、ドキュメント(単体仕 様書など)を読む • 実際に動かして理解する • それでもわからない場合は、作成者 に聞きに⾏く よくあるケース • その対象だけを動かすのが難しい • 動かすための前準備に時間がかかる • 繰り返し実⾏するのが⼿間
  40. © - BASE, Inc. ユニットテストがない場合 ΤϯδχΞ このメソッド何をし てくれるんだろう? • 動作コードを読んで理解する

    • もしあれば、ドキュメント(単体仕 様書など)を読む • 実際に動かして理解する • それでもわからない場合は、作成者 に聞きに⾏く よくあるケース • そもそも作成者が現場にいない • 作成者も覚えてない
  41. © - BASE, Inc. ユニットテストがある場合 ΤϯδχΞ このメソッド何をし てくれるんだろう? • ユニットテストを読んで理解する

    • ユニットテストを実⾏して理解する • 動作コードを読んで理解する • 要件を知るためのドキュメントを読む • (それでもわからない場合)作成者に聞 きに⾏く
  42. © - BASE, Inc. テストを読んで仕様を理解する <?php /** * @param int

    $user_id * @param bool $expected * * @see StatusChecker::canUse() * @dataProvider dataProvider_canUse */ public function test_canUse(int $user_id, bool $expected) { $checker = new StatusChecker(); $this->assertSame($expected, $checker->canUser($user_id)); } /** * @return array */ public function dataProvider_canUse(): array { return [ ‘௨ৗϢʔβʔ͸ར༻Մೳͱ൑ఆ’ => [1, true], ‘Ϣʔβʔ͕ଘࡏ͠ͳ͍৔߹͸ར༻ෆՄͱ൑ఆ’ => [9999, false], ‘ېࢭϢʔβʔͷ৔߹͸ར༻ෆՄͱ൑ఆ’ => [2, false], ‘Ϣʔβʔ͕཭୤Ϣʔβʔͷ৔߹͸ར༻ෆՄͱ൑ఆ’ => [3, false], ]; }
  43. © - BASE, Inc. テストを実⾏して理解する⽅法について

  44. © - BASE, Inc. Simple Test Test as Documentation

  45. © - BASE, Inc. このテストは何をしている? public function testConditional() { $Flight

    = new EagerFlight(); $Flight->setNumber(1); if ($Flight->number === 1) { $this->assertTrue($Flight->cancel()); } else if ($Flight->number === 2) { $this->assertTrue($Flight->cancel2()); } if ($Flight->airline_code === 'special') { $this->assertSame(2, $Flight->number); } }
  46. © - BASE, Inc. Simple Test • テストは読み書きする上でシンプルであるべき • ⼩さいテスト

    • 1回につき”ひとつのこと”をテストする • 重点を置くべきは、「テストを書くこと」ではなく 「テストをすること」
  47. © - BASE, Inc. Name to Convey Intent Test as

    Documentation
  48. © - BASE, Inc. このテストはどういうパターン? <?php /** * @param int

    $user_id * @param bool $expected * * @see StatusChecker::canUse() * @dataProvider dataProvider_canUse */ public function test_canUse(int $user_id, bool $expected) { $checker = new StatusChecker(); $this->assertSame($expected, $checker->canUser($user_id)); } /** * @return array */ public function dataProvider_canUse(): array { return [ [1, true], [9999, false], [2, false], [3, false], ]; }
  49. © - BASE, Inc. Name to Convey Intent • 意図、期待値を伝えるための命名‧ラベリング

    • 読み⼿に伝わる “ドキュメント” を⽬指す
  50. © - BASE, Inc. テストを改善する <?php /** * @param int

    $user_id * @param bool $expected * * @see StatusChecker::canUse() * @dataProvider dataProvider_canUse */ public function test_canUse(int $user_id, bool $expected) { $checker = new StatusChecker(); $this->assertSame($expected, $checker->canUser($user_id)); } /** * @return array */ public function dataProvider_canUse(): array { return [ ‘௨ৗϢʔβʔ͸ར༻Մೳͱ൑ఆ’ => [1, true], ‘Ϣʔβʔ͕ଘࡏ͠ͳ͍৔߹͸ར༻ෆՄͱ൑ఆ’ => [9999, false], ‘ېࢭϢʔβʔͷ৔߹͸ར༻ෆՄͱ൑ఆ’ => [2, false], ‘Ϣʔβʔ͕཭୤Ϣʔβʔͷ৔߹͸ར༻ෆՄͱ൑ఆ’ => [3, false], ]; }
  51. © - BASE, Inc. 振り返り:主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  52. テストを独⽴させる

  53. © - BASE, Inc. テストを独⽴させる

  54. © - BASE, Inc. 主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  55. © - BASE, Inc. SUTに対して疎結合 テストを独⽴させる

  56. © - BASE, Inc. SUTに対して疎結合

  57. SUT?

  58. © - BASE, Inc. SUT - Sytem Under Test •

    テストしている対象を⽰す • ユニットテストの場合、テスト対象のクラス‧メ ソッドなど • 書籍『xUnit Test Patterns: Refactoring Test Code』で登場する⽤語 https://www.amazon.co.jp/dp/ /ref=cm_sw_r_tw_dp_U_x_Y kJCb EX F
  59. © - BASE, Inc. SUTとテストクラスの関係性

  60. © - BASE, Inc. SUTとテストクラスの関係性 • CartTestクラスはCartクラスに依存している • クラス間の密結合はメンテナンスしていく上で弊害 になりうる

    • テストクラス‧SUT間もそれは同様
  61. © - BASE, Inc. テストがSUTに密結合する弊害 • SUTの変更に敏感に反応してテストが落ちる • ex. Private

    methodの実装変更 • SUTの内部実装を変えるたびに、テストを修正する • 壊れやすいテスト • 維持コストを抑えるために疎結合を意識する
  62. © - BASE, Inc. Test Public Method SUTに対して疎結合

  63. © - BASE, Inc. Test Public Method • SUTをブラックボックスとして⾒る •

    ブラックボックスの外から⾒える Public Method に 対してテストするのが Better • 逆を返すと、Private Methodはテストしない⽅が Better • ブラックボックスの外から⾒えない
  64. © - BASE, Inc. 尺度:Methodの “安定度” • Public Method •

    外部から使⽤される想定を持つ • 変更の頻度が少ない、“安定”している • Private Method • 外部から使⽤される想定はない • 責務の “不安定” さ • 変更の頻度が⾼い、 “不安定”
  65. © - BASE, Inc. Do Not Test Private Method •

    変更の頻度が⾼い Private Method • → テストの修正の頻度も⾼くなる • →メンテナンスコストの増⼤ • Private Methodは、同⼀クラスのPublic Methodに よって使⽤される • → Public Testのテストでカバーできる
  66. © - BASE, Inc. IF YOU CAN, Do Not Test

    Private Method • 現実の “レガシーコード” を⽬の前にするとテストし たいときはある • Private methodを切り出していくのが Better • それも苦しい時には、リファクタリングの障壁をへら すために、テストを書く選択肢もひとつある
  67. © - BASE, Inc. Isolate SUT from others SUTに対して疎結合

  68. © - BASE, Inc. 突然テストが落ちるようになりました、なぜ? public function test_canUse(int $user_id, bool

    $expected) { $search = CloudSearchWrapper::factory(); $search->conditions() ->keyword(‘test’, ‘title’) ->sort(‘list_order asc’); $search->documentBatch($this->addJson()); sleep(3); $result = $search->search($search->conditions()->query()); }
  69. © - BASE, Inc. Isolate SUT from others • SUTを他のソフトウェア(外部システム)から隔離す

    る • 依存している場合 • 外部システムの動作変更‧状態に応じて、テストが 突然落ちる • Dependency Injectionなどの技法の活⽤ • 依存しているオブジェクトをTest Doubleに置き換 える
  70. © - BASE, Inc. テスト間の独⽴ テストを独⽴させる

  71. © - BASE, Inc. テスト間の独⽴

  72. © - BASE, Inc. テスト間の独⽴性 • テストが相互依存‧順序依存する場合、 “独⽴性”が ない状態 •

    “独⽴性” がない弊害 • テストが通ったり落ちたりする • 「ローカルでは通るがCIでは通らないことがある」 • 不安定なテスト
  73. © - BASE, Inc. 順序依存するテスト

  74. © - BASE, Inc. 順序依存するテスト

  75. © - BASE, Inc. Depend in Fixture properly テスト間の独⽴

  76. © - BASE, Inc. Depend in Fixture properly • データベースを⽤いるテストを⾏う場合

    Fixture を⽤ いる • 全テストケースで共有する 共有されたFixture • 共有しているためテストの追加‧変更に影響を受ける
  77. © - BASE, Inc. 共有されたFixture

  78. © - BASE, Inc. 共有されたFixture

  79. © - BASE, Inc. 共有されたFixture TestE追加のためにFixtureを変更した

  80. © - BASE, Inc. 共有されたFixtureのMerit/Demerit • Merit • 共通のマスター系テーブルであれば、⼀回の Fixture作成で済む

    • Demerit • テスト間の独⽴性が損なわれる • エッジケースのテストのやりにくさ
  81. © - BASE, Inc. テストケース専⽤Fixture • テストケースごとに⽤意するFixture (Fresh Fixture) •

    テスト間の独⽴性の向上 • ex. Laraval => Factory‧Faker
  82. © - BASE, Inc. 共有 & 専⽤ Fixture

  83. © - BASE, Inc. Fixtureに適切に依存する • 全テストで共有することが有益なケース • 基本となるFixtureを定義 •

    ex. 「通常のユーザー」 • 使いみちが限定されるエッジケースのテスト • テストケース専⽤Fixtureを⽤意する • ex. 「利⽤禁⽌になったユーザー」
  84. © - BASE, Inc. Tear Down Global Changes テスト間の独⽴

  85. © - BASE, Inc. Tear Down Global Changes • テストがグローバルな状態変化を⽣み出す場合

    • $_SERVERの書き換え • Session状態の更新 • トランザクション • テスト時間 (timecop使⽤の場合など) • 他のテストに影響を及ぼす • テスト‧SUTの状態変化に応じてtearDownしておく
  86. © - BASE, Inc. 振り返り:主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  87. 重複を最⼩限に

  88. © - BASE, Inc. 重複を最⼩限に

  89. © - BASE, Inc. 主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  90. © - BASE, Inc. DRY in Test Code 重複を最⼩限に

  91. © - BASE, Inc. DRY in Test Code • DRY

    (Don’t Repeat Yourself)は、テストコードにお いても同じく意識 • テストコードの可読性を上げる • フレームワーク‧カスタムのTest Utilityの活⽤によ り、より意図を語るテストへ
  92. © - BASE, Inc. 振り返り:主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  93. テスト容易な設計

  94. © - BASE, Inc. 重複を最⼩限に

  95. © - BASE, Inc. 主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  96. © - BASE, Inc. テスト容易な設計 • テストコードに対する意識‧改善では、費⽤対効果の ⾼いテストは実現できない • プロダクションコードのテスタビリティの向上‧改善

    が必要
  97. © - BASE, Inc. TDD テスト容易な設計

  98. © - BASE, Inc. TDD - Test-Drive Development • プログラム開発⼿法のひとつ

    • 「動作するきれいなコード」をゴールとする • Red-Green-Refactor のサイクルを回す • 最初に Red にするため、テストファーストで進める
  99. © - BASE, Inc. TDDとテスト容易性 • テストファーストによって、テスト容易性が強制され る • テストから先に書くため、基本的な⽋陥はテスト実⾏

    によって気がつくことができる • テスト実⾏だけで実装中のコードをデバッグできる
  100. © - BASE, Inc. TDDによるテスト容易性の強制について https://speakerdeck.com/hgsgtk/tesutokaxin-iwojie-jue-surutesutoqu-dong-kai-fa-falseahuroti-at-phpkanhuarensuxian-tai-2019

  101. © - BASE, Inc. 振り返り:主に期待する効果 Ϣχοτςετ ʹΑΔ ίετ࡟ݮ Ϣχοτςετ ͷ

    ࡞੒ɾҡ࣋ίετ VS • खಈϢχοτςετͷίετ • ܽؕͷૣظൃݟʹΑΔमਖ਼ίετ • υΩϡϝϯςʔγϣϯίετ • σόοάίετ • ઃܭվળʹΑΔϝϯςφϯείετ • ৽نςετ࡞੒ίετ • طଘςετҡ࣋ίετ • ςετ࣮ߦ࣌ؒͷ଴ͪίετ • ࣗಈςετͷͨΊͷCIҡ࣋ίετ • Ϣχοτςετͷֶशίετ
  102. © - BASE, Inc. まとめ:考え⽅と実践 - 「How Testing?」 • コスト削減を達成するための「考え⽅」

    • 考え⽅に基づいた「実践」によって、効果を得る
  103. © - BASE, Inc. ユニットテストについて話すこと 考え⽅と実践 - 「How Testing?」 ⽬的

    - 「Why Testing?」 まとめ - 「That’s why Testing」
  104. © - BASE, Inc. 良いテストを書くのは難しい • 「テストを書く」ことは⽐較的簡単 • 費⽤対効果の⾼いテストを書くのは難度が上がる •

    費⽤対効果の⾼いテストを⽬指すのは、考えて実践し ていく必要がある
  105. © - BASE, Inc. 費⽤対効果を⾼めるには “テストにコストがかかることの解決⽅法は、テスト をやめることではありません。うまくなることです。” Sandi Metz. オブジェクト指向設計実践ガイド 〜Rubyでわかる

    進化しつづける柔軟なアプリケーションの育て⽅ https://gihyo.jp/book/2016/978-4-7741-8361-9
  106. Enjoy Happy Testing Life

  107. © - BASE, Inc. 補⾜:参考書籍 『xUnit Test Patterns: Refactoring Test

    Code』 https://www.amazon.co.jp/dp/ / ref=cm_sw_r_tw_dp_U_x_Y kJCb EX F 『オブジェクト指向設計実践ガイド 〜Rubyでわかる 進化しつづける柔 軟なアプリケーションの育て⽅』 https://gihyo.jp/book/ / - - - -
  108. © - BASE, Inc. 補⾜:関連資料 xUnit Test Patternsから学ぶ12個のユニットテストの原則 https://qiita.com/hgsgtk/items/a a

    d d b d xUnit Test Patternsから学ぶユニットテストの6つの⽬指すべきゴール https://qiita.com/hgsgtk/items/ daa d dac xUnit Test Patternsから学ぶテストアンチパターン https://speakerdeck.com/hgsgtk/testing-anti-pattern-learned-in-xunit-test- pattern ユニットテスト初⼼者を脱するために⾝につけたいN個のこと https://speakerdeck.com/hgsgtk/n-points-to-get-out-of-unit-test-beginner- number-phpstudy
  109. © - BASE, Inc. 補⾜:関連資料 テストが⾟いを解決するテスト駆動開発のアプローチ https://speakerdeck.com/hgsgtk/tesutokaxin-iwojie-jue-surutesutoqu-dong- kai-fa-falseahuroti-at-phpkanhuarensuxian-tai- PHPバージョンアップと決済リプレイスを⽀えたユニットテスト https://speakerdeck.com/hgsgtk/phpbaziyonatuputojue-ji-ripureisuwozhi-

    etayunitutotesuto-number-phpcon テストを書いたことがないエンジニアがテストを書けるようになるまで やったこと https://speakerdeck.com/hgsgtk/tesutowoshu- itakotokanaiensiniakatesutowoshu-keruyouninarumateyatutakoto-at- phpkanhuarensuguan-xi-