Slide 1

Slide 1 text

©tete marche CO., LTD. 「うわっ…うちのテスト、遅すぎ…?」 PHPUnit高速化テクニック ぴんくもひかん 資料公開済み 写真撮影・SNS投稿🙆

Slide 2

Slide 2 text

©tete marche CO., LTD. 2 このトークでお話すること PHPUnitでのテストを、テスト戦略や 実行環境などの工夫により高速化する方法 トピックのつまみ食い🙆

Slide 3

Slide 3 text

©tete marche CO., LTD. 3 ✔ テテマーチ株式会社 SINIS for X テックリード 篠田 北斗 ( @pinkumohikan ) ✔ バックエンド寄りの技術が好き ISUCON毎年参戦中🔥 自己紹介

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

©tete marche CO., LTD. Index 目次 6 1. テスト戦略の見直しで速くする 2. テスト実行方法の見直しで速くする 3. テスト環境の見直しで速くする

Slide 7

Slide 7 text

©tete marche CO., LTD. 7 テスト戦略の見直しで速くする テクニック編⏳

Slide 8

Slide 8 text

©tete marche CO., LTD. テスト量のバランス調整 1. 8

Slide 9

Slide 9 text

©tete marche CO., LTD. テストピラミッド 9 Unit Tests >> Service Tests > UI Testsのバランスを目指す 出典: The Practical Test Pyramid - martinfowler.com

Slide 10

Slide 10 text

©tete marche CO., LTD. テストピラミッド 10 考え方 ● 決定性が高く、高速なUTをメインに ● 漏れた部分をST, UITでカバー テストの重複が減り、 信頼性を担保したままテスト時間を短縮 できる 出典: The Practical Test Pyramid - martinfowler.com

Slide 11

Slide 11 text

©tete marche CO., LTD. 11 Google提唱のテスト分類法 テストを - Small (Unit Test相当) - Medium (Service Test相当) - Large (UI Test相当) の3種類に分類 Test Sizes 出典: Test Sizes - Google Testing Blog

Slide 12

Slide 12 text

©tete marche CO., LTD. 12 ● テストピラミッド ○ UTをメインで書き、漏れた部分をST,UITでカバー ○ 信頼性を担保したままテスト時間を短縮できる ● Test Sizes ○ 「どこまでがユニットテスト?」って揉めたらS/M/Lって表現する手もある ○ ちゃんと従っていれば、Smallテストは並列実行しやすいメリットも テスト量のバランス調整: まとめ

Slide 13

Slide 13 text

©tete marche CO., LTD. 外部API呼び出しのモック 2. 13

Slide 14

Slide 14 text

©tete marche CO., LTD. 外部API呼び出しのモック 外部API (外部のWeb API) の呼び出しをモックすることで高速化 14 決済 サービス 決済テスト 外部決済 サービス

Slide 15

Slide 15 text

©tete marche CO., LTD. 外部API呼び出しのモック 外部API (外部のWeb API) の呼び出しをモックすることで高速化 15 決済 サービス 決済テスト 外部決済 サービス ⚠ 遅延や失敗リスク

Slide 16

Slide 16 text

©tete marche CO., LTD. 外部API呼び出しのモック 外部API (外部のWeb API) の呼び出しをモックすることで高速化 16 決済 サービス 決済テスト ⚠ 遅延や失敗リスク 外部決済 サービス

Slide 17

Slide 17 text

©tete marche CO., LTD. 外部API呼び出しのモック 外部API (外部のWeb API) の呼び出しをモックすることで高速化 17 決済 サービス 決済テスト 外部決済 サービス 決済API モック

Slide 18

Slide 18 text

©tete marche CO., LTD. 環境によってテスト範囲を変える 3. 18

Slide 19

Slide 19 text

©tete marche CO., LTD. この世の真理に気づいてしまった 19 すべての環境で すべてのテストを実行しなければならない わけでは無い

Slide 20

Slide 20 text

©tete marche CO., LTD. 20 ローカルとCIでテスト対象範囲を変える 出典: The Practical Test Pyramid - martinfowler.com

Slide 21

Slide 21 text

