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

テストコードリーディングのみでPHPUnitの仕様を理解してみる / Try to understand PHPUnit specification with test code reading only

02
September 25, 2022

テストコードリーディングのみでPHPUnitの仕様を理解してみる / Try to understand PHPUnit specification with test code reading only

PHPカンファレンス2022で使用したスライドです。
https://fortee.jp/phpcon-2022/proposal/386a0edd-c64a-407b-8201-b3e55e73441f

02

September 25, 2022
Tweet

More Decks by 02

Other Decks in Programming

Transcript

  1. #phpcon2022
    #track4
    2022/09/25 PHPカンファレンス2022
    @02
    テストコードリーディングのみで
    PHPUnitの仕様を理解してみる

    View Slide

  2. #phpcon2022
    #track4
    BankEnd Software Enginner
    02 大津 和槻
    :@cocoeyes02
    2021/02~ BASE, Inc.
    自己紹介
    PHP系カンファレンス登壇 執筆 登壇応援中!

    View Slide

  3. #phpcon2022
    #track4
    ソースコードを読んでいるときに
    こんなお悩みはありませんか?
    3

    View Slide

  4. #phpcon2022
    #track4
    理解するのに時間がかかる
    具体例が欲しい
    使っているところを想像できない
    4
    ソースコードを読んでいるときに
    こんなお悩みはありませんか?

    View Slide

  5. #phpcon2022
    #track4
    理解するのに時間がかかる
    具体例が欲しい
    使っているところを想像できない
    その問題、テストコードを読むことで
    解決できます!
    5
    ソースコードを読んでいるときに
    こんなお悩みはありませんか?

    View Slide

  6. #phpcon2022
    #track4
    テストコードを読むと何がわかる?
    6
    6

    View Slide

  7. #phpcon2022
    #track4
    テストコードを読むと何がわかる?
    7
    プロダクトコードの大まかな仕様
    7

    View Slide

  8. #phpcon2022
    #track4
    テストコードを読むと何がわかる?
    8
    プロダクトコードの大まかな仕様
    プロダクトコードの使用例
    8


    View Slide

  9. #phpcon2022
    #track4
    テストコードを読むと何がわかる?
    9
    プロダクトコードの大まかな仕様
    プロダクトコードの使用例
    9
    実装する上で用いた観点



    View Slide

  10. #phpcon2022
    #track4
    そこで今回のテーマは!
    10

    View Slide

  11. #phpcon2022
    #track4
    そこで今回のテーマは!
    テストコードのリーディングだけで
    PHPUnitの仕様を理解していきます
    11

    View Slide

  12. #phpcon2022
    #track4
    そこで今回のテーマは!
    PHPUnitのプロダクトコードや
    公式ドキュメントサイトは
    一切見ない縛りで読みます
    12

    View Slide

  13. #phpcon2022
    #track4
    今回のアジェンダ
    13

    テストコードを読む上での
    勘所を解説
    お題を決めてPHPUnitの
    テストコードを読む
    13

    View Slide

  14. テストコードを読む上での
    勘所を解説

    View Slide

  15. #phpcon2022
    #track4
    テストコードを読む上での勘所を解説
    15


    テストコードの構成を把握しよう
    目的によって読むべき
    テストコードを変えよう
    15

    わからないテストは
    実際に動かしてみよう

    View Slide

  16. #phpcon2022
    #track4
    テストコードを読む上での勘所を解説
    16


    テストコードの構成を把握しよう
    目的によって読むべき
    テストコードを変えよう
    16

    わからないテストは
    実際に動かしてみよう

    View Slide

  17. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    17
    どの粒度のテストが実装されているのか把握しましょう。
    ● ユニットテスト
    ● 統合テスト
    ● E2Eテスト
    また、同じユニットテストや統合テストでも、
    何を対象にしたテストなのかも把握しましょう。
    大体ディレクトリ構成やファイル名から読み取ることができます。

    View Slide

  18. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    18

    View Slide

  19. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    19
    E2Eテスト(統合テスト)
    静的解析
    ユニットテスト

    View Slide

  20. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    20
    E2Eテストディレクトリの中身

    View Slide

  21. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    21
    テスト対象の種類

    View Slide

  22. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    22
    Issueに対するリグレッションテスト

    View Slide

  23. #phpcon2022
    #track4
    テストコードの構成を把握しよう
    23
    Issue番号に対応したテスト
    Issue番号に対応したテスト

    View Slide

  24. #phpcon2022
    #track4
    テストコードを読む上での勘所を解説
    24


    テストコードの構成を把握しよう
    目的によって読むべき
    テストコードを変えよう
    24

    わからないテストは
    実際に動かしてみよう

    View Slide

  25. #phpcon2022
    #track4
    目的によって読むべき
    テストコードを変えよう
    25
    正常系のE2Eテストと、異常系のユニットテストでは得られる情報が違う!
    必要なのは範囲の広い仕様理解?クラス・メソッドレベルなど詳細な仕様理解?
    正常系?異常系?
    これを見ればOK!ではなく、目的によって読むテストコードを選ぶ

    View Slide

  26. #phpcon2022
    #track4
    目的によって読むべき
    テストコードを変えよう
    26

    View Slide

  27. #phpcon2022
    #track4
    目的によって読むべき
    テストコードを変えよう
    27
    エラーが起きたときのE2Eテストでは、
    イベントの実行順序を確認している

    View Slide

  28. #phpcon2022
    #track4
    目的によって読むべき
    テストコードを変えよう
    28
    エラーが起きたときのユニットテストでは、
    エラーにまつわる情報が
    期待通り出力されているか確認している

    View Slide

  29. #phpcon2022
    #track4
    テストコードを読む上での勘所を解説
    29
    テストコードの構成を把握しよう
    目的によって読むべき
    テストコードを変えよう
    29
    わからないテストは
    実際に動かしてみよう



    View Slide

  30. #phpcon2022
    #track4
    わからないテストは
    実際に動かしてみよう
    30
    読んでいてわからないものはテストを実行してみましょう。
    何なら勝手に値を変えてみたり、assertionを追加してみるのもオススメです。
    テストコードは動くもので、いろんな具体例を知ることができます。
    大事なのは「理解した!」と自信がつくまで試すこと!

    View Slide

  31. #phpcon2022
    #track4
    わからないテストは
    実際に動かしてみよう
    31

    View Slide

  32. #phpcon2022
    #track4
    わからないテストは
    実際に動かしてみよう
    32
    「完全に理解した」と
    自信がつくまで増やそう!

    View Slide

  33. #phpcon2022
    #track4
    わからないテストは
    実際に動かしてみよう
    33
    テスト駆動開発 26章「レッドバーのパターン」より
    学習用テスト
    まずなじみのないクラスの新しいメソッドを相手にしているのだと、
    しっかり意識する。そして単にそのメソッドを使おうとする代わりに、
    APIが期待通りに動作するのかテストを書いて確かめるのだ。
    (中略)
    もし学習テストが失敗したら、自分たちのコードのテストも動きっこない、
    ということがわかる。その学習用テストが通るようになったら、
    自分達のコードのテストももちろん通る。

    View Slide

  34. お題を決めてPHPUnitの
    テストコードを読む

    View Slide

  35. #phpcon2022
    #track4
    ケーススタディ
    35
    お題:assertObjectEquals メソッドの仕様を理解する
    先にドキュメントを読んでみたい方はこちらからどうぞ!
    https://phpunit.readthedocs.io/ja/latest/assertions.html#assertobjectequals
    今回はassertOjbectEqualsの内部仕様を知りたい
    →ユニットテストを中心に読んでいきます

    View Slide

  36. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    36

    View Slide

  37. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    37
    assertObjectEqualsメソッドに関する正常系のテストケースがありました

    View Slide

  38. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    38
    constructに数値を渡したValueObjectを比較しています

    View Slide

  39. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    39
    同じ数値だったらassertがtrue
    異なる数値だったらAssertionFailedErrorの例外を返す

    View Slide

  40. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    40
    assertObjectEqualsメソッドで比較されている、このValueObjectは何者?

    View Slide

  41. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    41

    View Slide

  42. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    42
    ValueObject
    ● intの値を取り扱う
    ○ 引数は一つだけ
    ● equalsメソッド
    ○ ValueObject型のオブジェクトと同じ
    値であるか比較をしている
    ○ 厳密な比較演算子を用いている
    ● asIntメソッドでvalueを出力できる

    View Slide

  43. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    43
    いろんなint値にしても期待通り動きました(実行結果は割愛します)

    View Slide

  44. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    44
    String型のValueObjectを用意してみました

    View Slide

  45. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    45
    String型のValueObjectの新しいテストケースも、期待通り動きます

    View Slide

  46. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    46
    equalsメソッドを消した状態だとどうなるんだろうか?
    →異常系のテストケースを別ファイルから探す

    View Slide

  47. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    47
    equalsメソッドを消した状態だとどうなるんだろうか?
    →異常系のテストケースを別ファイルから探す

    View Slide

  48. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    48
    オブジェクトにequalsメソッドがないと、
    ComparisonMethodDoesNotExistExceptionが返ってくる(例外が返ってくる)

    View Slide

  49. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    49
    オブジェクトにequalsメソッドがないと、
    ComparisonMethodDoesNotExistExceptionが返ってくる(例外が返ってくる)

    View Slide

  50. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    50
    さらに下のメソッドを見ていくと、
    equalsメソッドの返り値がBoolでない場合も例外が返ってくる

    View Slide

  51. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    51
    さらに下のメソッドを見ていくと、
    equalsメソッドの返り値がBoolでない場合も例外が返ってくる

    View Slide

  52. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    52
    equalsという名前のメソッドじゃなければいけないのか?

    View Slide

  53. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    53
    equalsという名前のメソッドじゃなければいけないのか?
    →残念ながら実装されているテストコードからはわかりませんでした
    ドキュメントには第3引数の存在の説明があり、
    method名を指定(デフォルトはequals)できそうでした

    View Slide

  54. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    54
    リポジトリに実装されている各テストコードで、
    テストケースが網羅されているわけではありません。
    ときにはプロダクトコードを見て自力でテストコードを実装する必要があります。
    ちなみに、それが必要なテストケースなのであれば、
    コントリビュートチャンスなのではないかと思います。
    ぜひテストコードを書いてPRを出してみましょう!

    View Slide

  55. #phpcon2022
    #track4
    assertObjectEqualsメソッドの
    仕様を理解する
    55
    テストコードを読むだけで分かった仕様
    ● オブジェクト内で実装されているequalsメソッドを用いてテストしている
    ● equalsメソッドを実装する際に定義すべきこと
    テストコードだけでは分からなかった仕様
    ● 第3引数でメソッド名を指定すれば、equalsメソッド以外の名前のメソッドを使っ
    て比較ができる
    今回はお試しで「テストコードだけ読む」という縛りで進めましたが、
    テストコードだけ読めば完璧...ではないです。
    プロダクトコードと一緒に読んでいきましょう!

    View Slide

  56. #phpcon2022
    #track4
    最後に
    56
    テストコードを読むことは、プロダクトコードだけ読むよりも確実に仕様を理解できる
    ので、コードリーディングの難易度が下がることが最大のメリットだと考えています。
    コードリーディングに自信がないと思う人ほど、
    テストコードを読んだり動かしてみることをお勧めします!

    View Slide

  57. #phpcon2022
    #track4
    ● phpunit
    https://github.com/sebastianbergmann/phpunit
    https://phpunit.de/
    https://phpunit.readthedocs.io/ja/latest/
    ● テスト駆動開発
    https://www.amazon.co.jp/dp/B077D2L69C
    参考文献

    View Slide

  58. #phpcon2022
    #track4
    最後に
    58
    バックエンド
    エンジニア
    フロントエンド
    エンジニア
    QA
    エンジニア
    SRE
    セキュリティ
    エンジニア
    データ
    エンジニア
    We are hiring!
    https://binc.jp/jobs
    etc…

    View Slide