Slide 1

Slide 1 text

© RAKUS Co., Ltd. ユニットテスト環境整備 〜みんながテストを書ける環境へ〜 PHP Conference Japan 2023 株式会社ラクス  堀川慶太 2023/10/08

Slide 2

Slide 2 text

⾃⼰紹介 ● 2021年4⽉ 株式会社ラクス⼊社 ● 業務内容 ○ ~2023/08 開発チーム:新規機能開発‧バグ修正など ○ 2023/09~ 改善チーム:負債解消 2

Slide 3

Slide 3 text

プロダクトについて ● PHP + PostgreSQL ○ PHP:8.2 ● 販売管理システム ● サービス開始から15年(2008~) 3 8.0のEOLは11/23! https://www.php.net/supported-versions.php

Slide 4

Slide 4 text

© RAKUS Co., Ltd. 4 ユニットテスト書いてますか? PHP Conference Japan 2023

Slide 5

Slide 5 text

1. テスト駆動開発 2. 開発時はテストがセット 3. 重要機能だけ 4. 書かない(書けない) 5

Slide 6

Slide 6 text

1. テスト駆動開発 2. 開発時はテストがセット 3. 重要機能だけ 4. 書かない(書けない) ⇒ 3と4が混ざっているような状態 6

Slide 7

Slide 7 text

環境整備前の状態 機能開発を優先 ● ⻑年の負債が積もり開発速度の低下と品質の低下が⾒られる ● 改善の時間が取れない 7

Slide 8

Slide 8 text

環境整備前の状態 8 テストが無いので デグレが怖い リファクタしたい 修正箇所のコードが 汚い リファクタせずに コードを修正する 内部品質悪化の悪循環 時間もかかるし、 バグも出やすい

Slide 9

Slide 9 text

環境整備前の状態 ● ライブラリはある ○ Codeceptionを2018年に導⼊ ■ 結合テスト‧E2Eテストもカバー ■ DBに依存したテストが書きやすい(専⽤のassertが⽤意されている等) ● テストコードが⼀部存在 ○ 有識者がコア機能の開発を⾏った際に⾃発的に作成する程度 ○ 残りはライブラリ導⼊時付近で導⼊者が既存機能のテストを書いたもの ● 毎朝1回開発メインブランチに対して定期実⾏される(cron) 9

Slide 10

Slide 10 text

© RAKUS Co., Ltd. 10 なぜユニットテスト環境を整備するか PHP Conference Japan 2023

Slide 11

Slide 11 text

チームが改善したいこと ● ⼿動テスト⼯数の削減 ○ 設定の組み合わせパターンがあまりに多く、⼿動テストが⾟い ● ユニットテストを取り巻く環境の改善 ○ ユニットテストのライブラリがあるのにテストが追加されない ○ テストを書かない⽅が速い 11

Slide 12

Slide 12 text

チームが改善したいこと ● プロダクトの負債解消‧内部品質向上 ○ テストがほぼ無い‧書けないのでコードリファクタが難しい ○ アプリコードがユニットテストを書ける状態では無い ● デグレ防⽌ ○ 通常開発のデグレ ○ PHPバージョンアップ関連でのデグレ 12

Slide 13

Slide 13 text

© RAKUS Co., Ltd. 13 要するに PHP Conference Japan 2023

Slide 14

Slide 14 text

開発がスピードアップ出来ない 14 開発にかかる時間が年々増える(実装×テスト) ↓ リリースしてもバグが出て、修正時間が取られる ↓ プロダクトは伸び盛りなのに開発が追いついてこない ⇒ この状況を打開し、プロダクトを更に成⻑させていきたい!

Slide 15

Slide 15 text

© RAKUS Co., Ltd. 15 ⼀般的には... PHP Conference Japan 2023

Slide 16

Slide 16 text

なぜ単体テストを⾏うのか コードベースは成⻑と共に劣化する 時間が経つにつれ、開発スピードは加速度的に落ちていく 16 テストはソフトウェア開発におけるセーフティ‧ネット 単体テストの考え⽅/使い⽅:https://book.mynavi.jp/ec/products/detail/id=134252 ソフトウェア開発プロジェクトの成⻑を持続可能なものにする コードの変更によって⽣じる多くの退⾏(regression)を検出する テストを書く‧メンテすることにはコストが⽣じる

Slide 17

Slide 17 text

© RAKUS Co., Ltd. 17 実施したこと PHP Conference Japan 2023

Slide 18

Slide 18 text

1. ライブラリ移⾏ 2. CI活⽤ 3. 記述⽅針の整備 18

Slide 19

Slide 19 text

© RAKUS Co., Ltd. 19 ライブラリ移⾏ PHP Conference Japan 2023

Slide 20

Slide 20 text

