Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

テストコードの品質を客観的な数値で担保しよう〜Mutation Testのすすめ〜

Kanon
October 04, 2024

テストコードの品質を客観的な数値で担保しよう〜Mutation Testのすすめ〜

Kanon

October 04, 2024
Tweet

More Decks by Kanon

Other Decks in Technology

Transcript

  1. 8 そこで登場するのが Mutation Test Mutation Testとは? • Mutation = (突然)

    変異 ◦ コードを意図的に変更し、バグを植え付ける ◦ ex) a===0 を a !== 0 と変異させる ◦ その後テストを実行し、正しいテストが書かれていなければアサーションが エラーとなるはず ◦ エラーとならなかった箇所がきちんと検証されていないと判断できる • Googleでは2017~18年ごろから全社的に導入されているっぽい 参考:Googleにおける突然変異テストの状況 変異の内容と種類
  2. 9 Mutation Test に関わる指標 Mutation Testとは? • Killed ◦ 変異後、成功すべきテストが失敗したことにより検知された変異の数

    • Survived ◦ 変異後、失敗すべきテストが成功したことにより検知された変異の数 つまり、Survivedの数が多ければ多いほどテストコードの品質が低い
  3. 10 Mutation Test に関わる指標 Mutation Testとは? Mutation Score = Killed

    / Total * 100 この割合が高いほど品質がよい
  4. 20 今回の導入環境など • Nest.js (v10.4.1) ◦ TypeScript (v5.5.4) ◦ node

    (v20.11.0) ◦ Vitest (v2.0.5) ◦ Stryker (v8.5.0) • マシンはMBA M2 16GB • 新規プロジェクトに導入
  5. 24 なぜ遅いのか? • 変異の数はこの式で決まる ◦ 変異発生対象ファイル × 変異の種類 • 全体の実行時間はこの式で決まる

    ◦ 変異の数 × Unitテストケースの実行時間 • Strykerのデフォルト設定 ◦ 全てのファイル × 全変異パターン • よって変異発生対象ファイルと変異の種類を絞って あげればいい 正攻法で実行すると死ぬほど遅い 変異発生対象ファイルを指定 除外する変異発生対象を指定
  6. 26 実行時間で困った時の解法: 差分実行を使う • incremental オプション ◦ incremental: true で設定

    ◦ jsonで前回の結果を保存 ◦ 変異対象のファイルに差分があった箇所のみ新たに(再度)変異を発生させ て実行 正攻法で実行すると死ぬほど遅い
  7. 28 Stryker Dashboardがプライベートリポジトリに使えない 実戦で困ったこと • やろうとしていたこと ◦ GHAでMutation Testを定期実行して、レポートを取得 ▪

    Mutation Scoreがキープできているか? ▪ Mutation Scoreをより高くしていくために、どこを直す必要があるか? • なぜ? ◦ チームメンバーの品質への意識の向上 ◦ 修正を未経験新入社員にやってもらうことでプロダクションに影響のないところでコー ディング経験を積んでもらえる
  8. 29 Google Cloud Storageへ送信 + Slack通知 • Workload Identity連携でGCSへ送信 •

    バケットのURLをSlack通知 • バケットは非公開&権限付与されたアカウントのみ 閲覧可能な設定 • GCSに置いたレポートはライフサイクル管理を設定 することで、一定期間が過ぎたものは削除される Stryker Dashboardがプライベートリポジトリで使えない
  9. 32 Unitテストのカバレッジ • 一般的には65% ~ 80%くらいを目指すのが良いくらいとされるなか、かなり高い数値を キープできている (2024/09/29現在) • Mutation

    Testがあるおかげで、ある程度この数値も信頼できるようになった • 特に無理してテストを書いている感じはない • そもそも全体のStatementsは1805程度なので比較的小さい 導入した結果、どうなったか?