---
title: GoにおけるMutation Testingの実践チャレンジ
tags: 
author: [DeNA_Tech](https://docswell.com/user/DeNA_Tech)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/3JK9DRW5JD.jpg?width=480
description: Go Junction #1 で発表した資料となります。
published: March 23, 26
canonical: https://docswell.com/s/DeNA_Tech/5MQ1G2-2026-03-23-132421
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/3JK9DRW5JD.jpg)

GoにおけるMutation Testingの
実践チャレンジ
DeNA エンジニアリング室開発デザイングループ(SWET)
伊藤 瑛
© DeNA Co., Ltd.
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/LE3WR811E5.jpg)

自己紹介
●
伊藤 瑛
○
●
https://github.com/akito0107
DeNA エンジニアリング室開発デザイングループマネージャー
SWETと呼ばれていたところ
●
●
© DeNA Co., Ltd.
好きな言語など
○
Go, TypeScript
○
LEAN4
Web系全般の開発をやっています（それとGL）
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/8EDKYMXK7G.jpg)

本日のアジェンダ
●
Mutation Testingとは何か
●
Mutation Testingのユースケース
●
rmut (Mutation Testing Tool) の設計と実装
●
rmutの課題
© DeNA Co., Ltd.
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/V7PK6RP3J8.jpg)

ミューテーションテスト
ミューテーション解析
ご存知の方はいらっしゃいますか？
© DeNA Co., Ltd.
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/2JVV3R2NJQ.jpg)

Mutation Testing とは何か
●
テストの品質を測定する手法 (ミューテーション解析とも呼ぶ)
●
コードに意図的な不具合(ミュータント)を入れて、テストが失敗するかを見る。
○
🙆失敗すれば killed
○
🙅失敗しなければ survived
●
Coverageレベルで確認できるのはテストコードがそこを通ったか。
●
Mutation Testingでは、そのテストが不具合を発見できる能力があるかどうかを確認
できる。
© DeNA Co., Ltd.
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/5EGL3MR5JL.jpg)

シンプルな例
[IMAGE: IMG_015]
Replace this with the actual image
from Drive
© DeNA Co., Ltd.
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/4JQY5RVL7P.jpg)

Test実行
(日本では)成人は18歳からなので、実装にはバグがあるにもかかわらず
Testがpassしてしまう
*Coverageは100%
© DeNA Co., Ltd.
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/K74W98M5E1.jpg)

Mutation Testingの実施
●
&gt; を &gt;= に変える mutant を適用してtest実行する
*意図的な不具合を混入する
●
Test実行 =&gt; Testが落ちない(Survived)
Testが十分では無いことが機械的にわかる
© DeNA Co., Ltd.
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/LJ1YK282EG.jpg)

Mutation Testingの基本的な考え方
●
Test対象コードに変異(mutant)を埋め込み、Test Suiteを回す
●
Test Suiteがfailしなかった場合、Test Suiteにはその変異を発見できる能力がない、
つまり、適切なTest Suiteになっていないと捉える
●
変異は様々な種類がある
○
Operatorの書き換え
+ → - / &lt; → &lt;= …
○
literalの書き換え
1 → -1 / “some string” → “”
○
●
関数呼び出しの削除
https://pitest.org/quickstart/mutators/
あたりが参考になる
© DeNA Co., Ltd.
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/GJWGDRZ272.jpg)

もう一つの例
Query Builder
© DeNA Co., Ltd.
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4EZLGR1473.jpg)

このTest Codeは十分か？
© DeNA Co., Ltd.
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/Y76WYRLG7V.jpg)

このTest Codeは十分か？
←Test Data作成部分
© DeNA Co., Ltd.
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/G75MG81X74.jpg)

Server Sideプログラミングあるある
●
複雑なSQLのTestにはDBに十分にTest Dataを入れておかなくてはならない
●
どれくらいのデータを入れておくと十分なのか、なかなか判断しづらい
●
(個人の経験) 100行超えるSQLに対するTestをレビューするのは無理...
© DeNA Co., Ltd.
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/9J29YK1QER.jpg)

Query Builderに対するMutation
(仮説) Queryの条件を書き換えてもTestが通る ⇨ 条件の部分をTestできる能力がない
© DeNA Co., Ltd.
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/DEY4GNZYJM.jpg)

Mutation Testingでわかる可能性があること
●
Test Data / Fixtureの網羅性
●
Assertionが正しいか
●
ライブラリの挙動を勘違いしていないか
○
●
Equalsの振る舞いの誤解など
etc...
AI AgentがTestを大量に生成する時代、Testの”正しさ”を計測できる手法になりうる
© DeNA Co., Ltd.
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/VJNYGX3R78.jpg)

今日の結論: Mutation Testingをやろう
© DeNA Co., Ltd.
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/YE9PW89ZJ3.jpg)

現実の壁
●
運用が難しい
●
とんでもなく実行時間がかかる
© DeNA Co., Ltd.
○
mutant1つごとにTest Suiteを回すのがmutation testingの基本的な挙動
○
mutantを100個埋め込むとTest実行時間100倍
○
何も考えずにやると、大体数万個のmutantを埋め込む
○
厳しい
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GE8DN8DYED.jpg)

rmut
●
自作のMutation Testing Toolを作っている
○
DeNAの実プロダクトで運用にチャレンジ中
●
高速化・運用上の工夫を時間が許す限り話します
●
Runtime MUTation
© DeNA Co., Ltd.
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LELMPRM97R.jpg)