ライブラリ移⾏(Codeception → PHPUnit) ● 多くの機能が有る故に設定や環境構築が複雑化 ● ネットで調べても情報が⾒つけづらい‧無い ● 今後更新が続けられていくのか不安感 ● カバレッジがうまく取得できなかった 20 Codeception

Slide 21

Slide 21 text

ライブラリ移⾏(Codeception → PHPUnit) ● PHPにおけるユニットテストライブラリのデファクトスタンダード ● PHPバージョンアップへの追随が早い ● 社内でのPHPUnit導⼊実績あり ● ネット検索時の情報量の多さ 21 PHPUnit

Slide 22

Slide 22 text

ライブラリ移⾏(codeception → PHPUnit) ● バージョンは9.6 ● phpunit.xmlやブートストラップファイルを作成して実⾏の準備 ● 既存テストコードが動作するよう修正 ● カバレッジ取得◎ 22 移⾏

Slide 23

Slide 23 text

ライブラリ移⾏(codeception → PHPUnit) ● 既存テストコードの⾒直し ● 汎⽤サポートクラスの作成 ○ DB接続 ○ データファイル読込 ● 資料作成と周知 ○ 周知をどんどんしてチームを巻き込むのが⼤切 23 今後のために

Slide 24

Slide 24 text

© RAKUS Co., Ltd. 24 CIでのユニットテスト活⽤ PHP Conference Japan 2023

Slide 25

Slide 25 text

CI運⽤ ● 1⽇1回のみ実⾏されるのでテストの失敗に気づくのは翌⽇ ● 開発メインブランチにマージするまで失敗に気づかない ● テストを書いた実感が得づらい 25 今まで:開発メインブランチに対する定期実⾏

Slide 26

Slide 26 text

CI運⽤ ● PUSHが⾏われるとCIパイプラインで全てのユニットテストが実⾏される ● デグレの発⽣や新規作成したテスト‧実装のミスにすぐ気付ける ● ユニットテストが失敗したままマージは出来ない 26 環境整備後:PUSH時に実⾏されるように

Slide 27

Slide 27 text

CI実⾏イメージ 環境作成 実⾏ 27 OS,DB等の必要イメージを⽤意 アプリリポジトリをgit clone テストデータの⼊ったDBをリストア composer install phpunit {ディレクトリ名} ‒log-junit {ファイル名}

Slide 28

Slide 28 text

CI運⽤ ● 全体カバレッジ ○ テストコードの積み重ねが⽬に⾒える ○ 共有することでモチベーションの向上も ● Diffにカバレッジ表⽰ ○ ⾏単位でのケース漏れがわかる ○ 視覚的にテストを書いた実感が出る 28 2種類のカバレッジ取得

Slide 29

Slide 29 text

CI運⽤ ● 全体カバレッジ ○ アプリのメインディレクトリ全体に対して実⾏ ○ CIコンソールで出⼒されたカバレッジの値を取得する ○ 時間がかかる 29 カバレッジ

Slide 30

Slide 30 text

30 CIコンソール上 マージリクエスト上

Slide 31

Slide 31 text

CI運⽤ ● Diffにカバレッジ表⽰ ○ phpunit {ディレクトリ名} ‒coverage-cobertura={ファイル名} ○ 差分を対象に実⾏ ○ 全体に実⾏するより時間が短い ※ cobertura   フリーのJavaコードカバレッジレポートツール   PHP Unitでは9.4から直接cobertura形式でレポートを出⼒できるようになった   https://github.com/sebastianbergmann/php-code-coverage/pull/812 31 カバレッジ

Slide 32

Slide 32 text

32

Slide 33

Slide 33 text

33 掛け算の テストケースが ない!

Slide 34

Slide 34 text

© RAKUS Co., Ltd. 34 記述⽅針の整備 PHP Conference Japan 2023

Slide 35

Slide 35 text

ユニットテスト記述⽅針の整備 ● チームとしてテストを書きながら開発する最初の⼀歩を踏み出す ○ テストを書く‧書かないの判断を明確にして開発時の悩みを軽減させる ○ テストコードを書く場合のサンプルを提供する 35 作成理由

Slide 36

Slide 36 text

ユニットテスト記述⽅針の整備 ● テストの過剰作成と作成されないことを予防する ○ どういったパターンはテストを書き、どういったパターンは諦めるか決まってない 何から何までテストを書くと開発⼯数が爆発し、機能開発のペースが悪化する ○ 過去のテストが書かれない経験を踏まえ、最低限のテストが書かれるルールを作成する 36 作成理由

Slide 37

Slide 37 text

ユニットテスト記述⽅針の整備 ● 前段:なぜユニットテストを書くのか ● MUSTでテストを書くクラス種別とそのテストコード例 ● テストを書くためのアプリコード修正例 ● テストコード⽤のコーディング規約 ○ クラス名‧メソッド名等 ○ どの単位でテストクラスを定義するか 37 内容

Slide 38

