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.3k
テストコード品質を高めるために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
1k
GAS × Discord bot × Gemini で作ったさいきょーの情報収集ツール
ysknsid25
1
1.1k
そうだ、神戸へ行こう
ysknsid25
2
15k
テストコードの品質を客観的な数値で担保しよう〜Mutation Testのすすめ〜
ysknsid25
12
4.8k
「ばん・さく・つき・たー!」にならないためにSHIROBAKOから 学んだこと
ysknsid25
4
1.2k
useSWRをuseContextの代わりに使ってみる試み
ysknsid25
1
540
東遊園地近辺のおすすめランチ・カフェ
ysknsid25
4
17k
Other Decks in Technology
See All in Technology
PHP ユーザのための OpenTelemetry 入門 / phpcon2024-opentelemetry
shin1x1
3
1.6k
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
6
54k
三菱電機で社内コミュニティを立ち上げた話
kurebayashi
1
310
20240513 - 框裡框外_文學院學生如何在AI世代安身立命 @ 淡江大學
dpys
0
640
Unlearn Product Development - Unleashed Edition
lemiorhan
PRO
2
170
Zero Data Loss Autonomous Recovery Service サービス概要
oracle4engineer
PRO
1
5k
LangGraphとFlaskを用いた社内資料検索ボットの実装②Retriever構築編
aoikumadaki
0
100
デジタルアイデンティティ技術 認可・ID連携・認証 応用 / 20250114-OIDF-J-EduWG-TechSWG
oidfj
2
470
コロプラのオンボーディングを採用から語りたい
colopl
2
290
Azureの開発で辛いところ
re3turn
0
220
ゼロからわかる!!AWSの構成図を書いてみようワークショップ 問題&解答解説 #デッカイギ #羽田デッカイギおつ
_mossann_t
0
1.2k
Denoで作るチーム開発生産性向上のためのCLIツール
sansantech
PRO
0
160
Featured
See All Featured
Designing Experiences People Love
moore
139
23k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
113
50k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
A Tale of Four Properties
chriscoyier
157
23k
Why Our Code Smells
bkeepers
PRO
335
57k
Building Better People: How to give real-time feedback that sticks.
wjessup
366
19k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
860
Making the Leap to Tech Lead
cromwellryan
133
9k
4 Signs Your Business is Dying
shpigford
182
21k
It's Worth the Effort
3n
183
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 ご清聴、あざざました