Slide 1

Slide 1 text

©tete marche CO., LTD. 「うわっ…うちのテスト、遅すぎ…?」 PHPUnit高速化テクニック PHPerKaigi 2025 ぴんくもひかん 写真撮影・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

©tete marche CO., LTD. 4 ✔ テテマーチ株式会社 SINIS for X テックリード 篠田 北斗 ( @pinkumohikan ) ✔ 社内ブランディング 「定期的に髪色が変わるやべーやつ」   「いつもAIAI言ってる感じ悪いやつ」 ✔ バックエンド寄りの技術が好き ISUCON毎年参戦中🔥 自己紹介

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

©tete marche CO., LTD. 差分テスト そのPRの diffに関連するクラスだけ をテスト対象にすることで高速化 変更しなければデグレするはずがない → テストする必要がない 25 TODO: 車輪モデルにしか変更がな いならヘッドライトモデルのテストを する必要がないよね、みたいな分かり やすい素敵な図を用意する

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

©tete marche CO., LTD. テストの並列化 (Makefile) 37 めちゃくちゃ便利 じゃないです か!?!?

Slide 38

Slide 38 text

©tete marche CO., LTD. テストの並列化 (Makefile) 38 便利ですよね!!

Slide 39

Slide 39 text

©tete marche CO., LTD. テストの並列化 (Makefile) 39 使っていきましょ う!!!!!!!!! (Makefile狂信者)

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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


Slide 43

Slide 43 text

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


Slide 44

Slide 44 text

©tete marche CO., LTD. XDebug無効化 6. 44

Slide 45

Slide 45 text

©tete marche CO., LTD. XDebug無効化 XDebug … PHPで定番のプロファイラー 有効な状態でPHPUnitを実行するとかなりオーバーヘッドが乗る😢 使ってないなら無効化しよう 45

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

©tete marche CO., LTD. OPcacheの有効化 7. 48

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

©tete marche CO., LTD. 失敗するなら、速いほうが良い 8. 52

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

©tete marche CO., LTD. まとめ 54

Slide 55

Slide 55 text

©tete marche CO., LTD. 55 テストは速ければ 速いほど良い まとめ

Slide 56

Slide 56 text

©tete marche CO., LTD. 56 暇があったらテストの時短 まとめ

Slide 57

Slide 57 text

©tete marche CO., LTD. 57 暇がなかったらPdMにウインク まとめ

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

©tete marche CO., LTD. 59 ● Test Sizes - Google Testing Blog ○ https://testing.googleblog.com/2010/12/test-sizes.html, Google, 2025/3/16最終閲覧. ● Googleのソフトウェアエンジニアリング ○ O’Reilly Japan, 初版第一刷. ● 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 60

Slide 60 text

We are hiring!

Slide 61

Slide 61 text

©tete marche CO., LTD. Q&A 61

Slide 62

Slide 62 text

©tete marche CO., LTD. Q&A ParaTestデッドロックしがち ● テスト時にデッドロックする = 本番でもデッドロックしうるってこと ● デッドロックの原因を突き止めて治すのが根本対応 ○ MySQLのデッドロックログからどのクエリが競合しているか特定して、 それを読み書きしているテストを見つけて、読み書きの方向を揃える・明 示的にロックを取る・TXスコープ見直す・etc… ● テストプロセス毎にデータベースを作る方法もある ○ Laravel migrationを使っている場合はこれがやりやすい 62

Slide 63

Slide 63 text

©tete marche CO., LTD. Q&A どれからやっていくと良い? ● できることからやり、テンションを上げる ○ XDebug無効化、OPCache有効化は割とすぐできる ○ テストバランスの見直しは時間がかかる、並列化はデッドロックで詰ま りがち ● テスト実行のどの部分で時間がかかっているかを、CIのステップごとのサ マリーから特定してそこに効くやつをやる 63