Slide 38 text

© RAKUS Co., Ltd. 38 結果 PHP Conference Japan 2023

Slide 39

Slide 39 text

良かったこと ● 今は開発で触った箇所のテストを書いている段階 ● 総数は増えているのにカバレッジは着実に増加! 39 カバレッジが向上 半年 5年 0.47% (1196/255956) 1.04% (2712/260105)

Slide 40

Slide 40 text

良かったこと ● ユニットテスト作成を事前考慮して開発するようになった ● 想像以上の成果 ○ ユニットテストを書きたいというモチベーションはあった ○ 今は環境が背中を押してくれる ○ チェック者を⽴てて直近の修正コードでテストを書ける箇所が無いか確認している 40 テストが書かれるように

Slide 41

Slide 41 text

良かったこと ● リリース前に不具合を検知した💡 ○ デグレ検知 ○ 例:PHP8.1バージョンアップの静的変数挙動変更 ● ⼿動テストが⼀部軽減 ○ パターン網羅系のテストを⼀部だが任せられるように ○ ⼿動テストと違い再実⾏が簡単にできる 41 テストが効果を発揮

Slide 42

Slide 42 text

良かったこと ● テストを書くことでセルフチェックが出来る ○ 現在はテスト駆動開発では無い(実装 → ユニットテスト作成) ○ ケースを作成するために設計やコードを⾒直す ○ 実装漏れや可読性の低さに気付ける 42 アプリコードにも改善の兆し

Slide 43

Slide 43 text

良かったこと ● コードを綺麗にしようという意識の向上 ○ 責務の分割やメソッドの切り⽅が綺麗に ○ 設計やテストコードの書き⽅についての議論が⾏われるように ○ ユニットテスト以外にも要因はあるが、チームとして改善の意識が⾼くいい感じ 43 アプリコードにも改善の兆し

Slide 44

Slide 44 text

悪かったこと ● ライブラリ移⾏に予想以上の⼯数がかかった ○ 4〜5⼈⽇ ● CIの実⾏が遅い ○ 現時点で約5分 ○ 理由はDB関連と⼀部javaをキックするテストがある点等々 ○ カバレッジの取得も遅い ● テストの質 ○ まずテストを書くことに重点を置いたので、改善の余地あり 44

Slide 45

Slide 45 text

© RAKUS Co., Ltd. 45 今後について PHP Conference Japan 2023

Slide 46

Slide 46 text

やりたいこと ● PHPUnitのバージョンを10に上げる 上げました! ● 既存重要機能のテスト拡充 ● ユニットテスト記述⽅針の更新 ● CIでの実⾏速度改善 ● モックライブラリ‧DIコンテナ ● ユニットテスト関連の勉強会‧読書会 ● テストの⾒直し 46

Slide 47

Slide 47 text

© RAKUS Co., Ltd. 47 まとめ PHP Conference Japan 2023

Slide 48

Slide 48 text

まとめ ● ライブラリ移⾏ ○ 技術的な側⾯からテストコードが書きやすく、実⾏しやすく ● CI活⽤ ○ テストのフィードバックに即時性を ○ カバレッジの表⽰で積み重ねを⽬に⾒えるように ● 記述⽅針整備 ○ ⼈為的な側⾯からテストコードを書きやすく 48 様々な負債解消の第⼀歩に

Slide 49

Slide 49 text

© RAKUS Co., Ltd. 49 最後に PHP Conference Japan 2023

Slide 50

Slide 50 text

最後に ● ⼀歩⽬のハードルは可能な限り下げる ○ テストを書く際の悩みをできるだけ減らす ○ 書くことが負担にならないようにする ● 開発フローに混ぜ込む ○ テストを書くのが当然という状態に仕組みから持っていくのが理想 ⇒ ライブラリの移⾏‧記述⽅針の整備で実現 50 テストを書きながら開発する環境は作れる

Slide 51

Slide 51 text

最後に ● テストを書いている意味‧実感を感じられるようにする ○ カバレッジや結果がGUIで⾒ることができる ○ テスト結果が即時に返ってくる ⇒ CIにユニットテストを載せることで実現 51 テストを書きながら開発する環境は作れる

Slide 52

Slide 52 text

本当に最後に ● 1⼈ではできないことも⼒を借りればできる ○ 常に助けていただきながら実施しました ○ メンバーも声をかければ助けてくれます(きっと) ● 諦めない ○ 15年経ったプロダクトにもユニットテストの⽂化は⼊れられます ● 改善しよう ○ あなたが⾟いと感じる開発環境はみんな⾟いと感じているはずです ○ 環境を整える体験はきっといい経験になるはずです 52 ⾃分たちが開発する環境を⾃分たちで綺麗に

Slide 53

Slide 53 text

© RAKUS Co., Ltd. 53 ご清聴ありがとうございました。 PHP Conference Japan 2023