Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
テストコード品質を高めるためにMutation Testingライブラリ・Strykerを実戦...
Search
Kanon
November 15, 2024
Technology
8
3.6k
テストコード品質を高めるためにMutation Testingライブラリ・Strykerを実戦導入してみた話
TSKaigi Kansai 2024 での登壇資料です。
https://kansai.tskaigi.org/talks/ysknsid25
Kanon
November 15, 2024
Tweet
Share
More Decks by Kanon
See All by Kanon
統計データで2024年の クラウド・インフラ動向を眺める
ysknsid25
2
1.1k
GAS × Discord bot × Gemini で作ったさいきょーの情報収集ツール
ysknsid25
1
1.5k
そうだ、神戸へ行こう
ysknsid25
2
17k
テストコードの品質を客観的な数値で担保しよう〜Mutation Testのすすめ〜
ysknsid25
12
5.2k
「ばん・さく・つき・たー!」にならないためにSHIROBAKOから 学んだこと
ysknsid25
4
1.4k
東遊園地近辺のおすすめランチ・カフェ
ysknsid25
4
18k
Other Decks in Technology
See All in Technology
Gateway H2 モジュールで スマートホーム入門
minoruinachi
0
120
Simplify! 10 ways to reduce complexity in software development
ufried
1
180
DjangoCon Europe 2025 Keynote - Django for Data Science
wsvincent
0
370
OpenLane-V2ベンチマークと代表的な手法
kzykmyzw
0
150
10分で学ぶ、RAGの仕組みと実践
supermarimobros
0
690
Oracle Cloud Infrastructure:2025年4月度サービス・アップデート
oracle4engineer
PRO
0
320
テストって楽しい!開発を加速させるテストの魅力 / Testing is Fun! The Fascinating of Testing to Accelerate Development
aiandrox
0
160
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
5.4k
Новые мапы в Go. Вова Марунин, Clatch, МТС
lamodatech
0
1.5k
Microsoft の SSE の現在地
skmkzyk
0
270
Dynamic Reteaming And Self Organization
miholovesq
3
730
Cross Data Platforms Meetup LT 20250422
tarotaro0129
1
920
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
56
9.3k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
780
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Code Review Best Practice
trishagee
67
18k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
23
2.7k
Rebuilding a faster, lazier Slack
samanthasiow
81
9k
Mobile First: as difficult as doing things right
swwweet
223
9.6k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Writing Fast Ruby
sferik
628
61k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
119
51k
Raft: Consensus for Rubyists
vanstee
137
6.9k
It's Worth the Effort
3n
184
28k
Transcript
Kanon (@ysknsid25) #TSKaigiKansai テストコード品質を高めるために Mutationライブラリ・ Strykerを 実践導入してみた
README @ysknsid25 水瀬いのりさん が推し 表紙のアイコンは公式配布のものです。 https://x.com/tonikakuhayate/status/1806583319951233034?s=46&t=zwt7nxAvhST7_30NZnyMTQ @yskn_sid25 今日は神戸からきました
この発表のゴール 3 • Mutation Testについて知っていただく • 導入に必要な手順を知っていただく • 導入してみて困ったこととその解決法を知っていただく •
「Mutation Testを試しにやってみようかな」と思ってい ただく
4 Mutation Testとは?
コードに意図的なバグを植え付けることで、 テストコードの検証が適切に行われているか? を測定する手法 5
6 自分が自動テストに対してずっと思ってたこと テストコードがほんまに正しく書けてるか分からんのに、 テストコードを書いて「カバレッジx%やからヨシ!」 でほんまに品質って担保できてるんか?
7 カバレッジレポートの罠 • 通常のカバレッジメトリクスは嘘をつく • 例えば以下の(極端なテストケース)など コードサンプル javascript-testing-best-practice
8 そこで登場するのが Mutation Test • Mutation = (突然) 変異 ◦
コードを意図的に変更し、バグを植え付ける ◦ ex) a===0 を a !== 0 と変異させる ◦ その後テストを実行し、正しいテストが書かれていなければアサーションが エラーとなるはず ◦ エラーとならなかった箇所がきちんと検証されていないと判断できる • Googleでは2017~18年ごろから全社的に導入されているっぽい 参考:Googleにおける突然変異テストの状況 変異の内容と種類
9 Mutation Test に関わる指標 • Killed ◦ 変異後、成功すべきテストが失敗したことにより検知された変異の数 • Survived
◦ 変異後、失敗すべきテストが成功したことにより検知された変異の数 つまり、Survivedの数が多ければ多いほどテストコードの品質が低い
10 Mutation Test に関わる指標 Mutation Score = Killed / Total
* 100 この割合が高いほど品質がよい
11 百聞は一見に如かず
12 Stryker を使っていろいろと見てみます • Mutation ライブラリ • 変異を自動で作ったり、レポート作ったり • 対応言語
◦ JS ◦ C# ◦ Scala Playground (C#) があるのでそれを使ってみる
13 余談: TypeScript でも Strykerは変異を起こしてくれる レポートを見た感じ TSに対して変異を作っている 設定は特にしてない
14 余談: tsxでもOK
15 Mutation Reportを見てみる
16 “失敗すべきテストが成功するとは?” これを覚えておい てください これを覚えておい てください
17 “失敗すべきテストが成功するとは?”
18 “失敗すべきテストが成功するとは?” 変異前も前後も 結果は100 =変異してるのに テストは成功する この場合は 引数が適切でない
19 適切なテストにするには? テストパラメータを 修正し、再実行
20 LGTM👍 スコアアップ 🎉 Survivedだった 変異が消えた
21 導入してみる
22 今回の導入環境など • Next.js (v14.2.4) ◦ TypeScript (v5.2.2) ◦ React
(v18.2.0) ◦ Vitest (v2.0.5) ◦ Stryker (v8.5.0) • 既存のプロジェクト
23 今回の導入環境など • Nest.js (v10.4.1) ◦ TypeScript (v5.5.4) ◦ node
(v20.11.0) ◦ Vitest (v2.0.5) ◦ Stryker (v8.5.0) • 新規プロジェクトに導入
24 導入方法 • 導入自体は超簡単 ◦ npm i -g stryker-cli ◦
npm i --save-dev @stryker-mutator/vitest-runner ◦ npx stryker run • stryker.config.jsonという設定ファイルができる • このファイルに対していろいろ書いていく
25 詳しい記事
26 実際に導入して困ったこと
27 実戦で困ったこと • 正攻法で実行すると死ぬほど遅い • Stryker Dashboardがプライベートリポジトリだと使えない
28 正攻法で実行すると死ぬほど遅い CIに入れられるわけない Unit テストは 2,30秒くらいで終わっ てる
29 なぜ遅いのか? • 変異の数はこの式で決まる ◦ 変異発生対象ファイル × 変異の種類 • 全体の実行時間はこの式で決まる
◦ 変異の数 × Unitテストケースの実行時間 • Strykerのデフォルト設定 ◦ 全てのファイル × 全変異パターン • よって変異発生対象ファイルと変異の種類を絞っ てあげればいい 変異発生対象ファイルを指定 除外する変異発生対象を指定
30 変異対象のファイル絞ったったらええやん!
31 これで勝つる
32 そう簡単に改善サセネーヨ ★ CIに (ry
33 実行時間で困った時の解法: 差分実行を使う • incremental オプション ◦ incremental: true で設定
◦ jsonで前回の結果を保存 ◦ 変異対象のファイルに差分があった箇所のみ新たに(再度)変異を発生させ て実行
34 LGTM👍 ただ、変更箇所が多いと 実行時間は比例する が、PRを小さくするという意識を チームに植え付けられたので 結果オーライ
35 Stryker Dashboardがプライベートリポジトリに使えない • やろうとしていたこと ◦ GHAでMutation Testを定期実行して、レポートを取得 ▪ Mutation
Scoreがキープできているか? ▪ Mutation Scoreをより高くしていくために、どこを直す必要があるか? • なぜ? ◦ チームメンバーの品質への意識の向上 ◦ 修正を未経験新入社員にやってもらうことでプロダクションに影響のないところでコー ディング経験を積んでもらえる
36 Google Cloud Storageへ送信 + Slack通知 • Workload Identity連携でGCSへ送信 •
バケットのURLをSlack通知 • バケットは非公開&権限付与されたアカウントのみ 閲覧可能な設定 • GCSに置いたレポートはライフサイクル管理を設定 することで、一定期間が過ぎたものは削除される
37 LGTM👍 推しに通知してもらえて wktk
38 導入した結果、どうなったか?
39 Unitテストのカバレッジ (新規マイクロサービス) • 一般的には65% ~ 80%くらいを目指すのが良いくらいとされるなか、かなり高い数値を キープできている (2024/09/29現在) •
Mutation Testがあるおかげで、ある程度この数値も信頼できるようになった • 特に無理してテストを書いている感じはない • そもそも全体のStatementsは1805程度なので比較的小さい
40 Mutation テストのカバレッジ (新規マイクロサービス) • こっちは77%くらいなのでまずまず • Strykerにも閾値を設定できて(thresholdオプション)、今は50%以上なら CIはコケないようにしている
41 Unitテストのカバレッジ (フロント) • フロント側は後からテストコードを書いていってるので全体的に低い • 頑張ってカバレッジを上げていってるところ 💪
42 Mutation テストのカバレッジ (フロント) • これも後から入れている & テストコードがそもそもないので、Survivedは必 然的に多くなる •
今は全体ではなく、hooks系に絞ってやっているところ
43 感想 • Good 👍 ◦ 品質への意識が高まっただけでなく、結果的に PRを小さくする文化が浸透したのはよかった ◦ 今回は小さめのプロジェクトに導入したおかげでわりかし早く実行できているが、大規模なプ
ロジェクトに後から入れるのはしんどそう ◦ 入れる場合、変異対象や種類を部分的に入れて、徐々に拡張していくのがよさそう • Bad 👎 ◦ CIのタイミングでは「どこが Suvivedしているか?」を知ることができない
44 PHPのMutationライブラリ・Infection にはそれがある
45 自動テスト・品質向上の一助になれば幸いです
46 (いれば) 懇親会で懇親しましょう Kanonさんと話してみたいという方
47 ご清聴、あざざました