©tete marche CO., LTD. 21 テストピラミッドに従っていればUTのみでも大部分の不具合を検出できる ローカルとCIでテスト対象範囲を変える 出典: The Practical Test Pyramid - martinfowler.com

Slide 22

Slide 22 text

©tete marche CO., LTD. 関係のないテストを実行しない 4. 22

Slide 23

Slide 23 text

©tete marche CO., LTD. 差分テスト そのPRの diffに関連するクラスだけ をテスト対象にすることで高速化 23

Slide 24

Slide 24 text

©tete marche CO., LTD. 差分テスト 24 なぜテストするのか?

Slide 25

Slide 25 text

©tete marche CO., LTD. 差分テスト 25 A: デグレ (不具合) を 防ぎたいから

Slide 26

Slide 26 text

©tete marche CO., LTD. 差分テスト 26 なぜデグレが起きるのか?

Slide 27

Slide 27 text

©tete marche CO., LTD. 差分テスト 27 A: 変更を加えたから

Slide 28

Slide 28 text

©tete marche CO., LTD. 差分テスト そのPRの diffに関連するクラスだけ をテスト対象にすることで高速化 変更しなければデグレするはずがない → テストする必要がない 28

Slide 29

Slide 29 text

©tete marche CO., LTD. 差分テスト そのPRの diffに関連するクラスだけ をテスト対象にすることで高速化 変更しなければデグレするはずがない → テストする必要がない 29

Slide 30

Slide 30 text

©tete marche CO., LTD. 差分テスト 関連するクラスを見つけることが肝であり鬼門👹 いい方法知っていたら教えて欲しい こんな感じで出来るのでは説 1⃣ 変更されたクラスをリストアップ - git diff --name-only 2⃣ 変更クラスへの依存クラスを再帰的にリストアップ - nikic/PHP-Parser等を使い、AST (抽象構文木) から 3⃣ 各クラスの名前に Test suffixをつけてテストファイルをgrep 4⃣ ↑で見つかったテストファイルをPHPUnitで実行 30

Slide 31

Slide 31 text

©tete marche CO., LTD. 31 テスト実行方法の見直しで速くする テクニック編⏳

Slide 32

Slide 32 text

©tete marche CO., LTD. テストの並列実行でリソース効率を上げる 5. 32

Slide 33

Slide 33 text

©tete marche CO., LTD. テスト実行の並列化 33 PHPUnitを普通に実行するとシングルスレッドで動く 最近のPCやCI環境は当たり前にマルチコアなので、CPUを有効活用したい 🧠🧠 🧠🧠 🧠🧠 🧠🧠

Slide 34

Slide 34 text

©tete marche CO., LTD. テストの並列化 (ParaTest) 34 ParaTest ● PHPUnitテストを複数プロセスで並列実行できるツール ● 並列度を上げるとDB I/O部分でデッドロックしやすい☠ (Smallと相性◎)

Slide 35

Slide 35 text

©tete marche CO., LTD. テストの並列化 (ParaTest) 35

Slide 36

Slide 36 text

©tete marche CO., LTD. テストの並列化 (ParaTest) 36

Slide 37

Slide 37 text

©tete marche CO., LTD. テストの並列化 (Makefile) 37 Makefile ● 伝統的なタスクランナー ● `make -j` で並列実行できる ● ParaTestが使えない場合や一部だけ並列化したい場合などに便利

Slide 38

Slide 38 text

©tete marche CO., LTD. テストの並列化 (Makefile) 38

Slide 39

Slide 39 text

©tete marche CO., LTD. テストの並列化 (Makefile) 39

Slide 40

Slide 40 text

©tete marche CO., LTD. テストの並列化 (Makefile) 40

Slide 41

Slide 41 text

©tete marche CO., LTD. 41 テスト環境の見直しで速くする テクニック編⏳

Slide 42

Slide 42 text

©tete marche CO., LTD. テスト実行の水平分割 6. 42

Slide 43

Slide 43 text

©tete marche CO., LTD. CIでのテスト実行を水平分割 (マルチジョブ化) テストを複数のジョブに分割して実行することで待ち時間を減らす 43 30分


Slide 44

Slide 44 text

