mutation testingについて考えた


mutation testingとは?

以下を参照
https://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%A5%E3%83%BC%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E8%A7%A3%E6%9E%90

コードのいろいろなところを改変して、テストがちゃんと壊れるか?を確認するテストです。

使ってみた

rubyのmutantを使いました
https://github.com/mbj/mutant

感想

俺たちは手動でよくやっている

プログラムのいろいろな箇所を適当にいじってみることってよくあると思います。

目的は、バグのあるプログラムをとりあえずあてずっぽうで直してみるときや、テストがちゃんとfailすることを確認するときや、冗長な箇所を削ってみるときなど、いろいろあると思います。

mutation testingはこれを自動化できるということだと思いました。

頭を使わないでプログラミングできる

mutation testingの補助を借りると、かなり頭を使わないでプログラミングできます。

漏れなく思考することって結構負担のかかる思考だと思います。
例えば、正解を一つ見つける思考よりも、それ以外に正解が無いことを証明する思考のほうが頭を使います。

mutation testingを使うと乱数のちからで漏れなく思考する部分を助けてくれるので、頭の負担がかなり減ります。

昔の俺 -> 注意して実装を書く
今の俺 -> 注意してテストコードを書いて、頭を使わずに実装を書く
少し未来の俺 -> 頭を使わずにmutation testingの質問(これは冗長?バグ?テストの不備?)に答えながらテストコードを作り、頭を使わずに実装を書く
かなり未来の俺 -> 頭を使わずにテストと実装ができあがるのを待つ

今後のポイント

false positive

調べたら、mutation testingの課題は、false positiveが出ることらしいですが、これは帰無仮説(コードにバグが無い)をおいて検定すれば良いと思います。

killされた割合だけではなく、指標を増やしても良いかもしれません。

実行時間

railsの小さいモデルクラスとかに適用しても実行時間が10分以上かかったので、デイリーユースはできなそうでした。

バグは見つかりませんでしたが、テストの不備(将来のバグにつながる)はたくさん見つかったので(普通のコードカバレッジが100%だったにもかかわらず)、再現率の低いバグがあることはわかっているが、血眼でマジで見つからないときや、本気で品質を上げたいときは良いと思いました。

実現手段

あまりサーベイしていないですが、素人考えで以下のようなアイデアを思いつきました。

LLVM

mutation testingをC++に適用すると、ビルドに時間がかかりすぎてmutationをたくさん計算できません。
すでにあると思いますが、LLVMやJavaの中間コードを改変するようにすれば、ビルド時間を短縮できそうです。

影響範囲チェックやコードカバレッジと組み合わせる

あるコードの修正がどこに影響を与えるか?ってよく研究されていると思います。コードカバレッジも多分よく研究されています。

mutationの影響のあるテストだけを実行するようにすれば、テスト実行時間を短縮できそうです。

AI

ニューラルネットにプログラミング言語を学習させて、効率よくバグを発生させる方法を学ばせたり、効率よくバグを検知する方法を学ばせたりしたら面白そうです。

ニューラルネットのGANのようにコードとテストを戦わせるような仕組みにしたら面白そうです。