Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実践! ユニットテスト入門

実践! ユニットテスト入門

PHPカンファレンス沖縄2022の登壇資料です。
発表時間の関係で収まりきらなかった内容を大幅に加筆しています。

以下プロポーザルの内容を転記。

----
テスト書いてますか?
テストを書く理由と実際のテストコードを紹介する実践編に分け、TDD を3年間実践してきた経験に基づいてお話しします。

テストを書いたことのない方が、テストを書いてみたいと思ってもらえることを目指します。
サンプルコードは PHP + PHPUnit ですが、他言語でも通用する考え方を紹介します。

■ 概要
・なぜテストコードを書くのか
・レガシーコードとは、テストのないコード
・テストはコストが安いフィードバックループである

■ 実践編
・テストケースは日本語で書こう
・いろんな assertion を知ろう
・arrange / act / assertion のテストコード実装パターン
・set up / tear down を使って前処理/後処理をする
・dataProvider でテストをまとめる(ただし早すぎる抽象化に気をつけよう)

https://fortee.jp/phpcon-okinawa-2022/proposal/27bbf06e-f4b8-4697-ad29-3eddd7d7ecc6

panda_program

August 26, 2022
Tweet

More Decks by panda_program

Other Decks in Programming

Transcript

  1. 1
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    PHPカンファレンス沖縄2022(2022.08.27)
    実践!
    ユニットテスト入門
    プログラミングをするパンダ (@Panda_Program)
    #phpcon_okinawa #unit_testing

    View Slide

  2. 2
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    自己紹介
    ● BASE株式会社
    ● 所属:BASE / Product Dev / CRM3
    ● 現在のお仕事:シニアエンジニア
    ○ フロントエンドで React(Next.js)を書いたり Vue.js を書いたり
    ○ バックエンドでは PHP を書いてます
    ○ 最近は顧客管理機能(CRM)を開発してます
    ● 好きなことと活動
    ○ DevOps とアジャイルの開発プロセス(特にXP)が好き
    ○ Software Design 2022年3月号で TDD 特集の2,3部を執筆しました
    ○ twitter: @Panda_Program
    プログラミングをするパンダ(@Panda_Program、Mashu Kushibiki)

    View Slide

  3. 3
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    自己紹介
    個人開発が好き
    プログラミングをするパンダ(@Panda_Program、Mashu Kushibiki)
    ブログ書いてます
    https://panda-program.com/
    ビールの画像投稿サイト作りました
    https://beerbreak.info/
    Next.js + Vercel + Supabase

    View Slide

  4. 4
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    本発表の対象者

    View Slide

  5. 5
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    本発表の対象者
    ユニットテストを
    書いたことがない
    開発者

    View Slide

  6. 6
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    本発表の目標
    テストを書くための
    モチベーションを上げる

    明日からテストを実践するための
    知識を得る

    3 テストを通して、ソフトウェア開発の
    全体像に触れる

    View Slide

  7. 7
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    本発表の裏目標
    テストの入門者を初心者にする

    テストの初心者を中級者にすることを目的と
    した「『質』のいいユニットテストを書くた
    めのプラクティス」という良いスライドに進
    むための知識を得る
    https://speakerdeck.com/hgsgtk/practices-to-write-better-unit-
    test


    View Slide

  8. 8
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    本発表の位置付け
    https://roadmap.sh/backend

    View Slide

  9. 9
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    本発表の位置付け
    https://roadmap.sh/backend

    View Slide

  10. 10
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストを書くための
    モチベーションを
    上げる

    View Slide

  11. 11
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    小話をします
    (半分実話)

    View Slide

  12. 12
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    パンダくん
    新人PG
    キツネさん
    エースPG
    ゴリラ先輩
    PJリーダー
    登場人物

    View Slide

  13. 13
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある
    受託開発会社の
    お話

    View Slide

  14. 14
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある会社のお話
       「新人のパンダです。よろしくお願いします!」
       「よろしくね」

    View Slide

  15. 15
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある会社のお話
       「新人のパンダです。よろしくお願いします!」
       「よろしくね」
       「おーいゴリラくん、先日納品した機能にバグが
        出ちゃってね」
       「お客さんに原因と再発防止策を説明して欲しいんだ」

    View Slide

  16. 16
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある会社のお話
       「新人のパンダです。よろしくお願いします!」
       「よろしくね」
       「おーいゴリラくん、先日納品した機能にバグが
        出ちゃってね」
       「お客さんに原因と再発防止策を説明して欲しいんだ」
       「承知しました!」

    View Slide

  17. 17
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある会社のお話
      「エースのキツネくんが担当したところだね」
       「キツネくんはお客さんの欲しい機能をすぐに作れる天才なんだ
        けど、結構バグが出ちゃうんだ」

    View Slide

  18. 18
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある会社のお話
      「エースのキツネくんが担当したところだね」
      「(それってほんとの天才か...?)」
       「キツネくんはお客さんの欲しい機能をすぐに作れる天才なんだ
        けど、結構バグが出ちゃうんだ」

    View Slide

  19. 19
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    とある会社のお話
      「エースのキツネくんが担当したところだね」
       「キツネくんはお客さんの欲しい機能をすぐに作れる天才なんだ
        けど、結構バグが出ちゃうんだ」
      「(それってほんとの天才か...?)」
       「お気をつけて!」
       「ソフトウェアにバグはつきものだよね。オンボーディングは
        他の人に頼むから、僕はもう行くね」

    View Slide

  20. 20
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    パンダくん帰宅

    View Slide

  21. 21
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing

    View Slide

  22. 22
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    自宅にて
      「バグ、大変そうだったな」
      「バグはお客さんに大きな迷惑がかかるんだ」

    View Slide

  23. 23
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    自宅にて
      「バグ、大変そうだったな」
    「GitHubが落ちると『今日の仕事は終わり』というツ
    イートでTLがいっぱいになるしなあ」
      「バグはお客さんに大きな迷惑がかかるんだ」
      「バグを避けるにはどうすれば良いんだろう?」

    View Slide

  24. 24
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    自宅にて
      「バグ、大変そうだったな」
    「GitHubが落ちると『今日の仕事は終わり』というツ
    イートでTLがいっぱいになるしなあ」
      「バグはお客さんに大きな迷惑がかかるんだ」
      「バグを避けるにはどうすれば良いんだろう?」
      「おっと、明日に備えてもう寝ないと」

    View Slide

  25. 25
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    パンダくん就寝
    夢の中で

    View Slide

  26. 26
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で

    View Slide

  27. 27
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で

    View Slide

  28. 28
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「ソフトウェアでバグを出したくないとな?」
      「だれ?」

    View Slide

  29. 29
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「ソフトウェアでバグを出したくないとな?」
      「テストの仙人だ!」
      「神田明神にお参りに行った甲斐があった」
      「だれ?」
      「仙人!じゃあもう安心だ」

    View Slide

  30. 30
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
    神田明神
    https://www.kandamyoujin.or.jp/omamori/detail/?id=7

    View Slide

  31. 31
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「私は仙人だから神田明神は関係ないがな」

    View Slide

  32. 32
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「私は仙人だから神田明神は関係ないがな」
    「バグを出せば社内では上司や同僚からの信頼を失い、社外では 
    ユーザーからの信頼を失う」
      「どうも君はバグが怖いと見える。確かに怖い」
    「信頼を失ったユーザーは離脱し、サービスの売上は落ち、
     ひいては会社が倒産するかもしれない」

    View Slide

  33. 33
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
    「会社がなくなれば職を失う。失業を避けるためには、
     バグを出さないようにするのだ」
      「私は仙人だから神田明神は関係ないがな」
    「バグを出せば社内では上司や同僚からの信頼を失い、社外では 
    ユーザーからの信頼を失う」
      「どうも君はバグが怖いと見える。確かに怖い」
    「信頼を失ったユーザーは離脱し、サービスの売上は落ち、
     ひいては会社が倒産するかもしれない」

    View Slide

  34. 34
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「バグを防ぐにはテストが良いぞ」
      「テストって?何から始めればいいの?」

    View Slide

  35. 35
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「バグを防ぐにはテストが良いぞ」
    「まあ待て。画面での確認はしたことがあるか?」
      「テストって?何から始めればいいの?」
    「あります。でも本音を言うと面倒くさいです」

    View Slide

  36. 36
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    夢の中で
      「バグを防ぐにはテストが良いぞ」
    「まあ待て。画面での確認はしたことがあるか?」
    「では、ユニットテストから始めるのだ!」
      「テストって?何から始めればいいの?」
    「あります。でも本音を言うと面倒くさいです」

    View Slide

  37. 37
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ここまでのまとめ
    バグを出さないために
    テストは重要

    View Slide

  38. 38
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ここまでのまとめ
    ユニットテストから
    始めよう

    View Slide

  39. 39
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの種類
    手動テスト

    自動テスト


    View Slide

  40. 40
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの種類
    手動テスト(画面ポチポチ)

    自動テスト(テストコマンド実行)


    View Slide

  41. 41
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    PHPUnitの紹介
    ユニットテストは
    自動テストの一種

    View Slide

  42. 42
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    PHPUnitの紹介
    PHPUnit

    View Slide

  43. 43
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    PHPUnitの紹介
    自動テストは、ユニットテストから始めると良い
    PHPでユニットテストをするために PHPUnit を使おう
    https://phpunit.de/

    View Slide

  44. 44
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    PHPUnitの紹介
    $ composer require --dev phpunit/phpunit
    ディレクトリ構成と
    composer.jsonと
    インストールコマンド

    View Slide

  45. 45
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストクラスの作り方

    View Slide

  46. 46
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストクラスの作り方

    View Slide

  47. 47
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストクラスの作り方

    View Slide

  48. 48
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストクラスの作り方

    View Slide

  49. 49
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストクラスの作り方

    View Slide

  50. 50
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストクラスの作り方

    View Slide

  51. 51
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの実行結果
    テストが成功した
    = テストが通った(パスした)
    = テストがグリーンだ
    期待する値と実際の値が異なると...

    View Slide

  52. 52
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの実行結果

    View Slide

  53. 53
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの実行結果
    テストが失敗した
    = テストがレッドだ
    実際の値と期待する値の
    差分を表示してくれる
    プロダクションコードか
    テストコードがおかしいのでコード
    を修正する

    View Slide

  54. 54
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの実行結果
    . 成功したテスト
    F 失敗したテスト(Failure)
    E 予期せぬエラーで落ちたテスト(Error)

    View Slide

  55. 55
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの実行結果
    . 成功したテスト
    F 失敗したテスト(Failure)
    E 予期せぬエラーで落ちたテスト(Error)

    View Slide

  56. 56
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ユニットテストの
    位置付けは?

    View Slide

  57. 57
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストピラミッド

    View Slide

  58. 58
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストピラミッド
    「The Practical Test Pyramid」
    https://martinfowler.com/articles/practical-test-pyramid.html

    View Slide

  59. 59
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ユニットテストを
    たくさん書くことになる

    View Slide

  60. 60
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    明日からテストを
    実践するための
    知識を得る

    View Slide

  61. 61
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    良いテストを書くための
    テクニックを知ろう

    View Slide

  62. 62
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    1. テストケースは日本語で書こう
    ユニットテストの実践知識
    3. いろんな assertion を知ろう
    5. dataProvider でテストケースをまとめよう
    2. arrange / act / assert パターンで書こう
    4. setUp / tearDown で前後の処理をしよう

    View Slide

  63. 63
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストケースは
    日本語で書こう

    View Slide

  64. 64
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストケースは日本語で書こう

    View Slide

  65. 65
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストケースは日本語で書こう
    1テストケースにつき、1メソッド
    メソッド名なので、直感的に理解できる「日本語」がベスト
    格言「コードは書く時間より、読まれる時間の方が長い」
    格言「テストコードがドキュメントになるように書こう」
    このメソッドは何をしているのか(= what)を説明する

    View Slide

  66. 66
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストケースは日本語で書こう
    https://twitter.com/t_wada/status/904916106153828352

    View Slide

  67. 67
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストケースは日本語で書こう
    テストケース名のテクニック
    - 前提条件がある場合は、「method_Xのとき、Yを返す」と書く
    - 処理内容を一言で書きにくいときは、責務が多すぎる可能性あり
    - 処理を private メソッドに切り出す / 処理をクラスに切り出す
    - モデリングを見直してみる

    View Slide

  68. 68
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    arrange / act / assert
    パターンで書こう

    View Slide

  69. 69
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    arrange / act / assert パターンで書こう
    ・constructor で投稿のタイトルを設定
     する
    ・getTitle で投稿のタイトルを取得する
    (PHP 8 だともっとシンプルに書けるが、
    あえて省略していない)
    「Arrange Act Assert」
    http://wiki.c2.com/?ArrangeActAssert
    Post クラスの実装を変えてみる

    View Slide

  70. 70
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    arrange / act / assert パターンで書こう
    「Arrange Act Assert」
    http://wiki.c2.com/?ArrangeActAssert
    ・arrange で、前提条件と入力値を配置
    する
    ・act で、テスト対象(メソッド)を実
    行する
    ・assert で、期待した結果を得られるこ
    とをチェックする
    arrange / act / assert は
    ユニットテストの実装パターンの一つ

    View Slide

  71. 71
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    arrange / act / assert パターンで書こう
    「Arrange Act Assert」
    http://wiki.c2.com/?ArrangeActAssert
    arrange / act / assert パターンの
    メリット
    ・1テストケース 1act を意識できる
     ・左画像で getEditors は不要だとわかる
     ・複数の act があればテストケースを分ける
    ・自分が今どこを書いているのか自覚できる
     ・次に何を書くのか迷わなくなる
    なお、arrange は不要な時もある

    View Slide

  72. 72
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ちなみに

    View Slide

  73. 73
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    初見のテストは、以下の順番に読むとわかりやすい
    (テクニック)
    1. テストケース名
    2. 検証内容
    3. 前準備
    4. テスト対象の実行

    View Slide

  74. 74
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    初見のテストは、以下の順番に読むとわかりやすい
    (テクニック)
    1. テストケース名
    2. 検証内容  ← assert
    3. 前準備 ← arrange
    4. テスト対象の実行 ← act

    View Slide

  75. 75
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    いろんな
    assertion を知ろう

    View Slide

  76. 76
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    いろんな assertion を知ろう
    assertion(アサーション)は、値が真であることをプログラマが表明するためのもの
    $this->assertSame は最も基本となるアサーション
    「期待する値」と「実際の値」を比較した結果、
    同じならテストは success(成功)、違うなら fail

    View Slide

  77. 77
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    assertSame($val1, $val2)
    assertTrue($value)
    assertNull($value)
    assertEquals($val1,$val2)
    assertFalse($value)
    値の厳密な比較(===相当)
    $value が true である
    $value が null である
    値の緩い比較(==相当)
    $value が false である
    いろんな assertion を知ろう
    「PHPUnit Docs » 1. アサーション」
    https://phpunit.readthedocs.io/ja/latest/assertions.html

    View Slide

  78. 78
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    他にもあります

    View Slide

  79. 79
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    assertCount($num, $arr)
    assertContains($val, $arr)
    assertRegExp($ptn, $str)
    assertEmpty($arr)
    assertArrayHasKey($key, $arr)
    配列 $arr の要素が $num 個である
    配列 $arr が $val を含んでいる
    文字列 $str がパターン $ptn に
    マッチする
    配列 $arr が空配列である
    配列 $arr にキー $key が含まれている
    いろんな assertion を知ろう
    「PHPUnit Docs » 1. アサーション」
    https://phpunit.readthedocs.io/ja/latest/assertions.html

    View Slide

  80. 80
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    assertGreaterThan
    ($num1, $num2)
    assertFileExists($path)
    expectException($className)
    assertGreaterThanOrEqual
    ($num1, $num2)
    assertInstanceOf
    ($className, $instance)
    $num1 が $num2 より小さい
    ($num1 < $num2)
    ファイルパス $path にファイルがある
    $className の例外を throw する
    $num1 が $num2 以下である
    ($num1 <= $num2)
    $instance がクラス $className の
    インスタンスである
    いろんな assertion を知ろう
    「PHPUnit Docs » 1. アサーション」
    https://phpunit.readthedocs.io/ja/latest/assertions.html

    View Slide

  81. 81
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    いろんな assertion を知ろう
    各種アサーションは PHPUnit 由来のもの
    フレームワークが便利なアサーションを用意しているケースもある
    (ex. Laravel の assertDatabaseHas など)

    View Slide

  82. 82
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    いろんな assertion を知ろう
    配列をチェックするアサーションを並べてみた
    ・assertSame / assertCount / assertContains / assertNotEmpty

    View Slide

  83. 83
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    いろんな assertion を知ろう
    実際は、テストの意図をうまく表現できているアサーションだけで十分
    → 1テストケース、1つの意図

    View Slide

  84. 84
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    いろんな assertion を知ろう
    分割

    View Slide

  85. 85
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で
    前後の処理をしよう

    View Slide

  86. 86
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    2つのテストケースの arrange で重複が発生している

    View Slide

  87. 87
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    格言「繰り返しを避けること( DRY原則。Don’t Repeat Yourself.)」
    重複があるので、処理を共通化するリファクタリングを実施する
    (テストコードもリファクタリングの対象である)

    View Slide

  88. 88
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    前処理を setUp にまとめる
    ・setUp に、そのクラスの全てのテストケース 
    に共通な前処理(arrange) をまとめる
    ・setUp は、各テストケースの直前に必ず
     実行される
    後処理を tearDown にまとめる
    ・テストの前処理は setUp に、後処理は
     tearDown に記述する
    「PHPUnit Docs » 4. フィクスチャ」
    https://phpunit.readthedocs.io/ja/latest/fixtures.html

    View Slide

  89. 89
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    「PHPUnit Docs » 4. フィクスチャ」
    https://phpunit.readthedocs.io/ja/latest/fixtures.html
    setUp では、各テストケースに共通な
    arrange をまとめる
    ・オブジェクトの生成や日付管理ライブラリ
    で時間固定、DBへの接続に使うことが多い
     ・依存関係の解決(ex. new   
      PostPresenter(new Post))

    View Slide

  90. 90
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    tearDown は、あるテストが他の
    テストに影響を与えないようにする
    ために使う
    ・時間の固定を解除、テーブルのレコードを 
    リセットするなど
    ・本来、プロパティの unset はしなくて良い
    「PHPUnit Docs » 4. フィクスチャ」
    https://phpunit.readthedocs.io/ja/latest/fixtures.html

    View Slide

  91. 91
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    重複していた arrange が...

    View Slide

  92. 92
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう

    View Slide

  93. 93
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ちょっとした
    テクニック

    View Slide

  94. 94
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう

    View Slide

  95. 95
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    setUp / tearDown で前後の処理をしよう
    setUp にまとめるのではなく、
    前処理用の private メソッドを作ってもいい
    - 今回の例ならこちらの方が適している
    - タイトルと本文が、テストケースごとに異なるため
    - テスト対象ではない値は空文字にするなど柔軟な対応ができる

    View Slide

  96. 96
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider で
    テストケースをまとめよう

    View Slide

  97. 97
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    今は本文($body)が一行のテスト
    しかない
    「本文($body)が改行を含むとき、
     getBody() を実行すると
    改行が消えてしまうかも😰」
    どうする?
    (getter なのでそんなことはないが、一例として)

    View Slide

  98. 98
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    本文に改行があるとき、改行が削除
    されないか不安になった
    󰢃 画面ぽちぽち
    󰢃 var_dump での出力確認

    View Slide

  99. 99
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    不安をテストで解消する
    󰢏

    View Slide

  100. 100
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    テストを追加して、挙動を確認する

    View Slide

  101. 101
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    2つのテストケースの構造が同じ

    View Slide

  102. 102
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    格言「繰り返しを避けること( DRY原則。Don’t Repeat Yourself.)」
    どこで共通化する?

    View Slide

  103. 103
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    複数のテストケースの構造が同じ
    󰢃 setUp にまとめる
    全てのテストケースで重複しているわけではない
    (例えば、getTitle のテストケースでは arrange が異なる)

    View Slide

  104. 104
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    「PHPUnit Docs » 2. PHPUnit 用のテストの書き方(データプロバイダ)」
    https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers
    複数のテストケースの構造が同じ
    󰢏 データプロバイダーにまとめる
    処理が同様なら、テストの変数は「入力値」と「期待値」だ

    View Slide

  105. 105
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう

    View Slide

  106. 106
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストのロジックと
    入力値・期待値のデータに
    分ける

    View Slide

  107. 107
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    ロジック側
    ・複数のテストケースで共通の処理
    を1つにまとめる
    ・テストメソッドに引数を追加
     ・入力値と期待する値(データ)
    を受け取る
    「PHPUnit Docs » 2. PHPUnit 用のテストの書き方(データプロバイダ)」
    https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers

    View Slide

  108. 108
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    データ側
    ・データプロバイダーは、テストのデー
    タセットを配列で返す
    ・アノテーション @dataProvider は、
    データを受け取るテストメソッドに書く
    ・データプロバイダー名は「テスト対象
    のメソッド名 + Provider」がおすすめ
     ・今回は getBodyProvider
    「PHPUnit Docs » 2. PHPUnit 用のテストの書き方(データプロバイダ)」
    https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers

    View Slide

  109. 109
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    データ側
    ・返り値は配列
    (厳密には Iterator インターフェース
    を実装していれば良い)
    ・キーにテストケース名、値に入力値と
    期待する値を指定する
    ・メリット
     ・テストケースをまとめられる
     ・バリエーションの追加が簡単
    「PHPUnit Docs » 2. PHPUnit 用のテストの書き方(データプロバイダ)」
    https://phpunit.readthedocs.io/ja/latest/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers

    View Slide

  110. 110
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    注意点

    View Slide

  111. 111
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストケースがない時に
    dataProvider から
    書かない

    View Slide

  112. 112
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    テストケースが重複してから初めて、dataProvider を使う。
    最初から dataProvider を書き始めない。
    「頭の中で考えて同じだから」ではなく
    「目で見て」コードが重複していることを確認してから dataProvider を使う。
    そうしなければ、各テストケースで
    微妙に arrange が異なったり、assertion を増やしたい場合、
    dataProvider を解体する手戻りが発生してしまうため。

    View Slide

  113. 113
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    dataProvider でテストケースをまとめよう
    GitHub
    https://github.com/KushibikiMashu/unit-test-sample-php

    View Slide

  114. 114
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストを通して、
    ソフトウェア開発の
    全体像を学ぶ

    View Slide

  115. 115
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    発展的な内容

    View Slide

  116. 116
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    DevOps の考え方

    View Slide

  117. 117
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの位置付け
    Wikipedia - DevOps
    https://ja.wikipedia.org/wiki/DevOps#/media/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%A
    B:Devops-toolchain.svg

    View Slide

  118. 118
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの位置付け
    A Practical Guide to Testing in DevOps Japanese Edition
    https://leanpub.com/testingindevops-japanese-edition
    Continuous Testing

    View Slide

  119. 119
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストの位置付け
    A Practical Guide to Testing in DevOps Japanese Edition
    https://leanpub.com/testingindevops-japanese-edition
    ユニットテスト
    (ローカル、CIで実行)

    View Slide

  120. 120
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストピラミッド
    「The Practical Test Pyramid」
    https://martinfowler.com/articles/practical-test-pyramid.html

    View Slide

  121. 121
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストピラミッドを
    発展させた考え方

    View Slide

  122. 122
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    バグフィルター

    View Slide

  123. 123
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    DevOps バグフィルター
    A Practical Guide to Testing in DevOps Japanese Edition
    https://leanpub.com/testingindevops-japanese-edition
    ユニットテストで
    小さいバグを捉える
    バグが本番にまで
    行かないようにする
    = フィルター(網)

    View Slide

  124. 124
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ソフトウェアテストの7原則
    (JSTQB (日本ソフトウェアテスト資格認定委員会)制定)
    1. テストは「欠陥があること」しか示せない
    2. 全数テストは不可能

    View Slide

  125. 125
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    パンダ
    「バグを避けるには
    どうすれば良いんだろう?」

    View Slide

  126. 126
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    パンダ
    「バグを避けるには
    どうすれば良いんだろう?」
    DevOps 的な Answer
    1. みんなで、いろんなフェーズでテストをしよう
    2. ただし、どれだけテストをしても本番でバグは出る
    3. 本番でバグが出ても、ユーザー影響を最小限にするた
    め、すぐに変更を元に戻そう

    View Slide

  127. 127
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    コードを書いて
    給料を貰っているなら
    あなたはプロフェッショナル

    View Slide

  128. 128
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    プロフェッショナルなら
    テストを書いて
    ユーザーをバグから守ろう

    View Slide

  129. 129
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ご清聴
    ありがとうございました

    View Slide

  130. 130
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    Q&A

    View Slide

  131. 131
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    付録

    View Slide

  132. 132
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ①「質とスピード」

    View Slide

  133. 133
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ゴリラ
    「キツネくんはお客さんの欲しい機能を
    すぐに作れる天才なんだけど、
    結構バグが出ちゃうんだ」

    View Slide

  134. 134
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    内部品質が悪いと
    実装スピードが遅くなる

    View Slide

  135. 135
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    質とスピード
    「質とスピード(2022春版、質疑応答用資料付き)」和田 卓人(@t_wada)
    https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition?slide=54

    View Slide

  136. 136
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    質とスピード
    「質とスピード(2022春版、質疑応答用資料付き)」和田 卓人(@t_wada)
    https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition?slide=54

    View Slide

  137. 137
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    質とスピード
    「質とスピード(2022春版、質疑応答用資料付き)」和田 卓人(@t_wada)
    https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition?slide=54

    View Slide

  138. 138
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    「質とスピード」は
    ソフトウェア開発の
    両輪

    View Slide

  139. 139
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ゴリラ
    「実装は早いけどバグが出る」
    Answer
    コードを綺麗に保ち続けないと、
    機能追加、改修のたびに余分な工数が増える
    = 1ヶ月で実装速度が遅くなる
    →リファクタリングをし続けよう

    View Slide

  140. 140
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ゴリラ
    「実装は早いけどバグが出る」
    Answer
    バグの原因を分析しよう。原因は現場によって
    様々なので、対処法はケースバイケース。
    手動テスト、自動テストを組み合わせながら
    リリース前にバグを検知しよう。

    View Slide

  141. 141
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ②ユニットテストの
    更なる力

    View Slide

  142. 142
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ユニットテストは
    品質を高めるだけでなく
    設計にも使える

    View Slide

  143. 143
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDD
    TDD
    Test Driven Development
    テスト駆動開発

    View Slide

  144. 144
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDD
    「テスト駆動開発(TDD)とは何か。コードで実践方法を解説します」
    https://panda-program.com/posts/test-driven-development

    View Slide

  145. 145
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDD
    「テスト駆動開発(TDD)とは何か。コードで実践方法を解説します」
    https://panda-program.com/posts/test-driven-development

    View Slide

  146. 146
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    XP の計画/フィードバックループ

    View Slide

  147. 147
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    XP の計画/フィードバックループ

    View Slide

  148. 148
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストを先に書くと
    テストを書き忘れない
    (テストファースト)

    View Slide

  149. 149
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    実装方法がわからないとき、
    テストを設計手法とする
    (Test Driven Development)

    View Slide

  150. 150
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ③TDDの限界

    View Slide

  151. 151
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDD のテストは
    Testing ではなく
    Checking

    View Slide

  152. 152
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    ソフトウェアテストの7原則
    (JSTQB (日本ソフトウェアテスト資格認定委員会)制定)
    1. テストは「欠陥があること」しか示せない
    2. 全数テストは不可能

    ソフトウェアテストの7原則
    https://hkawabata.github.io/technical-note/note/Principle/7-Principl
    es-of-Software-Test.html

    View Slide

  153. 153
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    アジャイルテストの
    四象限

    View Slide

  154. 154
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    アジャイルテストの四象限
    Using Models to Help Plan Tests in Agile Projects
    https://www.informit.com/articles/article.aspx?p=2253544&ranMID=24808
    開発を支援する
    製品を評価
    (批評)する
    技術面
    ビジネス面

    View Slide

  155. 155
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    アジャイルテストの四象限
    Using Models to Help Plan Tests in Agile Projects
    https://www.informit.com/articles/article.aspx?p=2253544&ranMID=24808
    開発を支援する
    製品を評価
    (批評)する
    技術面
    ビジネス面

    View Slide

  156. 156
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    DevOps バグフィルター
    A Practical Guide to Testing in DevOps Japanese Edition
    https://leanpub.com/testingindevops-japanese-edition
    網目をすり抜けて
    本番でバグが出る
    可能性もある

    View Slide

  157. 157
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDD のテストは
    Testing ではなく
    Checking

    View Slide

  158. 158
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    Example-guided development
    (TDD, BDD, ATDD を xDD としてまとめた呼び方)
    「Example-guided development: A useful abstraction for the xDD family?」
    https://cucumber.io/blog/bdd/example-guided-development/

    View Slide

  159. 159
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDDは
    テスト技法ではなく
    設計手法である

    View Slide

  160. 160
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    TDDは設計手法
    https://roadmap.sh/backend

    View Slide

  161. 161
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストカバレッジが
    100%でも
    バグが出ないとは
    言い切れない

    View Slide

  162. 162
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    それでも開発者が書く
    「テスト」には
    大きな意味がある

    View Slide

  163. 163
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    テストでユーザーを
    バグから守ろう

    View Slide

  164. 164
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    さらなる学習のための資料
    TDD(テスト駆動開発)
    「テスト自動化とテスト駆動開発」講演資料(@yattom)
    https://yattom.hatenablog.com/entry/2021/04/01/102052
    「質問5. 実際にTDDで運用したとき、それでも不具合が発生したことがありました。
    データの量、質が問題視されたことがありました。 受け取った情報の信憑性は会話し
    ながら模索しないといけないのでしょうか」(@yattom)
    https://yattom.hatenablog.com/entry/2021/04/04/171531
    「テスト駆動開発の題材を目的別で紹介する」(@nihonbuson)
    https://nihonbuson.hatenadiary.jp/entry/2021/08/16/090000
    「SymfonyとDoctrineで簡単クリーンアーキテクチャ 〜プロトタイピングにこそクリーンなTDD
    が活きた話〜 」(ページ下部に動画あり)
    https://fortee.jp/phpcon-2021/proposal/37d95a00-37bd-41e3-bc4a-7db9414d7597

    View Slide

  165. 165
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    さらなる学習のための資料
    ATDD
    「TDDからATDDへ歩みをすすめる / Step to Acceptance test–driven development
    from TDD」(@hgsgtk)
    https://speakerdeck.com/hgsgtk/step-to-acceptance-test-driven-development-from-tdd
    モックを使った開発
    「実践テスト駆動開発」
    https://www.amazon.co.jp/dp/4798124583
    「スタブ・モックは本当に悪者なのか?〜テスト駆動開発をやめて、なお残すべき習慣とは (2)」
    https://twop.agile.esm.co.jp/finding-a-blind-spot-by-agile-test-quadrant-807179783360
    DevOps の観点から
    「A Practical Guide to Testing in DevOps Japanese Edition」(日本語)
    https://leanpub.com/testingindevops-japanese-edition

    View Slide

  166. 166
    © 2012-2022 BASE, Inc.
    #phpcon_okinawa #unit_testing
    Special Thanks
    資料レビューありがとうございました!
    キュアセブン(@cureseven、同僚)
    02(@cocoeyes02、同僚)
    東口さん(@hgsgtk、ex-BASE、Autify勤務)

    View Slide