©tete marche CO., LTD. CIでのテスト実行を水平分割 (マルチジョブ化) テストを複数のジョブに分割して実行することで待ち時間を減らす 44 30分
 6分


Slide 45

Slide 45 text

©tete marche CO., LTD. XDebug無効化 7. 45

Slide 46

Slide 46 text

©tete marche CO., LTD. XDebug無効化 PHPで定番のプロファイラー これが有効な状態でPHPUnitを実行すると、かなりオーバーヘッドが乗る😢 使ってないなら無効化しましょう ⚠ XDebugはカバレッジ計測に使われていることがあるのには注意 46

Slide 47

Slide 47 text

©tete marche CO., LTD. XDebug無効化 実施例 47

Slide 48

Slide 48 text

©tete marche CO., LTD. XDebug無効化 ⚠ GitHub ActionsのUbuntuでは標準でXDebugが有効 PHPer御用達 shivammathur/setup-php ActionのREADMEにも、 使ってないなら高速化のために停めたほうが良い旨の記載がある 48 出典: shivammathur/setup-php

Slide 49

Slide 49 text

©tete marche CO., LTD. OPcacheの有効化 8. 49

Slide 50

Slide 50 text

©tete marche CO., LTD. OPCache有効化 50 出典: 問題解決に必要な能力 〜CodeBuildとOPCacheに振り回された話〜

Slide 51

Slide 51 text

©tete marche CO., LTD. OPCache有効化 OPCacheはテスト実行時にも効く ⚠ 開発環境で有効にすると「変更したのに反映されない...!?」が起きがち ⚠ PHPUnitはCLIで実行されるので opcache.enable_cli も必要 51

Slide 52

Slide 52 text

©tete marche CO., LTD. OPCache有効化 実施例 52

Slide 53

Slide 53 text

©tete marche CO., LTD. 細かいテクニック 9. 53

Slide 54

Slide 54 text

©tete marche CO., LTD. テスト失敗時、即終了させる CIでは すべてのテストが通るか否か が重要 それなら、1つでもテストが失敗したらテストを続ける必要がない そこでPHPUnit stop-on-failure オプション 54 出典: PHPUnit 10.5 Configuration

Slide 55

Slide 55 text

©tete marche CO., LTD. GHAのキャッシュウォームアップ GitHub Actionsのキャッシュの注意点 ● 別ブランチのキャッシュは参照できない ○ デフォルトブランチは例外 ● 7日間未アクセスで自動削除 このせいで意図せずcache missしていることが案外多い😭 対策: Workflowをmain向けて週次実行して、キャッシュを作っておく 55

Slide 56

Slide 56 text

©tete marche CO., LTD. 最後に 56

Slide 57

Slide 57 text

©tete marche CO., LTD. 57 テストは速ければ 速いほど良い 最後に

Slide 58

Slide 58 text

©tete marche CO., LTD. 58 暇があったらテストの時短 最後に

Slide 59

Slide 59 text

©tete marche CO., LTD. 59 暇がなかったらPdMにウインク 最後に

Slide 60

Slide 60 text

©tete marche CO., LTD. 60 テストを高速化して アジリティ上げて行きましょう! 最後に

Slide 61

Slide 61 text

©tete marche CO., LTD. 61 ● Googleのソフトウェアエンジニアリング ○ 書籍, O’Reilly Japan, 初版第一刷. ● Test Sizes - Google Testing Blog ○ https://testing.googleblog.com/2010/12/test-sizes.html, Google, 2025/3/16 最終閲覧. ● The Practical Test Pyramid ○ https://martinfowler.com/articles/practical-test-pyramid.html, martinfowler.com, 2025/03/22 最終閲覧. ● GitHub Actions でテストを並列化して CI 時間を短縮する ○ https://tech.gunosy.io/entry/actions_parallel, グノシー, 2025/03/22 最終閲覧. ● 問題解決に必要な能力 〜CodeBuildとOPCacheに振り回された話〜 ○ https://speakerdeck.com/matsukaz/ability-to-solve-problems, matsukaz, 2025/03/22 最終閲覧. 参考文献

Slide 62

Slide 62 text

We are hiring!