$30 off During Our Annual Pro Sale. View Details »

テストコードリーディングのみで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の仕様を理解してみる

  2. #phpcon2022 #track4 BankEnd Software Enginner 02 大津 和槻 :@cocoeyes02 2021/02~

    BASE, Inc. 自己紹介 PHP系カンファレンス登壇 執筆 登壇応援中!
  3. #phpcon2022 #track4 ソースコードを読んでいるときに こんなお悩みはありませんか? 3

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

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

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

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

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

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

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

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

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

  13. #phpcon2022 #track4 今回のアジェンダ 13 2 テストコードを読む上での 勘所を解説 お題を決めてPHPUnitの テストコードを読む 13

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

  15. #phpcon2022 #track4 テストコードを読む上での勘所を解説 15 1 2 テストコードの構成を把握しよう 目的によって読むべき テストコードを変えよう 15

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

    3 わからないテストは 実際に動かしてみよう
  17. #phpcon2022 #track4 テストコードの構成を把握しよう 17 どの粒度のテストが実装されているのか把握しましょう。 • ユニットテスト • 統合テスト •

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

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

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

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

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

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

  24. #phpcon2022 #track4 テストコードを読む上での勘所を解説 24 1 2 テストコードの構成を把握しよう 目的によって読むべき テストコードを変えよう 24

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

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

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

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

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

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

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

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

  33. #phpcon2022 #track4 わからないテストは 実際に動かしてみよう 33 テスト駆動開発 26章「レッドバーのパターン」より 学習用テスト まずなじみのないクラスの新しいメソッドを相手にしているのだと、 しっかり意識する。そして単にそのメソッドを使おうとする代わりに、

    APIが期待通りに動作するのかテストを書いて確かめるのだ。 (中略) もし学習テストが失敗したら、自分たちのコードのテストも動きっこない、 ということがわかる。その学習用テストが通るようになったら、 自分達のコードのテストももちろん通る。
  34. お題を決めてPHPUnitの テストコードを読む

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

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

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

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

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

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

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

  42. #phpcon2022 #track4 assertObjectEqualsメソッドの 仕様を理解する 42 ValueObject • intの値を取り扱う ◦ 引数は一つだけ

    • equalsメソッド ◦ ValueObject型のオブジェクトと同じ 値であるか比較をしている ◦ 厳密な比較演算子を用いている • asIntメソッドでvalueを出力できる
  43. #phpcon2022 #track4 assertObjectEqualsメソッドの 仕様を理解する 43 いろんなint値にしても期待通り動きました(実行結果は割愛します)

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

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

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

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

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

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

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

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

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

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

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

    ぜひテストコードを書いてPRを出してみましょう!
  55. #phpcon2022 #track4 assertObjectEqualsメソッドの 仕様を理解する 55 テストコードを読むだけで分かった仕様 • オブジェクト内で実装されているequalsメソッドを用いてテストしている • equalsメソッドを実装する際に定義すべきこと

    テストコードだけでは分からなかった仕様 • 第3引数でメソッド名を指定すれば、equalsメソッド以外の名前のメソッドを使っ て比較ができる 今回はお試しで「テストコードだけ読む」という縛りで進めましたが、 テストコードだけ読めば完璧...ではないです。 プロダクトコードと一緒に読んでいきましょう!
  56. #phpcon2022 #track4 最後に 56 テストコードを読むことは、プロダクトコードだけ読むよりも確実に仕様を理解できる ので、コードリーディングの難易度が下がることが最大のメリットだと考えています。 コードリーディングに自信がないと思う人ほど、 テストコードを読んだり動かしてみることをお勧めします!

  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

    参考文献
  58. #phpcon2022 #track4 最後に 58 バックエンド エンジニア フロントエンド エンジニア QA エンジニア

    SRE セキュリティ エンジニア データ エンジニア We are hiring! https://binc.jp/jobs etc…