Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
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.1k
テストコード品質を高めるために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
GAS × Discord bot × Gemini で作ったさいきょーの情報収集ツール
ysknsid25
1
570
そうだ、神戸へ行こう
ysknsid25
2
97
テストコードの品質を客観的な数値で担保しよう〜Mutation Testのすすめ〜
ysknsid25
12
4.6k
「ばん・さく・つき・たー!」にならないためにSHIROBAKOから 学んだこと
ysknsid25
4
1.1k
useSWRをuseContextの代わりに使ってみる試み
ysknsid25
1
490
東遊園地近辺のおすすめランチ・カフェ
ysknsid25
3
320
Other Decks in Technology
See All in Technology
「今までで一番学びになった瞬間」発表 LT - Shinjuku.rb #96
kozy4324
0
140
歴史あるRuby on Railsでデッドコードを見つけ、 消す方法@yabaibuki.dev #3
ayumu838
0
1.7k
高品質と高スピードを両立させるソフトウェアQA/Software QA that Supports Agility and Quality
goyoki
8
1.2k
農業用ダム監視を目的とした衛星SAR 干渉解析の適用性について
osgeojp
0
130
間違いだらけのポストモーテム - ホントに役立つレビューはこうだ!
jacopen
5
940
「品質とスピードはトレード・オンできる」に向き合い続けた2年半を振り返る / Quality and speed can be traded on.
mii3king
0
540
pmconf2024_UPSIDER
upsider_tech
0
3.8k
MySQL 8.0 から PostgreSQL 16 への移行と RLS 導入までの道のりと学び
baseballyama
0
260
深層学習のリペア技術の最新動向と実際 / DNN Repair Techniques for AI Performance Alignment for Safety Requirements
ishikawafyu
0
270
ソフトウェアエンジニアとしてキャリアの螺旋を駆け上がる方法 - 経験と出会いが人生を変える / Career-Anchor-Drive
soudai
4
940
Remix SPAモードのファイルベースルーティングで進めるフロントエンド構築
ryochike
0
140
そろそろOn-Callの通知音について考えてみよう (PagerDuty編)
tk3fftk
1
310
Featured
See All Featured
What's new in Ruby 2.0
geeforr
343
31k
Building Applications with DynamoDB
mza
91
6.1k
Bash Introduction
62gerente
608
210k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
Designing for Performance
lara
604
68k
Docker and Python
trallard
40
3.1k
Site-Speed That Sticks
csswizardry
1
120
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
Facilitating Awesome Meetings
lara
50
6.1k
Statistics for Hackers
jakevdp
796
220k
Happy Clients
brianwarren
98
6.7k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
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 ご清聴、あざざました