Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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