Mutation Testing Toolの素朴な実装
実装は簡単
実行速度は...
© DeNA Co., Ltd.
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/4JMY4RYVJW.jpg)

AST書き換え &amp; Compileを1回で済ますアイディア
こうする
これを
*説明のために簡略化しています。
実際の実装はもう少し複雑です。
© DeNA Co., Ltd.
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/PJR9WR9W79.jpg)

AST書き換え &amp; Compileを1回で済ますアイディア
●
1回のAST書き換えで 全ての ミューテーションを埋め込み、TestIdを付与する
●
TestMainでTestをloopさせ、loopごとにUniqueなTestIdをSetして、それぞれのloopで
異なるMutatorが起動するようにする
●
AST書き換え &amp; Compileが1度で済む
はやい！！！！
© DeNA Co., Ltd.
*rmutオリジナルのアイディアというわけではありません。他のmutation testing toolもこの方法で実装され
ているものもあります。
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/PEXQPRQVJX.jpg)

一旦まとめ
●
この設計だけで実行時間の問題が全て解決！とはならない
●
（そもそも実装が難しい）
●
Mutationの結果無限ループを発生させてしまう問題など
実運用にはまだまだ課題がある
●
callgraph解析で効率的にmutation範囲を絞るなどの運用上
の工夫もしています
●
この辺りの問題を効率よくテストするための手法について
Lint Night #4( https://lintnight.connpass.com/event/385142/ )
で話す予定です
© DeNA Co., Ltd.
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/3EK9DR95ED.jpg)

Appendix.
© DeNA Co., Ltd.
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/L73WR8W175.jpg)

実装の難しさ
●
実装が難しい
●
素朴な実装だと、Compile Errorになるような書き換えを行なっても、そのmutantだ
けが失敗(killed)とマークされる
●
今回の実装だとAST書き換えにおいてComile Errorになるような書き換えを行なって
しまったら、全てのMutation Testingが動かない。
© DeNA Co., Ltd.
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/87DKYMKKJG.jpg)

Compileができるコードを生成するのが難しい理由
●
匿名関数でmutatorをwrapするという特性上、書き換え対象のASTが何の型なのかを
知る必要がある
○
●
© DeNA Co., Ltd.
ASTだけではわからないので、packages.Loadを使っている
この場合、 a + b というexpressionが何の型を持つのかを調べる必要がある
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/VJPK6RK3E8.jpg)

注意を要するケース Untyped
●
untyped int のケース
●
1000 というリテラルだけをみても型が
●
なにも考えないとこうなる
決まらないケースがあり、ASTの親の型
やコンテキストなどを調べる必要があ
る。
© DeNA Co., Ltd.
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/2EVV3RVNEQ.jpg)

Compile Errorは突破しても...
●
Mutationによる無限ループ混入問題
●
解決策
○
Timeout
■
go標準の仕組みを使える
■
何万件とtestを回す中で1回の
test実行で数分もっていかれ
るのは辛い
○ LoopCounterを仕込む
© DeNA Co., Ltd.
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/57GL3ML5EL.jpg)

LoopCounter
●
for を発見したら、AST書き換え時にLoopCounterを仕込み、n回loopしたらpanicす
るようにして、早期にtestを失敗させる
●
全てではないが、ある程度の無限ループには対応できるようになった。
○
●
© DeNA Co., Ltd.
goto や再帰により発生する無限ループなど、まだ対応できていないものもある
それでも無限ループしてしまうものはgo testのtimeoutで対応する
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/4EQY5RYLJP.jpg)

無限ループ?
●
1万回LoopCounterを回すのに1万秒かかる...
●
未解決問題...?
© DeNA Co., Ltd.
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/KJ4W98W571.jpg)

その他の運用上の工夫
●
sync.*系のmutationの除外(deadlockするので)
●
mutation範囲の限定
○
gitのdiffからcallgraphを解析して、そのPRでどのファイルが影響がありそうか
を推定し、mutationをかける範囲を限定する
●
custom mutator pluginの仕組み
○
squirrel等のGo標準以外のコードに対するmutatorはpluginで提供 &amp; ユーザが
pluginを書いて拡張できるようにする
© DeNA Co., Ltd.
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/LE1YK2Y27G.jpg)

課題は色々...
●
Compile Errorがたまにある
○
そんな構文が!?のような驚き
○
構文解析・書き換えのツールの効率的なtest手法について
Lint Night #4( https://lintnight.connpass.com/event/385142/ )で話す予定です。
●
どこまで行っても実行時間は安定しない
○
●
急に無限ループを踏むことがある
Survivedなmutationであっても意味がないことがある
■
●
© DeNA Co., Ltd.
logger, 例外処理など
plugin配布の難しさ
○
go/plugin...
○
wasiで配布も難しい
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/GEWGDRG2J2.jpg)

Mutation Testingについて知るためのreferences
●
https://stryker-mutator.io/docs/
●
https://github.com/hcoles/pitest/blob/master/so_you_want_to_build_mutation_t
esting_system.md
●
© DeNA Co., Ltd.
https://research.google/pubs/state-of-mutation-testing-at-google/
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/47ZLGRL4J3.jpg)

まとめ
●
Mutation Testingの紹介
○
●
●
© DeNA Co., Ltd.
Testの品質を測定しよう
自作Mutation Testing Tool, rmutの設計
○
Compileを一度にすませ、test実行時にmutationを制御する設計
○
無限ループへの対応
○
callgraph解析などで適用範囲を最小化する
rmutの課題
○
実行時間
○
plugin
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/YJ6WYRWGJV.jpg)

© DeNA Co., Ltd.
34


